原创 AVR_Mega8 + SHT71温湿度及露点检测(下)

2009-2-8 19:20 6135 7 7 分类: MCU/ 嵌入式

点击开大图


/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.3 Standard
Automatic Program Generator
?Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com


Project :
Version :
Date    : 2008-4-15
Author  : lubing                           
Company : swust                          
Comments:



Chip type           : ATmega8
Program type        : Application
Clock frequency     : 8.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/


#include <mega8.h>
#include <stdlib.h>
#include <math.h>
#include <delay.h>
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <delay.h>
//float calc_dewpoint(float h,float t);
char SHT_ReadByte(unsigned char ack);
void SHT_Transstart(void);
void SHT_ConnectionRest(void);
char SHT_Read_StatusReg(unsigned char *p_value,unsigned char *p_checksum);
char SHT_Write_StatusReg(unsigned char *P_value);
char SHT_SoftRst(void);
char SHT_Measure(unsigned char *p_value,unsigned char *p_checksum,unsigned char mode);
float Calc_SHT71(float p_value,float *p_temerature);
float Calc_dewpoint(float h,float t);
void rezult_SHT_xx(void);
typedef union 
{ unsigned int i;
  float f;
} value;
enum {TEMP,HUMI};
#define        DATA_OUT           PORTC.0
#define        DATA_IN            PINC.0
#define        SCK                PORTC.1 
#define noACK 0
#define ACK   1        
                            //adr  command  r/w
#define STATUS_REG_W 0x06   //000   0011    0
#define STATUS_REG_R 0x07   //000   0011    1
#define MEASURE_TEMP 0x03   //000   0001    1
#define MEASURE_HUMI 0x05   //000   0010    1
#define RESET        0x1e   //000   1111    0
// Declare your global variables here
unsigned int tempervalue[2]={0,0};
void main(void)
{
// Declare your local variables here
  value humi_val,temp_val;
  unsigned char error,checksum;
  float dewpoint="0".0;
  //unsigned char outp;
  //unsigned int humi;      
  char inp;
  unsigned char Humidity[5]={0,0,0,0,0};
  unsigned char Temperture[5]={0,0,0,0,0};
  unsigned char Depoint[5]={0,0,0,0,0};
 // float temp1,temp2,temp3,temp4;
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;


// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;


// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;


// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;


// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top="FFFFh"
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;


// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top="FFh"
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;


// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;


// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
lcd_init(16);
delay_ms(15);
lcd_clear();       
lcd_gotoxy(0,0);
lcd_putsf("RH:");
lcd_gotoxy(8,0);
lcd_putsf("C:");
lcd_gotoxy(0,1);
lcd_putsf("DE:");
SHT_ConnectionRest();
while (1)
      {
      error="0";            
     //delay_ms(15);
     //error+=SHT_Measure((unsigned char*) &temp_val.i,&checksum,TEMP);  //measure temperature           
     error+=SHT_Measure((unsigned char*)( &humi_val.i),&checksum,HUMI);  //measure humidity
     //delay_ms(15);
     error+=SHT_Measure((unsigned char*) (&temp_val.i),&checksum,TEMP);  //measure temperature               
      //error+=SHT_Measure((unsigned char*) &humi_val.i,&checksum,HUMI);  //measure humidity
     //delay_ms(15);
     error += SHT_Read_StatusReg(&inp, &checksum);
    if(error!=0) 
       {
       SHT_ConnectionRest();                 //in case of an error: connection reset
       lcd_clear();
       lcd_gotoxy(0,0);
       lcd_putsf("Error");   
       }       
    else
    {
      humi_val.f=(float)tempervalue[1];                   //converts integer to float
      temp_val.f=(float)tempervalue[0];                   //converts integer to float
      humi_val.f=Calc_SHT71(humi_val.f,&temp_val.f);      //calculate humidity, temperature
      dewpoint="Calc"_dewpoint(humi_val.f,temp_val.f) ;
     
     
      ftoa(humi_val.f,2,Humidity);                           
      lcd_gotoxy(3,0);
      lcd_puts(Humidity);
      //delay_us(10);
      ftoa(temp_val.f,2,Temperture);
      lcd_gotoxy(10,0);
      lcd_puts(Temperture); 
      ftoa(dewpoint,2,Depoint);
      lcd_gotoxy(3,1);
      lcd_puts(Depoint);
    }
     delay_ms(100);  
  };
   
}
/***********************************/
char SHT_WriteByte(unsigned char value)

  unsigned char i,error=0;  
  DDRC = 0b00000011;    // 设置输出方向
  for (i=0x80;i>0;i/=2) //shift bit for masking
  { 
    if (i & value)       
    DATA_OUT=1; //masking value with i , write to SENSI-BUS
    else DATA_OUT=0;                       
    SCK="1";      //clk for SENSI-BUS
    delay_us(5); //pulswith approx. 5 us          
    SCK="0";       
  }
  DATA_OUT=1;            //release dataline                
  DDRC = 0b00000010;    // DATA Eingang
  SCK="1";                //clk #9 for ack 
  delay_us(2);
  error="DATA"_IN;       //check ack (DATA will be pulled down by SHT11)
  delay_us(2);
  SCK="0";        
  return error;       //error=1 in case of no acknowledge


//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" 
//----------------------------------------------------------------------------------


char SHT_ReadByte(unsigned char ack)

  unsigned char i,val=0;
  DDRC = 0b00000010;    // DATA Eingang
  for (i=0x80;i>0;i/=2)             //shift bit for masking
  { SCK="1";                          //clk for SENSI-BUS       
    delay_us(2);
    if (DATA_IN) val=(val | i);        //read bit  
    delay_us(2);
    SCK="0";
    //delay_us(5);                                          
    //delay_us(2);
   
  }   
  DDRC = 0b00000011;    // DATA Ausgang
  DATA_OUT=!ack;        //in case of "ack==1" pull down DATA-Line 
  //DATA_IN=!ack;       //in case of "ack==1" pull down DATA-Line
  SCK="1";                //clk #9 for ack
  delay_us(5);          //pulswith approx. 5 us 
  SCK="0";
  DATA_OUT=1;           //release DATA-line  //ADD BY LUBING                                                               
  return val;

//----------------------------------------------------------------------------------
// generates a transmission start 
//       _____         ________
// DATA:      |_______|
//           ___     ___
// SCK : ___|   |___|   |______
//----------------------------------------------------------------------------------


void SHT_Transstart(void)
{                        
   DDRC = 0b00000011;    // DATA Ausgang
   DATA_OUT=1; SCK="0";   //Initial state
   delay_us(2);
   SCK="1";
   delay_us(2);
   DATA_OUT=0;
   delay_us(2);
   SCK="0";  
   delay_us(5);
   SCK="1";
   delay_us(2);
   DATA_OUT=1;                   
   delay_us(2);
   SCK="0";      
   DDRC = 0b00000010;    // DATA Eingang

//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
//       _____________________________________________________         ________
// DATA:                                                      |_______|
//          _    _    _    _    _    _    _    _    _        ___     ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
//----------------------------------------------------------------------------------


void SHT_ConnectionRest(void)
{  
  unsigned char i; 
  DDRC = 0b00000011;    // DATA Ausgang
  DATA_OUT=1; SCK="0";                    //Initial state
  for(i=0;i<9;i++)                  //9 SCK cycles
  { SCK="1"; 
    delay_us(1);
    SCK="0";
    delay_us(1);
  }
  SHT_Transstart();                   //transmission start
  DDRC = 0b00000010;    // DATA Eingang

//----------------------------------------------------------------------------------
// resets the sensor by a softreset 
//----------------------------------------------------------------------------------


char SHT_SoftRst(void)

  unsigned char error="0";  
  SHT_ConnectionRest();              //reset communication
  error+=SHT_WriteByte(RESET);       //send RESET-command to sensor
  return error;                     //error=1 in case of no response form the sensor

//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
//----------------------------------------------------------------------------------


char SHT_Read_StatusReg(unsigned char *p_value, unsigned char *p_checksum)

  unsigned char error="0";
  SHT_Transstart();                   //transmission start
  error="SHT"_WriteByte(STATUS_REG_R); //send command to sensor
  *p_value=SHT_ReadByte(ACK);        //read status register (8-bit)
  *p_checksum=SHT_ReadByte(noACK);   //read checksum (8-bit)  
  return error;                     //error=1 in case of no response form the sensor
}


//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
//----------------------------------------------------------------------------------


char SHT_Write_StatusReg(unsigned char *p_value)

  unsigned char error="0";
  SHT_Transstart();                   //transmission start
  error+=SHT_WriteByte(STATUS_REG_W);//send command to sensor
  error+=SHT_WriteByte(*p_value);    //send value of status register
  return error;                     //error>=1 in case of no response form the sensor
}   
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
//----------------------------------------------------------------------------------


char SHT_Measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)

  unsigned error="0";
 
 unsigned int temp="0";
  SHT_Transstart();                   //transmission start    


  switch(mode){                     //send command to sensor
    case TEMP        : error+=SHT_WriteByte(MEASURE_TEMP); break;
    case HUMI        : error+=SHT_WriteByte(MEASURE_HUMI); break;
    default     : break;         
  }                  
  DDRC = 0b00000010;    // DATA Eingang
  //等待SHT71AD转换      
 while (1)
 {        
   if(DATA_IN==0) break; //wait until sensor has finished the measurement
  } 
  //for (i=0;i<65535;i++) if(DATA_IN==0) break; //wait until sensor has finished the measurement
  if(DATA_IN) error+=1;                // or timeout (~2 sec.) is reached     
              
  //if (error!=0)
 //{ 
 //while(1); 
 
 //}


  //*(p_value)  =tempervalue[0]=SHT_ReadByte(ACK);    //read the first byte (MSB)  
  //*(p_value+1)=tempervalue[1]=SHT_ReadByte(ACK);    //read the second byte (LSB)
  
  //tempervalue[0]=SHT_ReadByte(ACK);    //read the first byte (MSB)  
  //tempervalue[1]=SHT_ReadByte(ACK);    //read the second byte (LSB)
  switch(mode){                     //send command to sensor
    case TEMP        : temp="0";
                       temp="SHT"_ReadByte(ACK);
                       temp<<=8;
                       tempervalue[0]=temp;
                       temp="0";
                       temp="SHT"_ReadByte(ACK);
                       tempervalue[0]|=temp;
                        break;
    case HUMI        : temp="0";
                       temp="SHT"_ReadByte(ACK);
                       temp<<=8;
                       tempervalue[1]=temp;
                       temp="0";
                       temp="SHT"_ReadByte(ACK);
                       tempervalue[1]|=temp;
                        break;
    default     : break;         
  }   
  *p_checksum =SHT_ReadByte(noACK);  //read checksum     
  return error;


//----------------------------------------------------------------------------------------
// calculates temperature [癈] and humidity [%RH] 
// input :  humi [Ticks] (12 bit) 
//          temp [Ticks] (14 bit)
// output:  humi [%RH]
//          temp [癈]
//----------------------------------------------------------------------------------------
 
  const float C1=-4.0;              // for 12 Bit
  const float C2=+0.0405;           // for 12 Bit
  const float C3=-0.0000028;        // for 12 Bit
  const float T1=+0.01;             // for 14 Bit @ 5V
  const float T2=+0.00008;           // for 14 Bit @ 5V        
  
//void Calc_SHT71(float *p_humidity ,float *p_temperature) 
float Calc_SHT71(float p_humidity ,float *p_temperature)
{
  float t=*p_temperature;           // t:       Temperature [Ticks] 14 Bit 
  float rh="p"_humidity;             // rh:      Humidity [Ticks] 12 Bit
  float rh_lin;                     // rh_lin:  Humidity linear
  float rh_true;                    // rh_true: Temperature compensated humidity
  float t_C;                        // t_C   :  Temperature [癈]


  t_C=t*0.01 - 40;                  //calc. temperature from ticks to [癈]
  rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]
  rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH]
  if(rh_true>100)rh_true=100;       //cut if the value is outside of
  if(rh_true<0.1)rh_true=0.1;       //the physical possible range


  *p_temperature=t_C;               //return temperature [癈]
  //*p_humidity=rh_true;              //return humidity[%RH]
   return rh_true;

//--------------------------------------------------------------------
float Calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// calculates dew point
// input:   humidity [%RH], temperature [癈]
// output:  dew point [癈]
{ float logEx,dew_point;
  logEx="0".66077+7.5*t/(237.3+t)+(log10(h)-2);
  dew_point = (logEx - 0.66077)*237.3/(0.66077+7.5-logEx);
  return dew_point;
}


              
 

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条