/*****************************************************
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条评论)
登录后参与讨论