#include <NXP/iolpc2148.h>
#include <stdio.h>
#define uint16 unsigned short int
#define uchar unsigned char
#define uint unsigned int
#define RS_SET IO0SET=1<<8
#define RS_CLR IO0CLR=1<<8
#define RW_SET IO0SET=1<<9
#define RW_CLR IO0CLR=1<<9
#define EN_SET IO0SET=1<<10
#define EN_CLR IO0CLR=1<<10
#define DataPort(Y) IO0SET=Y
typedef union {
unsigned int i; //定义了两个共用体
float f;
}
value;
enum { TEMP,HUMI};
//void delay1(unsigned int t)
//{
//unsigned int temp=2100;
//for(;t>0;t--)
// for(;temp>0;temp--);
//}
void delay1(void)
{
int a=3000;
while(a--);
}
void LCD_Write_Com(unsigned char com)
{
delay1();
RS_CLR;
RW_CLR;
EN_SET;
DataPort(com);
delay1();
EN_CLR;
IO0CLR=0xff;
}
void LCD_Write_Data(unsigned char Data)
{
delay1();
RS_SET;
RW_CLR;
EN_SET;
DataPort(Data);
delay1();
EN_CLR;
IO0CLR=0xff;
}
/*
* --------------------------------------
* ;模块名称:LCD_init();
* ;功 能:初始化LCD1602
* ;-------------------------------------
*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*显示模式设置*/
delay1();
LCD_Write_Com(0x38);
delay1();
LCD_Write_Com(0x38);
delay1();
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
delay1();
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
/**
* --------------------------------------
* ;模块名称:LCD_disp_char();
* ;功 能:LCD1602显示一个字符函数,在某个屏幕位置上显示一个字符,X(0-15),y(1-2)。
* ;-------------------------------------
*/
void LCD_disp_char(uchar x, uchar y, uchar dat) {
uchar address;
if (y == 1)
address = 0x80 + x;
else
address = 0xc0 + x;
LCD_Write_Com(address);
LCD_Write_Data(dat);
}
/**
* --------------------------------------
* ;模块名称:LCD_disp_str();
* ;功 能:LCD1602显示字符串函数,在某个屏幕起始位置{X(0-15),y(1-2)}上显示一个字符串。
* ;-------------------------------------
*/
void LCD_disp_str(uchar x, uchar y, uchar * str) {
uchar address;
if (y == 1)
address = 0x80 + x;
else
address = 0xc0 + x;
LCD_Write_Com(address);
while (* str != '\0')
// while (*str)
{
LCD_Write_Data(* str);
str++;
}
}
/*----------------------------------------------------------------------------*/
#define CLK_SHT 0x00008000//p0.15
#define DAT_SHT 0x00004000//p0.14
//typedef union {
// unsigned int i; //定义了两个共用体
// float f;
//}
//value;
//enum {
// TEMP,HUMI}; //分别对应温度OR湿度测量
#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
void s_transstart(void)
{
PINSEL0=PINSEL0&0x00000000;
IO0DIR|=DAT_SHT;IO0DIR|=CLK_SHT;
IO0SET=DAT_SHT;
IO0CLR=CLK_SHT;
delay1();
IO0SET=CLK_SHT;
delay1();
IO0CLR=DAT_SHT;
delay1();
IO0CLR=CLK_SHT;
delay1();
IO0SET=CLK_SHT;
delay1();
IO0SET=DAT_SHT;
delay1();
IO0CLR=CLK_SHT;
delay1();
}
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// 连接复位;
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
unsigned char i;
PINSEL0 =PINSEL0&(~DAT_SHT)&(~CLK_SHT);
IO0DIR|=DAT_SHT;IO0DIR|=CLK_SHT;
IO0SET=DAT_SHT;
IO0CLR=CLK_SHT;
delay1(); //准备
for(i=0;i<9;i++) //DATA保持高,SCK时钟触发9次,发送启动传输,通讯即复位
{
IO0SET=CLK_SHT;
delay1();
IO0CLR=CLK_SHT;
delay1();
}
s_transstart();
}
long s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// 写字节函数
{
unsigned char i;
long error=0;
PINSEL0=PINSEL0&0x00000000;
//IO0DIR|=DAT_SHT;
//delay1();
for (i=0x80;i>0;i/=2) //高位为1,循环右移
{
if (i & value) IO0SET=DAT_SHT; //和要发送的数相与,结果为发送的位
else IO0CLR=DAT_SHT;
IO0SET=CLK_SHT;
delay1();
IO0CLR=CLK_SHT;
delay1();
}
IO0SET=DAT_SHT; //release DATA-line
IO0SET=CLK_SHT; //clk #9 for ack
//IO0DIR&=~( 1 << 14);
IO0DIR&=~DAT_SHT;
//delay1();
//error=(IO0PIN & 0x4000); //check ack (DATA will be pulled down by DHT90),DATA在第9个上升沿将被DHT90自动下拉为低电平。
error=(IO0PIN & DAT_SHT);
delay1();
IO0CLR=CLK_SHT;
delay1();
// IO0DIR|=( 1 << 14);
IO0DIR|=DAT_SHT;
IO0SET=DAT_SHT; //release DATA-line
return error; //error=1 in case of no acknowledge //返回:0成功,1失败
}
char s_read_byte(unsigned char ack)
{
unsigned char i,val=0;
PINSEL0=PINSEL0&0x00000000;
//IO0DIR&=~( 1 << 14); //release DATA-line
IO0DIR&=~DAT_SHT;
IO0SET=DAT_SHT;
for (i=0x80;i>0;i/=2) //shift bit for masking
{
IO0SET=CLK_SHT; //clk for SENSI-BUS
if (IO0PIN & 0x4000) val=(val | i); //read bit
delay1();
IO0CLR=CLK_SHT;
delay1();
}
//IO0DIR|=( 1 << 14);
IO0DIR|=DAT_SHT;
if(ack==1)IO0CLR=DAT_SHT; //in case of "ack==1" pull down DATA-Line
else IO0SET=DAT_SHT; //如果是校验(ack==0),读取完后结束通讯
delay1();
IO0SET=CLK_SHT; //clk #9 for ack
delay1();
IO0CLR=CLK_SHT;
delay1();
IO0SET=DAT_SHT; //release DATA-line
return val;
}
//----------------------------------------------------------------------------------
uchar s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset
{
uchar error=0;
s_connectionreset(); //reset communication
error+=s_write_byte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
uchar s_read_statusreg( uchar *p_value, uchar *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
uchar error=0;
s_transstart(); //transmission start
error=s_write_byte(STATUS_REG_R); //send command to sensor
*p_value=s_read_byte(ACK); //read status register (8-bit)
*p_checksum=s_read_byte(noACK); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
uchar s_write_statusreg( uchar *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
uchar error=0;
s_transstart(); //transmission start
error+=s_write_byte(STATUS_REG_W);//send command to sensor
error+=s_write_byte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
char s_measure(unsigned char * p_value, unsigned char * p_checksum, unsigned char mode)
{ // makes a measurement (humidity/temperature) with checksum
unsigned error = 0;
unsigned int i;
s_transstart(); //transmission start
switch (mode) { // send command to sensor
case TEMP : error += s_write_byte(MEASURE_TEMP);
break;
case HUMI : error += s_write_byte(MEASURE_HUMI);
break;
default : break;
}
IO0DIR&=~DAT_SHT;
for (i = 0;i < 65535;i++)
{ error=IO0PIN&DAT_SHT;
if (error==0) break;} //wait until sensor has finished the measurement
if (error) error += 1; // or timeout (~2 sec.) is reached * (p_value) = s_read_byte(ACK); //read the first byte (MSB) * (p_value + 1) = s_read_byte(ACK); //read the second byte (LSB) * p_checksum = s_read_byte(noACK); //read checksum
*(p_value) =s_read_byte(ACK); //read the first byte (MSB)
*(p_value+1)=s_read_byte(ACK); //read the second byte (LSB)
*p_checksum =s_read_byte(noACK); //read checksum
return error;
}
//----------------------------------------------------------------------------------------
void calc_sht75(float *p_humidity ,float *p_temperature)
//void calc_sht75()
{
//----------------------------------------------------------------------------------------
// calculates temperature [癈] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// 温湿度转换公式
//Temperature = d1+d2 * temp[Ticks]
//RH_lin = c1 + c2*SO + c3 * humi[Ticks]
//RH_true = (T - 25)*(t + t * humi[Ticks] ) + RH_lin
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
float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
float t=*p_temperature; // t: Temperature [Ticks] 14 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]
}
//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;
//}
void main()
{
value humi_val, temp_val;
unsigned char error, checksum;
unsigned int shidu,wendu;
PINSEL0=0x00;
//PINSEL1=0x00;
IO0DIR=0xfff;
LCD_Init();
PINSEL0 =PINSEL0&(~DAT_SHT)&(~CLK_SHT);
//PINSEL0 =PINSEL0&0x00000000;
s_connectionreset();
LCD_disp_str(0, 1, "TE");
LCD_disp_str(0, 2, "RH");
// *********初始化温度显示区*********
LCD_disp_str(2, 1, "TTT.TC");
// *********初始化湿度显示区*********
LCD_disp_str(2, 2, "RRR.R%");
delay1();
while(1)
{error = 0;
error += s_measure((unsigned char *) &humi_val . i, &checksum, HUMI); //measure humidity
error += s_measure((unsigned char *) &temp_val . i, &checksum, TEMP); //measure temperature
if (error != 0) s_connectionreset(); //in case of an error: connection reset
else {
humi_val . f = (float)humi_val . i; //converts integer to float
temp_val . f = (float)temp_val . i; //converts integer to float
calc_sht75(&humi_val . f, &temp_val . f);//calculate humidity, temperature
wendu = (int)(10 * temp_val . f);
LCD_disp_char(2, 1, wendu/1000+'0'); //显示温度百位
LCD_disp_char(3, 1, (wendu % 1000) / 100 + '0'); //显示温度十位
LCD_disp_char(4, 1, (wendu % 100) / 10 + '0'); //显示温度个位
LCD_disp_char(6, 1, (wendu % 10) + '0'); //显示温度小数点后第一位
shidu = (int)(10 * humi_val . f);
LCD_disp_char(2, 2, shidu / 1000 + '0'); //显示湿度百位
LCD_disp_char(3, 2, (shidu % 1000) / 100 + '0'); //显示湿度十位
LCD_disp_char(4, 2, (shidu % 100) / 10 + '0'); //显示湿度个位
LCD_disp_char(6, 2, (shidu % 10) + '0'); //显示湿度小数点后第一位
}
delay1();
}
} |
|