Teil 1
Quelltext des Sensor-Programmes mit MEGA8L
Quelltext des Anzeige-Programmes mit MEGA128


Blockschaltbild
Details
Evaluierungsprogramm
//-----------------------------------------------------------------------------
// Programm zum Messen der Luftfeuchte mit dem Sensor HH10D
//      und zum Messen des Luftdrucks u. Temperatur mit HP03S
// Bearbeiter:  S. Taborek
// Beginn: 23.12.2010
// Stand: 29.12.2010
//

// Prozessor: ATMEGA8L

// Interface: UART1

//
//-----------------------------------------------------------------------------


program AVR_HP03S_HH10D;



{ Declarations section }
var cnt_0          : word;
    w_h            : word;
    b_h            : byte;
    str2           : string[2];
    uart_cmd       : byte;
    //-----------------------
    ctc_1          : longint;
    humidity       : real;
    pressure       : real;
    temperature    : real;
    //----------------------
    hh10d_sens     : word;      // ROM-Constante für HH10D
    hh10d_offs     : word;      // ROM-Constante für HH10D
    hp03s_C1       : word;
    hp03s_C2       : word;
    hp03s_C3       : word;
    hp03s_C4       : word;
    hp03s_C5       : word;
    hp03s_C6       : word;
    hp03s_C7       : word;
    hp03s_A        : byte;
    hp03s_B        : byte;
    hp03s_C        : byte;
    hp03s_D        : byte;
    hp03s_Pressure : word;
    hp03s_Temperat : word;
    hh10d_mess     : word;
    //-----------------------
    h_txt          : string[15];
    send_txt       : string[90];
    cnt2           : word;
   
const
  ROM_Adr_HH10D          : byte = 0xA2;  //Moduladr. read
  ROM_Adr_HP03S          : byte = 0xA0;
  ADC_HP03S              : byte = 0xEE;  // ROM write
 
 

{==============================================================================}
procedure Counter0_ISR; org IVT_ADDR_TIMER0_OVF;
{==============================================================================}
var h1, h2 : longint;
// Zähler an F_Out des Humidity-Sensors
// Es werden jeweils 32512 steigende Flanken gezählt und anschließend mit
// einer festen Frequenz verglichen. Das entspricht einer Messzeit von 3-7 sec.
begin
  //TCNT0 := 0;           // Überlauf bei 256
  inc(cnt_0);
  if (cnt_0 > 127) then begin  // 127*256 = 32512
    h2 := ctc_1;
    ctc_1 := 0;
    PORTD.6 := not PORTD.6;
    h1 := (h2 * 10000);
    h2 := h1 div 327869;       // siehe CTC
    h1 := (32512000 div h2);   // Ergebnis in Hz / Genauigkeit +/- 2Hz
    hh10d_mess := h1;
    cnt_0 := 0;
  end;
end;


{==============================================================================}
procedure Counter1_ISR; org IVT_ADDR_INT0;
{==============================================================================}
// angekoppelt an externen Takt von CTC1 (Frequenz: 31,3725 KHz)
begin
  inc(ctc_1);
end;



{------------------------------------------------------------------------------}
procedure SetError_LED(_a: byte);
{------------------------------------------------------------------------------}
var i : byte;
begin
  for i := 1 to _a do begin
    PORTD.6 := not PORTD.6;
    delay_ms(100);
  end;
end;


{------------------------------------------------------------------------------}
function Read_ROMC(device_adr, b_adr: byte;): word;
{------------------------------------------------------------------------------}
// Read one word from EEPROM (like 24C02)
var bl, bh, bdu : byte;
begin
  result := 0;
  if TWI_Start() = 0 then begin
    PORTD.6 := 0;     // LED on
    PORTD.7 := 0;     // LED on
    TWI_Write(device_adr+0);  // Device-Adr für write
    TWI_Write(b_adr);         // Adresse des 1.Bytes
    //nun lesen
    TWI_Start();
    TWI_Write(device_adr+1);  // Device-Adr für read
    bh := TWI_Read(1);
    bl := TWI_Read(0);
    TWI_Stop();
    result := bh*256 + bl;
    //
    delay_ms(40);
    PORTD.6 := 1;     // LED off
    PORTD.7 := 1;
  end
  else begin
    SetError_LED(10);
  end;
  delay_ms(40);
end;


{------------------------------------------------------------------------------}
function Test_ROM_HP03S_Constants: byte;
{------------------------------------------------------------------------------}
begin
  result := 0;
  if (hp03s_C1 < 256)  then result := 1;
  if (hp03s_C2 > 8197) then result := 2;
  if (hp03s_C3 > 3000) then result := 3;
  if (hp03s_C4 > 4096) then result := 4;
  if (hp03s_C5 < 4096) then result := 5;
  if (hp03s_C6 > 16384) then result := 6;
  if (hp03s_C7 < 2400) or (hp03s_C7 > 2600) then result := 7;
  if (hp03s_A = 0) or (hp03s_A > 63) then result := 8;
  if (hp03s_B = 0) or (hp03s_B > 63) then result := 9;
  if (hp03s_C = 0) or (hp03s_C > 15) then result := 10;
  if (hp03s_D = 0) or (hp03s_D > 15) then result := 11;

  if result > 0 then begin  // constants not real
    SREG.7 := 0;                  // Interrupts disabled

    // Fehleranzeige mittels vorhandener LED s
    w_h :=  2* result;
    PORTD.6 := 0;
    PORTD.7 := 0;
    delay_ms(2500);
    repeat
       PORTD.6 := not PORTD.6;
       PORTD.7 := not PORTD.7;
       delay_ms(500);
       dec(w_h);
    until  w_h = 0;
    PORTD.6 := 1;
    PORTD.7 := 1;
    SREG.7 := 1;                  // Interrupts enabled
  end;
end;


{------------------------------------------------------------------------------}
procedure Read_ROM_Constants_HH10D;
{------------------------------------------------------------------------------}
// Read ROM-Constants from HH10D
begin
  hh10d_sens := Read_ROMC(ROM_Adr_HH10D, 0x10);
  hh10d_offs := Read_ROMC(ROM_Adr_HH10D, 0x12);
  delay_ms(100);
end;


{------------------------------------------------------------------------------}
function Read_ROM_Constants_HP03S: byte;
{------------------------------------------------------------------------------}
begin
  result := 0;
  hp03s_C1 := Read_ROMC(ROM_Adr_HP03S, 0x10);
  hp03s_C2 := Read_ROMC(ROM_Adr_HP03S, 0x12);
  hp03s_C3 := Read_ROMC(ROM_Adr_HP03S, 0x14);
  hp03s_C4 := Read_ROMC(ROM_Adr_HP03S, 0x16);
  hp03s_C5 := Read_ROMC(ROM_Adr_HP03S, 0x18);
  hp03s_C6 := Read_ROMC(ROM_Adr_HP03S, 0x1A);
  hp03s_C7 := Read_ROMC(ROM_Adr_HP03S, 0x1C);
  // and now the 4 Byte-Constants:
  w_h := Read_ROMC(ROM_Adr_HP03S, 0x1E);
  hp03s_A := hi(w_h);
  hp03s_B := lo(w_h);
  w_h := Read_ROMC(ROM_Adr_HP03S, 0x20);
  hp03s_C := hi(w_h);
  hp03s_D := lo(w_h);
  //------------------------------------------
 
  result := Test_ROM_HP03S_Constants; // Test the limits of values
                                
end;


{------------------------------------------------------------------------------}
function Read_ADC_HP03S(_selector: byte;): word;
{------------------------------------------------------------------------------}
var bl, bh, bdu : byte;
const Awrite = 0;
      Aread  = 1;
// _selector for one of the both values:
begin
  result := 1;
  PORTD.7 := 1;
  PORTB.2 := 1;                      // set XCLR an HP03S hi
  delay_ms(10);
  if TWI_Start() = 0 then begin
    PORTD.7 := 0;                    // LED on
    TWI_Write(ADC_HP03S + Awrite);   // Device-Adr für write
    TWI_Write(0xFF);                 //
    TWI_Write(_selector);            // Pressure/Temperature selector
    TWI_Stop();
    delay_ms(60);
    TWI_Start();
    TWI_Write(ADC_HP03S + Awrite);   // Device-Adr für write
    TWI_Write(0xFD);                 //
    //now read
    TWI_Start();
    TWI_Write(ADC_HP03S + Aread);    // Device-Adr für read
    bh := TWI_Read(1);
    bl := TWI_Read(0);
    TWI_Stop();
    result := bh*256 + bl;
    PORTD.7 := 1;                                             
    //
  end
  else begin
    SetError_LED(7);
  end;
  PORTB.2 := 0;                      // set XCLR an HP03S  lo
end;



{------------------------------------------------------------------------------}
procedure Compute_Humidity(var hum1: real);
{------------------------------------------------------------------------------}
var HC1 : real;
begin
  HC1 := hh10d_offs;
  HC1 := HC1 - hh10d_mess;
  HC1 := HC1 * hh10d_sens ;  //
  hum1 := HC1 / 4096;
end;


{------------------------------------------------------------------------------}
function Compute_P_T(var _pr, _te : real): boolean;
{------------------------------------------------------------------------------}

// Berechnungen erfolgen im Bereich der real-Zahlen:
var HC1, HC2, HC3 : real;
    h_pow : longint;
    dUT, OFF, SENS, X : real;
    i : byte;
begin
  result := 0;
  _pr := 0;
  _te := 0;
  //
//  if Test_ROM_HP03S_Constants = 0 then begin
    HC1 := hp03s_Temperat;
    HC1 := HC1 - hp03s_C5;
    HC2 := HC1 / 128;
    dUT := HC1;
    h_pow := 1;
    h_pow := h_pow shl hp03s_C;
    if (hp03s_temperat >= hp03s_C5) then begin
      HC1 := (HC2 * HC2 * hp03s_A);
    end
    else begin
      HC1 := (HC2 * HC2 * hp03s_B);
    end;
    HC2 := HC1 / h_pow;
    dUT := dUT - HC2;
    //-------------------
    HC1 := hp03s_C4;
    HC1 := HC1 - 1024;
    HC1 := HC1 * dUT;
    HC1 := HC1 / 16384;
    HC1 := HC1 + hp03s_C2;
    OFF := HC1 * 4;
    //-------------------
    HC1 := hp03s_C3;
    HC1 := HC1 * dUT;
    HC1 := HC1 / 1024;
    SENS := HC1 + hp03s_C1;
    //-------------------
    HC1 := hp03s_pressure;
    HC1 := HC1 - 7168;
    HC1 := HC1 * SENS;
    HC1 := HC1 / 16384;
    X := HC1 - OFF;
    //--------------------
    HC1 := X * 10;
    HC1 := HC1 / 32;
    _pr := HC1 + hp03s_C7;  // result

    _pr := _pr / 10;
    //--------------------
    HC1 := hp03s_C6;
    HC1 := HC1 * dUT;
    HC1 := HC1 / 65536;
    h_pow := 1;
    h_pow := h_pow shl hp03s_D;
    HC3 := dUT / h_pow;
    _te := HC1 - HC3 + 250;  // result
    _te := _te / 10;
    //---------------------------
    result := 1;
//  end;
end;


{------------------------------------------------------------------------------}
function SendDateStr(): boolean;
{------------------------------------------------------------------------------}
var cnt : byte;
begin
  result := false;
  send_txt := send_txt +  # +#0;  //delimiter
  UART1_Write_Text(send_txt);
  cnt := 0;
   repeat
     inc(cnt);
     if (UART1_Data_Ready() = 1) then begin
       if (UART1_Read() = 0xA0) then result := true;
     end;
     delay_ms(1);
   until (result = true)or(cnt > 25) ;
end;


{------------------------------------------------------------------------------}
procedure MCU_Init;
{------------------------------------------------------------------------------}
begin
  TWI_Init(100000);
  UART1_Init(9600);
  // Initialisierung des Timer1 als Freuenzgenerator:
  DDRB := DDRB or %00000010;    // B1 = OC1A out
  TCCR1A := %01000000;          // Port B1 toggeln
  TCCR1B := %00001001;          // Timer1-Reset bei compare, no prescaling
  OCR1AH := 0;
  OCR1AL := 244;                // 16000000/2/244 = 32,7869 KHz
  //Initialisierung der LED-Ausgaben:
  DDRD := DDRD or %11000000;    // D7 = gn LED  D6 = ye LED
  //Initialisierung des XCLR-Ausgangs für HP03S-PIN:
  DDRB := DDRB or %00000100;    // B2 low für ROM-read sonst hight
  PORTB.2 := 0;                 // XCLR an HP03S low
  // Initialisierung für DCF-PON
  DDRC := DDRC or %00000001;    // C0 low = DCF on
  PORTB.2 := 1;                 // DCF on
  //Initialisierung des Timer0 als Counter:
  DDRD := DDRD and %11101111;   // D4 =  XCK/T0 Eingang
  PortD.4 := 1;                 // PullUp für D4 aktiv
  TCCR0 := %00000110;           // External clock on T0 pin falling edge.
  TIMSK.TOIE0 := 1;             // Timer0-Overflow ISR aktiv
  TCNT0  := 0;                  // Counter0 voreinstellen
  //Initialisierung des externen Interrupts an PIND2
  DDRD := DDRD and %11111011;   // D2 ist input <-- B1
  PortD := PortD or %00000100;  // PullUp für D2 aktiv
  GICR  :=  GICR or %01000000;  // Int0 erlaubt
  MCUCR := MCUCR or %00000010;  // Int0 löst bei fallender Flanke aus
  SREG.7 := 1;                  // Interrupts enabled
  //------------------------------------------------------------------
  PORTD.6 := 1;
  PORTD.7 := 0;
end;



{==============================================================================}
begin
  { Main program ATMEGA8L}
  MCU_Init;
  //------------------------------------------------------------------
  Read_ROM_Constants_HH10D;
  //------------------------------------------------------------------
  Read_ROM_Constants_HP03S;
  //------------------------------------------------------------------
  cnt2 := 250;

  while true do begin

      if (UART1_Data_Ready() = 1) then begin // stand by for request
        uart_cmd := UART1_Read();
        if (uart_cmd = 0xA1) then begin
          Compute_Humidity(humidity);
          FloatToStr(huminity, h_txt);
          h_txt[5] := 0;
          Send_txt :=      + h_txt +  %/ ;
          FloatToStr(temperature, h_txt);
          if temperature > 0 then begin
            h_txt[5] := 0;
            str2 :=     ;
          end
          else begin
            h_txt[6] := 0;
            str2 :=    ;
          end;
          Send_txt := send_txt + str2 + h_txt +  C/ ;
          FloatToStr(pressure, h_txt);
          if pressure < 1000 then begin
            h_txt[6] := 0;
            str2 :=    ;
          end
          else begin
            h_txt[7] := 0;
            str2 :=   ;
          end;
          Send_txt := send_txt + str2 + h_txt +  p / / ;
          //--- raw-values:
          WordToStr(hh10d_mess, h_txt);
          send_txt := send_txt +  Hum   + h_txt +  / ;
          WordToStr(hp03s_temperat, h_txt);
          send_txt := send_txt +  Tem   + h_txt +  / ;
          WordToStr(hp03s_pressure, h_txt);
          send_txt := send_txt +  Pre   + h_txt;
          SendDateStr();
        end;
        //
        if (uart_cmd = 0xA9) then begin  // send HH10D-ROM-Constants
          WordToStr(hp03s_C1, h_txt);
          send_txt := h_txt +  / ;
          WordToStr(hp03s_C2, h_txt);
          send_txt := send_txt + h_txt +  / ;
          WordToStr(hp03s_C3, h_txt);
          send_txt := send_txt + h_txt +  / ;
          WordToStr(hp03s_C4, h_txt);
          send_txt := send_txt + h_txt +  / ;
          WordToStr(hp03s_C5, h_txt);
          send_txt := send_txt + h_txt +  / ;
          WordToStr(hp03s_C6, h_txt);
          send_txt := send_txt + h_txt +  / ;
          WordToStr(hp03s_C7, h_txt);
          send_txt := send_txt + h_txt;
          if not SendDateStr() then begin  // sendet send_txt
          end;
        end;
        if (uart_cmd = 0xAA) then begin  // send HH10D-ROM-Constants
          ByteToStr(hp03s_A, h_txt);
          send_txt := h_txt;
          ByteToStr(hp03s_B, h_txt);
          send_txt := send_txt + h_txt;
          ByteToStr(hp03s_C, h_txt);
          send_txt := send_txt + h_txt;
          ByteToStr(hp03s_D, h_txt);
          send_txt := send_txt + h_txt +  / / ;
          WordToStr(hh10d_offs, h_txt);
          send_txt := send_txt + h_txt +  / ;
          WordToStr(hh10d_sens, h_txt);
          send_txt := send_txt + h_txt;
          if not SendDateStr() then begin  // send send_txt
          end;
        end;
      end;
    //-------------------------------------------------
    delay_ms(25);
    PORTD.7 := not PORTD.7; //  gn LED
    inc(cnt2);
    if cnt2 > 250 then begin // cyclic computing
      cnt2 := 0;
      hp03s_Pressure := Read_ADC_HP03S(0xF0);
      hp03s_Temperat := Read_ADC_HP03S(0xE8);
      Compute_P_T(pressure, temperature);
    end;
  end;
end.
Quelltext des Programms zur zyklischen Abfrage der Sensoren und Berechnung der Werte.

Compiler: MikroPascal 3.5 von MikroElektronika