SHT10程序代码
- 格式:pdf
- 大小:262.54 KB
- 文档页数:8
这是我自己写的SHT10的程序,SHT1X系列的都适用。
几点说明:1.主要是分以下几个模块写的:SHT10,LCD1602,主函数,头文件。
2.每支SHTxx传感器都在25℃(77 °F)和3.3V条件下进行过标定并且完全符合精度指标.因为考虑到实际硬件5V的电压比较好操作,所以SHT10用的精度采用的为5V时的参数。
其他的都采取默认值(14bit湿度,12bit 温度)。
3.SHT10中所以部分我都编写了。
有的部分在本次程序中没用到,也可以作为参考。
4.所有程序都已经加了注释,且有仿真图。
5.个人认为还可以在此基础上添加个中断。
6.程序编写keil 4 ,仿真protues7.5/****************************************************************************** *****************************************************************************/头文件(tou.h):#ifndef __TOU_H__#define __TOU_H__#include<reg52.h>#include <intrins.h>//#include <math.h> //Keil library#define uchar unsigned charenum {TEMP,HUMI};sbit DATA = P1^7;sbit SCK = P1^6;sbit LcdRs = P2^4;sbit LcdRw = P2^5;sbit LcdEn = P2^6;sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口/******** DS1602函数声明********/void LCD_Initial();void GotoXY(unsigned char x, unsigned char y);void Print(unsigned char *str);void LCD_Write(bit style, unsigned char input);/******** SHT10函数声明********/void s_connectionreset(void);char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);void calc_sth10(float *p_humidity ,float *p_temperature);//float calc_dewpoint(float h,float t);#endif/****************************************************************************** *****************************************************************************/SHT10程序(SHT10.c):#include<tou.h>#define noACK 0 //继续传输数据,用于判断是否结束通讯#define ACK 1 //结束数据传输;//地址命令读/写#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//写字节程序char s_write_byte(unsigned char value){unsigned char i,error=0;for (i=0x80;i>0;i>>=1) //高位为1,循环右移{if (i&value) DA TA=1; //和要发送的数相与,结果为发送的位else DATA=0;SCK=1;_nop_();_nop_();_nop_(); //延时3usSCK=0;}DA TA=1; //释放数据线SCK=1;error=DATA; //检查应答信号,确认通讯正常_nop_();_nop_();_nop_();SCK=0;DA TA=1;return error; //error=1 通讯错误}//读字节程序char s_read_byte(unsigned char ack)//----------------------------------------------------------------------------------{unsigned char i,val=0;DA TA=1; //释放数据线for(i=0x80;i>0;i>>=1) //高位为1,循环右移{SCK=1;if(DATA) val=(val|i); //读一位数据线的值SCK=0;}DA TA=!ack; //如果是校验,读取完后结束通讯;SCK=1;_nop_();_nop_();_nop_(); //延时3usSCK=0;_nop_();_nop_();_nop_();DA TA=1; //释放数据线return val;}//启动传输void s_transstart(void)// generates a transmission start// _____ ________// DATA: |_______|// ___ ___// SCK : ___| |___| |______{DA TA=1; SCK=0; //准备_nop_();SCK=1;_nop_();DA TA=0;_nop_();SCK=0;_nop_();_nop_();_nop_();SCK=1;_nop_();DA TA=1;_nop_();SCK=0;}//连接复位void s_connectionreset(void)// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart// _____________________________________________________ ________ // DATA: |_______|// _ _ _ _ _ _ _ _ _ ___ ___// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______{unsigned char i;DA TA=1; SCK=0; //准备for(i=0;i<9;i++) //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位{SCK=1;SCK=0;}s_transstart(); //启动传输}//软复位程序char s_softreset(void)// resets the sensor by a softreset{unsigned char error=0;s_connectionreset(); //启动连接复位error+=s_write_byte(RESET); //发送复位命令return error; //error=1 通讯错误}/*读状态寄存器char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)//----------------------------------------------------------------------------------// reads the status register with checksum (8-bit){unsigned char error=0;s_transstart(); //transmission starterror=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}//写状态寄存器char s_write_statusreg(unsigned char *p_value)// writes the status register with checksum (8-bit){unsigned char error=0;s_transstart(); //transmission starterror+=s_write_byte(STATUS_REG_W);//send command to sensorerror+=s_write_byte(*p_value); //send value of status registerreturn 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)// 进行温度或者湿度转换,由参数mode决定转换内容;{// enum {TEMP,HUMI}; //已经在头文件中定义unsigned error=0;unsigned int i;s_transstart(); //启动传输switch(mode) //选择发送命令{case TEMP : error+=s_write_byte(MEASURE_TEMP); break; //测量温度case HUMI : error+=s_write_byte(MEASURE_HUMI); break; //测量湿度default : break;}for (i=0;i<65535;i++) if(DA TA==0) break; //等待测量结束if(DATA) error+=1; // 如果长时间数据线没有拉低,说明测量错误*(p_value) =s_read_byte(ACK); //读第一个字节,高字节(MSB)*(p_value+1)=s_read_byte(ACK); //读第二个字节,低字节(LSB)*p_checksum =s_read_byte(noACK); //read CRC校验码return error; // error=1 通讯错误}//温湿度值标度变换及温度补偿void calc_sth10(float *p_humidity ,float *p_temperature){const float C1=-4.0; // 12位湿度精度修正公式const float C2=+0.0405; // 12位湿度精度修正公式const float C3=-0.0000028; // 12位湿度精度修正公式const float T1=+0.01; // 14位温度精度5V条件修正公式const float T2=+0.00008; // 14位温度精度5V条件修正公式float rh=*p_humidity; // rh: 12位湿度float t=*p_temperature; // t: 14位温度float rh_lin; // rh_lin: 湿度linear值float rh_true; // rh_true: 湿度ture值float t_C; // t_C : 温度℃t_C=t*0.01 - 40; //补偿温度rh_lin=C3*rh*rh + C2*rh + C1; //相对湿度非线性补偿rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相对湿度对于温度依赖性补偿if(rh_true>100)rh_true=100; //湿度最大修正if(rh_true<0.1)rh_true=0.1; //湿度最小修正*p_temperature=t_C; //返回温度结果*p_humidity=rh_true; //返回湿度结果}//从相对温度和湿度计算露点/*float calc_dewpoint(float h,float t){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;} *//****************************************************************************** *****************************************************************************/ DS1602程序(1602.c):#include<tou.h>//内部等待函数************************************************************** unsigned char LCD_Wait(void){LcdRs=0;LcdRw=1; _nop_();LcdEn=1; _nop_();LcdEn=0;return DBPort;}//向LCD写入命令或数据******************************************************** #define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 光标返回原点void LCD_Write(bit style, unsigned char input){LcdEn=0;LcdRs=style;LcdRw=0; _nop_();DBPort=input; _nop_();//注意顺序LcdEn=1; _nop_();//注意顺序LcdEn=0; _nop_();LCD_Wait();}//设置显示模式************************************************************ #define LCD_SHOW 0x04 //显示开#define LCD_HIDE 0x00 //显示关#define LCD_CURSOR 0x02 //显示光标#define LCD_NO_CURSOR 0x00 //无光标#define LCD_FLASH 0x01 //光标闪动#define LCD_NO_FLASH 0x00 //光标不闪动void LCD_SetDisplay(unsigned char DisplayMode){LCD_Write(LCD_COMMAND, 0x08|DisplayMode);}//设置输入模式************************************************************ #define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default#define LCD_MOVE 0x01 // 画面可平移#define LCD_NO_MOVE 0x00 //defaultvoid LCD_SetInput(unsigned char InputMode){LCD_Write(LCD_COMMAND, 0x04|InputMode);}//初始化LCD************************************************************ void LCD_Initial(){LcdEn=0;LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动}//液晶字符输入的位置************************void GotoXY(unsigned char x, unsigned char y){if(y==0)LCD_Write(LCD_COMMAND,0x80|x);if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));}//将字符输出到液晶显示void Print(unsigned char *str){while(*str!='\0'){LCD_Write(LCD_DA TA,*str);str++;}}/****************************************************************************** *****************************************************************************/ 主函数(main.c):#include<tou.h>typedef union //定义共用同类型{unsigned int i;float f;} value;//延时函数void delay(int z) //z为毫秒数{int x,y;for(x=z;x>0;x--)for(y=125;y>0;y--);}void main(){unsigned int temp,humi;value humi_val,temp_val; //定义两个共同体,一个用于湿度,一个用于温度// float dew_point; //用于记录露点值unsigned char error; //用于检验是否出现错误unsigned char checksum; //CRCuchar wendu[6]; //用于记录温度uchar shidu[6]; //用于记录湿度LCD_Initial(); //初始化液晶GotoXY(0,0); //选择温度显示位置Print("TEMP: %C"); //5格空格GotoXY(0,1); //选择湿度显示位置Print("HUMI: %RH"); //5格空格s_connectionreset(); //启动连接复位while(1){error=0; //初始化error=0,即没有错误error+=s_measure((unsigned char*)&temp_val.i,&checksum,TEMP); //温度测量error+=s_measure((unsigned char*)&humi_val.i,&checksum,HUMI); //湿度测量if(error!=0) s_connectionreset(); ////如果发生错误,系统复位else{humi_val.f=(float)humi_val.i; //转换为浮点数temp_val.f=(float)temp_val.i; //转换为浮点数calc_sth10(&humi_val.f,&temp_val.f); //修正相对湿度及温度// dew_point=calc_dewpoint(humi_val.f,temp_val.f); //计算e dew_point temp=temp_val.f*10;humi=humi_val.f*10;GotoXY(5,0); //设置温度显示位置wendu[0]=temp/1000+'0'; //温度百位wendu[1]=temp%1000/100+'0'; //温度十位wendu[2]=temp%100/10+'0'; //温度个位wendu[3]=0x2E; //小数点wendu[4]=temp%10+'0'; //温度小数点后第一位Print(wendu); //输出温度GotoXY(5,1); //设置湿度显示位置shidu[0]=humi/1000+'0'; //湿度百位shidu[1]=humi%1000/100+'0'; //湿度十位shidu[2]=humi%100/10+'0'; //湿度个位shidu[3]=0x2E; //小数点shidu[4]=humi%10+'0'; //湿度小数点后第一位Print(shidu); //输出湿度}delay(800); //等待足够长的时间,以现行下一次转换}}/****************************************************************************** *****************************************************************************/ 仿真图:。
XX系统摘要本文是一种由单片机控制的、智能的湿度控制系统,采用STC12C5A60S2单片机为核心,温湿度传感器SHT10、12864液晶显示、WT588D语音芯片组合成的一种智能湿度控制系统。
本系统采用SHT10温湿度传感器进行温度与湿度的感应,湿度大于80%RH的时候,启动风扇进行排风,且语音提示“请注意,湿度过大,已经打开排气扇”,并显示“湿度过大!”,当低于80%的时候,自动停止风扇。
当温度高于30摄氏度的时候,提示“温度过高,已经打开排气扇”,低于30摄氏度就停止风扇。
关鍵词:单片机语音播报 12864液晶 WT588D 温湿度传感器ABSTRACTThis article is a kind of the single chip microcomputer control, intelligent humidity control system, adopting STC12C5A60S2 microcontroller as the core, temperature and humidity sensor SHT10, 12864 liquid crystal display, WT588D speech synthesis of a kind of intelligent chipset humidity control system. The system USES the SHT10 temperature and humidit y sensors for temperature and humidity sensor, relative humidity above 80% RH, start to exhaust fan, and voice prompt "please note, humidity, already open exhaust fan", and display the humidity!" When less than 80% of the time, automatic stop fan. When the temperature is higher than 30 degrees Celsius, suggested that "the temperature too high, already open exhaust fan," less than 30 degrees Celsius stop fan.Keywords: SCM Speech broadcast 12864 LCD WT588D Temperature and humidity sensor第一章绪论1.1课题背景随着国民经济的快速发展,城市建设规模不断扩大,房产的大量开发,智能家居越来越接近人们的生活。
Datasheet SHT1x (SHT10, SHT11, SHT15数字温湿度传感器• 完全标定• 数字信号输出• 低功耗• 卓越的长期稳定性• SMD 封装–适于回流焊接外形尺寸图 1 SHT1x 传感器尺寸(1mm=0.039inch,“ 11”表示该传感器型号为 SHT11。
外部接口:1:GND, 2: DATA, 3: SCK, 4: VDD传感器芯片此说明书适用于 SHT1x-V4。
SHT1x-V4 是第四代硅传感芯片,除了湿度、温度敏感元件以外,还包括一个放大器, A/D 转换器, OTP 内存和数字接口。
第四代传感器在其顶部印有产品批次号,以字母及数字表示,如“ A5Z ”,见图 1。
材质传感器的核心为 CMOS 芯片,外围材料顶层采用环氧 LCP ,底层为 FR4。
传感器符合 ROHS 和WEEE 标准,因此不含 Pb, Cd, Hg, Cr(6+, PBB, PBDE 。
实验包如要进行直接的传感器测量,传感器性能检验或者温湿度实验,客户可选用 EK-H2,其中包括传感器和与电脑配套的软、硬件。
如需进行更复杂的,要求更高的测量,可选用 EK-H3。
它可以同时进行 20个点的温湿度测量。
产品概述SHT1x (包括 SHT10, SHT11 和 SHT15 属于 Sensirion 温湿度传感器家族中的贴片封装系列。
传感器将传感元件和信号处理电路集成在一块微型电路板上,输出完全标定的数字信号。
传感器采用专利的 CMOSens® 技术,确保产品具有极高的可靠性与卓越的长期稳定性。
传感器包括一个电容性聚合体测湿敏感元件、一个用能隙材料制成的测温元件,并在同一芯片上,与 14 位的 A/D 转换器以及串行接口电路实现无缝连接。
因此,该产品具有品质卓越、响应迅速、抗干扰能力强、性价比高等优点。
每个传感器芯片都在极为精确的湿度腔室中进行标定,校准系数以程序形式储存在 OTP 内存中,用于内部的信号校准。
基于51单片机SHT11温湿度传感器检测程序(含电路图)下面是原理图:F面是SHT11与MCU连接的典型电路:下面是源代码:#include <reg52.h>#include <intrins.h>/********************************************************宏定义********************************************************/ #define uint unsigned int#define uchar unsigned char#define noACK 0#define ACK 1#define STATUS_REG_W 0x06#define STATUS_REG_R 0x07#define MEASURE_TEMP 0x03#define MEASURE_HUMI 0x05#define RESET 0x1eenum?{TEMP,HUMI};typedef?union?//定义共用同类型(unsigned?int?i;float?f;} value;/******************************************************** 位定义********************************************************/ sbit lcdrs=P2八0;sbit lcdrw=P2」;sbit lcden=P2八2;sbit SCK = P「0;sbit DATA = P11;/******************************************************** 变量定义********************************************************/ uchar table2[]=〃SHT11 温湿度检测〃; uchar table3[]=〃温度为:℃";uchar table4[]=〃湿度为:〃;uchar table5[]=〃.〃;uchar wendu[6];uchar shidu[6];/******************************************************** 1ms延时函数********************************************************/ void?delay(int?z)(int?x,y;for(x=z;x>0;x--)for(y=125;y>0;y--);)/******************************************************** 50us延时函数********************************************************/ void?delay_50us(uint t)(uint j;for(;t>0;t--)for(j=19;j>0;j--);)/******************************************************** 50ms延时函数********************************************************/ void?delay_50ms(uint t)(uint j;for(;t>0;t--)for(j=6245;j>0;j--);)/******************************************************** 12864液晶写指令********************************************************/ void?write_12864com(uchar com)(lcdrs=0;delay_50us(1);P0=com;lcden=1;delay_50us(10);lcden=0;delay_50us(2);)/******************************************************** 12864液晶写数据********************************************************/ void?write_dat(uchar dat)(lcdrs=1;lcdrw=0;delay_50us(1);P0=dat;lcden=1;delay_50us(10);lcden=0;delay_50us(2);)/******************************************************** 12864液晶初始化********************************************************/ void?init128641cd(void)(delay_50ms(2);write_12864com(0x30);delay_50us(4);write_12864com(0x30);delay_50us(4);write_12864com(0x0f);delay_50us(4);write_12864com(0x01);delay_50us(240);write_12864com(0x06);delay_50us(10);write_12864com(0x0c);delay_50us(10);)/******************************************************** 12864液晶显示函数********************************************************/ void?display1(void)(uchar i;write_12864com(0x80);for(i=0;i<18;i++)(write_dat(table2[i]);delay_50us(1);))/******************************************************** 12864液晶显示函数********************************************************/ void?display2(void)(uchar i;write_12864com(0x90);for(i=0;i<18;i++)(write_dat(table3[i]);delay_50us(1);))/******************************************************** 12864液晶显示函数********************************************************/ void?display3(void)(uchar i;write_12864com(0x88);for(i=0;i<8;i++)(write_dat(table4[i]);delay_50us(1);))/******************************************************** 12864液晶显示函数********************************************************/ void?displaywendu(void)(uchar i;write_12864com(0x94);for(i=0;i<3;i++)(write_dat(wendu[i]);delay_50us(1);)for(i=0;i<1;i++)(write_dat(table5[i]);delay_50us(1);)for(i=4;i<5;i++)(write_dat(wendu[i]);delay_50us(1);))/******************************************************** 12864液晶显示函数********************************************************/ void?displayshidu(void)(uchar i;write_12864com(0x8C);for(i=0;i<3;i++)(write_dat(shidu[i]);delay_50us(1);)for(i=0;i<1;i++)(write_dat(table5[i]);delay_50us(1);)for(i=4;i<5;i++)(write_dat(shidu[i]);delay_50us(1);))/******************************************************** SHT11写字节程序********************************************************/char?s_write_byte(unsigned?char?value)(unsigned?char?i,error=0;for?(i=0x80;i>0;i>>=1)?//高位为 1,循环右移(if?(i&value) DATA=1;?//和要发送的数相与,结果为发送的位 else?DATA=0; SCK=1;_nop_();_nop_();_nop_();?//延时 3usSCK=0;)DATA=1;?//释放数据线SCK=1;error=DATA;?//检查应答信号,确认通讯正常_nop_();_nop_();_nop_();SCK=0;DATA=1;return?error;?//error=1 通讯错误)/******************************************************** SHT11读字节程序********************************************************/char?s_read_byte(unsigned?char?ack)(unsigned?char?i,val=0;DATA=1;?//释放数据线for(i=0x80;i>0;i>>=1)?//高位为 1,循环右移(SCK=1;if(DATA) val=(val|i);?//读一位数据线的值SCK=0;)DATA=!ack;?SCK=1;_nop_();_nop_();_nop_();?//延时 3usSCK=0;_nop_();_nop_();_nop_();DATA=1;?//释放数据线return?val;)/********************************************************SHT11启动传输********************************************************/void?s_transstart(void)(DATA=1; SCK=0;?//准备_nop_();SCK=1;_nop_();DATA=0;_nop_();SCK=0;_nop_();_nop_();_nop_();SCK=1;_nop_();DATA=1;_nop_();SCK=0;)/********************************************************SHT11连接复位********************************************************/void?s_connectionreset(void)(unsigned?char?i;DATA=1; SCK=0;?//准备for(i=0;i<9;i++)?//DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位(SCK=1;SCK=0;)s_transstart();?//启动传输)/******************************************************** SHT11温湿度检测********************************************************/char?s_measure(unsigned?char?*p_value, unsigned?char?*p_checksum, unsigned?charmode)(unsigned error=0;unsigned?int?i;s_transstart();?//启动传输switch(mode)?〃选择发送命令 (case?TEMP : error+=s_write_byte(MEASURE_TEMP);?break;?〃测量温度case?HUMI : error+=s_write_byte(MEASURE_HUMI);?break;?〃测量湿度default?:?break;)for?(i=0;i<65535;i++)?if(DATA==0)?break;?〃等待测量结束if(DATA) error+=1;?//如果长时间数据线没有拉低,说明测量错误 *(p_value) =s_read_byte(ACK);?//读第一个字节,高字节(MSB)*(p_value+1)=s_read_byte(ACK);?//读第二个字节,低字节(LSB) *p_checksum =s_read_byte(noACK);?//read CRC 校验码 return?error;?// error=1 通讯错误)/********************************************************SHT11温湿度值标度变换及温度补偿********************************************************/void?calc_sth10(float?*p_humidity ,float?*p_temperature) (const?float?C1=-4.0;?// 12位湿度精度修正公式const?float?C2=+0.0405;?// 12 位湿度精度修正公式const?float?C3=-0.0000028;?// 12 位湿度精度修正公式 const?float?T1=+0.01;?// 14位温度精度5V条件修正公式 const?float?T2=+0.00008;?// 14位温度精度5V条件修正公式float?rh=*p_humidity;?// rh: 12 位湿度float?t=*p_temperature;?// t: 14 位温度 float?rh_lin;?// rh_lin: 湿度linear 值 float?rh_true;?// rh_true: 湿度 ture 值 float?t_C;?// t_C :温度℃t_C=t*0.01 - 40;?//补偿温度rh_lin=C3*rh*rh + C2*rh + C1;?//相对湿度非线性补偿rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;?//相对湿度对于温度依赖性补偿if(rh_true>100)rh_true=100;?//湿度最大修正if(rh_true<0.1)rh_true=0.1;?//湿度最小修正*p_temperature=t_C;?//返回温度结果*p_humidity=rh_true;?//返回湿度结果)/********************************************************主函数********************************************************/ void?main(void)(unsigned?int?temp,humi;value humi_val,temp_val;?//定义两个共同体,一个用于湿度,一个用于温度unsigned?char?error;?//用于检验是否出现错误unsigned?char?checksum;?//CRCinit12864lcd();display1();display2();display3();s_connectionreset();?//启动连接复位while(1)(error=0;?//初始化error=0,即没有错误error+=s_measure((unsigned?char*)&temp_val.i,&checksum,TEMP);?//温度测量error+=s_measure((unsigned?char*)&humi_val.i,&checksum,HUMI);?//湿度测量if(error!=0) s_connectionreset();?////如果发生错误,系统复位else{ _humi_val.f=(float)humi_val.i;?//转换为浮点数temp_val.f=(float)temp_val.i;?//转换为浮点数calc_sth10(&humi_val.f,&temp_val.f);?//修正相对湿度及温度temp=temp_val.f*10;humi=humi_val.f*10;wendu[0]=temp/1000+'0';?//温度百位wendu[1]=temp%1000/100+'0';?//温度十位wendu[2]=temp%100/10+'0';//温度个位wendu[3]=0x2E;?//小数点wendu[4]=temp%10+'0';?//温度小数点后第一位displaywendu();shidu[0]=humi/1000+'0';?//湿度百位shidu[1]=humi%1000/100+'0';?//湿度十位shidu[2]=humi%100/10+'0';?//湿度个位shidu[3]=0x2E;?//小数点shidu[4]=humi%10+'0';?//湿度小数点后第一位displayshidu();)delay(800);//等待足够长的时间,以现行下一次转换) )相关手册资料及源码下载地址:。
#include "stdafx.h"#include "bsp.h"//#include <s3c6410.h>#include <DrvLib.h>#include <winuser.h>#include "shidu.h"// humidity virtual addressstatic volatile S3C6410_GPIO_REG *v_pIOPregs;#define noACK 0 //继续传输数据,用于判断是否结束通讯#define ACK 1 //结束数据传输;//地址命令#define STATUS_REG_W 0x06 //000 00110 写寄存器#define STATUS_REG_R 0x07 //000 00111 读寄存器#define MEASURE_TEMP 0x03 //000 00011 温度测量#define MEASURE_HUMI 0x05 //000 00101 湿度测量#define RESET 0x1e //000 11110 软复位//typedef struct//{// int integer;// int decimal;//}HumHandle;//小数 decimal、整数 integer////// global variable//HumHandle g_Hum;float g_Hum;//----------------------------------------------------------------------------/ /// DLL entry////----------------------------------------------------------------------------/ /BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:OutputDebugString(L"\n Humidity - DLL_PROCESS_ATTACH\n");RETAILMSG(1,(TEXT("Humidity - DLL_PROCESS_ATTACH\n")));break;case DLL_PROCESS_DETACH:RETAILMSG(1,(TEXT("Humidity - DLL_PROCESS_DETACH\n")));break;case DLL_THREAD_ATTACH:break;case DLL_THREAD_DETACH:break;default:break;}return TRUE;}//----------------------------------------------------------------------------/ /// Delay//----------------------------------------------------------------------------/ /static void Delay(UINT32 count){volatile int i, j = 0;volatile static int loop = S3C6410_ACLK/1000000;for(;count > 0;count--)for(i=0;i < loop; i+=15) { j++; }}static void Delay_ms(UINT32 count){volatile int i, j = 0;volatile static int loop = S3C6410_ACLK/1000;for(;count > 0;count--)for(i=0;i < loop; i+=15) { j++; }}//----------------------------------------------------------------------------------// GPPCON9 =01 "DATA输出" ;=00 "DATA输入"//----------------------------------------------------------------------------------void Data_out(void){v_pIOPregs->GPPCON &= ~(0x3<<(9*2)); //GPP9 = 00v_pIOPregs->GPPCON |= (0x1<<(9*2)); //目的:GPP9 = 01}/*GPPCON & = (0x3<<(8*2)表示0011中的11左移8*2=16位,即将16到17位置1GPPCON & = ((0x3<<(8*2))|(0x3<<(9*2)))表示将16到19位分别置1GPPCON & = ~((0x3<<(8*2))|(0x3<<(9*2)))表示将GPPCON的16到19位分别置0*/void Data_in(void){v_pIOPregs->GPPCON &= ~(0xf<<(9*2));//GPP9 = 00}//----------------------------------------------------------------------------------// GPPCON8 =01 "SCK输出" ;=00 "SCK输入"//----------------------------------------------------------------------------------void Sck_out(void){v_pIOPregs->GPPCON &= ~(0x3<<(8*2)); //GPP8 = 00v_pIOPregs->GPPCON |= (0x1<<(8*2)); //目的:GPP8 = 01}void Sck_1(void){v_pIOPregs->GPPDAT |= (0x1<<8); //SCK=1; GPP8=1 }void Sck_0(void){v_pIOPregs->GPPDAT &= ~(0x1<<8); //SCK=0; GPP8=0 }void Data_1(void){v_pIOPregs->GPPDAT |= (0x1<<9); //DATA=1; GPP9=1 }void Data_0(void){v_pIOPregs->GPPDAT &= ~(0x1<<9); //DATA=1; GPP9=0 }//----------------------------------------------------------------------------------// 启动传输// _____ ________// DATA: |_______|// ___ ___// SCK : ___| |___| |______//----------------------------------------------------------------------------------void s_transstart(void){Data_out();Sck_out();Data_1(); //准备Sck_0(); //准备Delay(2);Sck_1(); //SCK=1;Delay(2);Data_0(); //DATA=0;Delay(2);Sck_0(); //SCK=0 ;Delay(5);Sck_1(); //SCK=1;Delay(2);Data_1(); //DATA=1;Delay(2);Sck_0(); //SCK=0 ;RETAILMSG(1, (TEXT("s_transport\r\n")));}//----------------------------------------------------------------------------------// 连接复位;// _____________________________________________________ ________ // DATA: |_______|// _ _ _ _ _ _ _ _ _ ___ ___// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______ //----------------------------------------------------------------------------------void s_connectionreset(void){unsigned char i;Data_out();Sck_out();Data_1(); //准备Sck_0(); //准备Delay(1);for(i=0;i<9;i++) //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位{Sck_1(); //SCK=1;Delay(1);Sck_0(); //SCK=0Delay(1);}s_transstart(); //启动传输RETAILMSG(1, (TEXT("s_connectionreset\r\n")));}//----------------------------------------------------------------------------------// 写字节函数//----------------------------------------------------------------------------------char sth_Wbyte(unsigned char cmd){unsigned char i,j,error=0;//在串口打印信息,显示正在写入数据为测量温度命令或湿度命令if (cmd==MEASURE_TEMP){RETAILMSG(1, (TEXT("write_byte temp\r\n")));}else if (cmd ==MEASURE_HUMI){RETAILMSG(1, (TEXT("write_byte humi\r\n")));}Sck_out();Data_out();for (i=0x80;i>0;i/=2) //高位为1,循环右移{if (i & cmd)Data_1(); // DATA=1 和要发送的数相与,结果为发送的位elseData_0(); //DATA=0;Delay(2);Sck_1(); //SCK=1;Delay(5);Sck_0(); //SCK=0 ;}Data_1(); // DATA=1 释放数据线//写入数据之后,测试ACK处,DATA有没有被拉低Sck_1(); //SCK=1; clk #9 for ackData_in(); //设置gpp9为输入口(input)Delay(2);j = (v_pIOPregs->GPPDAT)&(0x1<<9);if(j){error = 0;error += 1; // 如果长时间数据线没有拉低,说明测量错误RETAILMSG(1, (TEXT("wbyte_ack_ladi: error=%d\r\n"),error));}else{RETAILMSG(1, (TEXT("wbyte_ack_ladi: success\r\n")));}Sck_0(); //SCK=0 ;Data_out();Data_1();RETAILMSG(1, (TEXT("s_wbyte: error=%d\r\n"),error));return error; //error=1 通讯错误}//----------------------------------------------------------------------------------// 读字节函数//----------------------------------------------------------------------------------char sth_Rbyte(unsigned char ack){unsigned char i,j=0,val=0;Data_out();Data_1(); // DATA=1 数据线为高释放数据线Sck_out();Data_in(); //设置gpp9为输入口(input)for(i=0x80; i>0; i/=2) //右移位{Sck_1(); //SCK=1;Delay(2);j = (v_pIOPregs->GPPDAT)&(0x1<<9); //取DATA的值if (j)val = (val | i); /*读数据线的值,或“|”等价于加,即与1对应位加1,其余加0。
基于51单片机SHT11温湿度传感器检测程序(含电路图)?下面是原理图:下面是SHT11与MCU连接的典型电路:下面是源代码:#include <reg52.h>#include <intrins.h>/********************************************************宏定义********************************************************/#define uint unsigned int#define uchar unsigned char#define noACK 0#define ACK 1#define STATUS_REG_W 0x06#define STATUS_REG_R 0x07#define MEASURE_TEMP 0x03#define MEASURE_HUMI 0x05#define RESET 0x1eenum?{TEMP,HUMI};typedef?union?//定义共用同类型{unsigned?int?i;float?f;} value;/******************************************************** ?位定义********************************************************/ sbit lcdrs=P2^0;sbit lcdrw=P2^1;sbit lcden=P2^2;sbit SCK = P1^0;sbit DATA = P1^1;/******************************************************** 变量定义********************************************************/ uchar table2[]="SHT11 温湿度检测";uchar table3[]="温度为:℃";uchar table4[]="湿度为:";uchar table5[]=".";uchar wendu[6];uchar shidu[6];/******************************************************** 1ms延时函数********************************************************/ void?delay(int?z){int?x,y;for(x=z;x>0;x--)for(y=125;y>0;y--);}/******************************************************** 50us延时函数********************************************************/ void?delay_50us(uint t){uint j;for(;t>0;t--)for(j=19;j>0;j--);}/******************************************************** 50ms延时函数********************************************************/ void?delay_50ms(uint t){uint j;for(;t>0;t--)for(j=6245;j>0;j--);}/******************************************************** 12864液晶写指令********************************************************/ void?write_12864com(uchar com){lcdrs=0;delay_50us(1);P0=com;lcden=1;delay_50us(10);lcden=0;delay_50us(2);}/******************************************************** 12864液晶写数据********************************************************/ void?write_dat(uchar dat){lcdrs=1;lcdrw=0;delay_50us(1);P0=dat;lcden=1;delay_50us(10);lcden=0;delay_50us(2);}/******************************************************** 12864液晶初始化********************************************************/ void?init12864lcd(void){delay_50ms(2);write_12864com(0x30);delay_50us(4);write_12864com(0x30);delay_50us(4);write_12864com(0x0f);delay_50us(4);write_12864com(0x01);delay_50us(240);write_12864com(0x06);delay_50us(10);write_12864com(0x0c);delay_50us(10);}/******************************************************** 12864液晶显示函数********************************************************/ void?display1(void){uchar i;write_12864com(0x80);for(i=0;i<18;i++){write_dat(table2[i]);delay_50us(1);}}/******************************************************** 12864液晶显示函数********************************************************/ void?display2(void){uchar i;write_12864com(0x90);for(i=0;i<18;i++){write_dat(table3[i]);delay_50us(1);}}/******************************************************** 12864液晶显示函数********************************************************/ void?display3(void){uchar i;write_12864com(0x88);for(i=0;i<8;i++){write_dat(table4[i]);delay_50us(1);}}/******************************************************** 12864液晶显示函数********************************************************/ void?displaywendu(void){uchar i;write_12864com(0x94);for(i=0;i<3;i++){write_dat(wendu[i]);delay_50us(1);}for(i=0;i<1;i++){write_dat(table5[i]);delay_50us(1);}for(i=4;i<5;i++){write_dat(wendu[i]);delay_50us(1);}}/******************************************************** 12864液晶显示函数********************************************************/ void?displayshidu(void){uchar i;write_12864com(0x8C);for(i=0;i<3;i++){write_dat(shidu[i]);delay_50us(1);}for(i=0;i<1;i++){write_dat(table5[i]);delay_50us(1);}for(i=4;i<5;i++){write_dat(shidu[i]);delay_50us(1);}/******************************************************** SHT11写字节程序********************************************************/ char?s_write_byte(unsigned?char?value){unsigned?char?i,error=0;for?(i=0x80;i>0;i>>=1)?//高位为1,循环右移{if?(i&value) DATA=1;?//和要发送的数相与,结果为发送的位 else?DATA=0;SCK=1;_nop_();_nop_();_nop_();?//延时3usSCK=0;}DATA=1;?//释放数据线SCK=1;error=DATA;?//检查应答信号,确认通讯正常_nop_();_nop_();_nop_();SCK=0;DATA=1;return?error;?//error=1 通讯错误}/******************************************************** SHT11读字节程序********************************************************/ char?s_read_byte(unsigned?char?ack){unsigned?char?i,val=0;DATA=1;?//释放数据线for(i=0x80;i>0;i>>=1)?//高位为1,循环右移{SCK=1;if(DATA) val=(val|i);?//读一位数据线的值SCK=0;}DATA=!ack;?SCK=1;_nop_();_nop_();_nop_();?//延时3usSCK=0;_nop_();_nop_();_nop_();DATA=1;?//释放数据线return?val;/********************************************************SHT11启动传输********************************************************/void?s_transstart(void){DATA=1; SCK=0;?//准备_nop_();SCK=1;_nop_();DATA=0;_nop_();SCK=0;_nop_();_nop_();_nop_();SCK=1;_nop_();DATA=1;_nop_();SCK=0;}/********************************************************SHT11连接复位********************************************************/void?s_connectionreset(void){unsigned?char?i;DATA=1; SCK=0;?//准备for(i=0;i<9;i++)?//DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位{SCK=1;SCK=0;}s_transstart();?//启动传输}/********************************************************SHT11温湿度检测********************************************************/char?s_measure(unsigned?char?*p_value, unsigned?char?*p_checksum, unsigned?charmode){unsigned error=0;unsigned?int?i;s_transstart();?//启动传输switch(mode)?//选择发送命令{case?TEMP : error+=s_write_byte(MEASURE_TEMP);?break;?//测量温度case?HUMI : error+=s_write_byte(MEASURE_HUMI);?break;?//测量湿度default?:?break;}for?(i=0;i<65535;i++)?if(DATA==0)?break;?//等待测量结束if(DATA) error+=1;?// 如果长时间数据线没有拉低,说明测量错误*(p_value) =s_read_byte(ACK);?//读第一个字节,高字节 (MSB)*(p_value+1)=s_read_byte(ACK);?//读第二个字节,低字节 (LSB)*p_checksum =s_read_byte(noACK);?//read CRC校验码return?error;?// error=1 通讯错误}/********************************************************SHT11温湿度值标度变换及温度补偿********************************************************/void?calc_sth10(float?*p_humidity ,float?*p_temperature){const?float?C1=-4.0;?// 12位湿度精度修正公式const?float?C2=+0.0405;?// 12位湿度精度修正公式const?float?C3=-0.0000028;?// 12位湿度精度修正公式const?float?T1=+0.01;?// 14位温度精度 5V条件修正公式const?float?T2=+0.00008;?// 14位温度精度 5V条件修正公式float?rh=*p_humidity;?// rh: 12位湿度float?t=*p_temperature;?// t: 14位温度float?rh_lin;?// rh_lin: 湿度 linear值float?rh_true;?// rh_true: 湿度 ture值float?t_C;?// t_C : 温度℃t_C=t*0.01 - 40;?//补偿温度rh_lin=C3*rh*rh + C2*rh + C1;?//相对湿度非线性补偿rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;?//相对湿度对于温度依赖性补偿if(rh_true>100)rh_true=100;?//湿度最大修正if(rh_true<0.1)rh_true=0.1;?//湿度最小修正*p_temperature=t_C;?//返回温度结果*p_humidity=rh_true;?//返回湿度结果}/********************************************************?主函数********************************************************/void?main(void){unsigned?int?temp,humi;value humi_val,temp_val;?//定义两个共同体,一个用于湿度,一个用于温度 unsigned?char?error;?//用于检验是否出现错误unsigned?char?checksum;?//CRCinit12864lcd();display1();display2();display3();s_connectionreset();?//启动连接复位while(1){error=0;?//初始化error=0,即没有错误error+=s_measure((unsigned?char*)&temp_val.i,&checksum,TEMP);?//温度测量error+=s_measure((unsigned?char*)&humi_val.i,&checksum,HUMI);?//湿度测量if(error!=0) s_connectionreset();?////如果发生错误,系统复位else{humi_val.f=(float)humi_val.i;?//转换为浮点数temp_val.f=(float)temp_val.i;?//转换为浮点数calc_sth10(&humi_val.f,&temp_val.f);?//修正相对湿度及温度temp=temp_val.f*10;humi=humi_val.f*10;wendu[0]=temp/1000+'0';?//温度百位wendu[1]=temp%1000/100+'0';?//温度十位?wendu[2]=temp%100/10+'0';?//温度个位wendu[3]=0x2E;?//小数点wendu[4]=temp%10+'0';?//温度小数点后第一位displaywendu();shidu[0]=humi/1000+'0';?//湿度百位shidu[1]=humi%1000/100+'0';?//湿度十位shidu[2]=humi%100/10+'0';?//湿度个位shidu[3]=0x2E;?//小数点shidu[4]=humi%10+'0';?//湿度小数点后第一位displayshidu();}?delay(800);?//等待足够长的时间,以现行下一次转换}}相关手册资料及源码下载地址:。
这是我自己写的SHT10的程序,SHT1X系列的都适用。
几点说明:1.主要是分以下几个模块写的:SHT10,LCD1602,主函数,头文件。
2.每支SHTxx传感器都在25℃(77 °F)和3.3V条件下进行过标定并且完全符合精度指标.因为考虑到实际硬件5V的电压比较好操作,所以SHT10用的精度采用的为5V时的参数。
其他的都采取默认值(14bit湿度,12bit 温度)。
3.SHT10中所以部分我都编写了。
有的部分在本次程序中没用到,也可以作为参考。
4.所有程序都已经加了注释,且有仿真图。
5.个人认为还可以在此基础上添加个中断。
6.程序编写keil 4 ,仿真protues7.5/****************************************************************************** *****************************************************************************/头文件(tou.h):#ifndef __TOU_H__#define __TOU_H__#include<reg52.h>#include <intrins.h>//#include <math.h> //Keil library#define uchar unsigned charenum {TEMP,HUMI};sbit DATA = P1^7;sbit SCK = P1^6;sbit LcdRs = P2^4;sbit LcdRw = P2^5;sbit LcdEn = P2^6;sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口/******** DS1602函数声明********/void LCD_Initial();void GotoXY(unsigned char x, unsigned char y);void Print(unsigned char *str);void LCD_Write(bit style, unsigned char input);/******** SHT10函数声明********/void s_connectionreset(void);char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);void calc_sth10(float *p_humidity ,float *p_temperature);//float calc_dewpoint(float h,float t);#endif/****************************************************************************** *****************************************************************************/SHT10程序(SHT10.c):#include<tou.h>#define noACK 0 //继续传输数据,用于判断是否结束通讯#define ACK 1 //结束数据传输;//地址命令读/写#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//写字节程序char s_write_byte(unsigned char value){unsigned char i,error=0;for (i=0x80;i>0;i>>=1) //高位为1,循环右移{if (i&value) DATA=1; //和要发送的数相与,结果为发送的位else DATA=0;SCK=1;_nop_();_nop_();_nop_(); //延时3usSCK=0;}DA TA=1; //释放数据线SCK=1;error=DATA; //检查应答信号,确认通讯正常_nop_();_nop_();_nop_();SCK=0;DA TA=1;return error; //error=1 通讯错误}//读字节程序char s_read_byte(unsigned char ack)//----------------------------------------------------------------------------------{unsigned char i,val=0;DA TA=1; //释放数据线for(i=0x80;i>0;i>>=1) //高位为1,循环右移{SCK=1;if(DATA) val=(val|i); //读一位数据线的值SCK=0;}DATA=!ack; //如果是校验,读取完后结束通讯;SCK=1;_nop_();_nop_();_nop_(); //延时3usSCK=0;_nop_();_nop_();_nop_();DA TA=1; //释放数据线return val;}//启动传输void s_transstart(void)// generates a transmission start// _____ ________// DATA: |_______|// ___ ___// SCK : ___| |___| |______{DA TA=1; SCK=0; //准备_nop_();SCK=1;_nop_();DA TA=0;_nop_();SCK=0;_nop_();_nop_();_nop_();SCK=1;_nop_();DA TA=1;_nop_();SCK=0;}//连接复位void s_connectionreset(void)// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart// _____________________________________________________ ________ // DATA: |_______|// _ _ _ _ _ _ _ _ _ ___ ___// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______{unsigned char i;DA TA=1; SCK=0; //准备for(i=0;i<9;i++) //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位{SCK=1;SCK=0;}s_transstart(); //启动传输}//软复位程序char s_softreset(void)// resets the sensor by a softreset{unsigned char error=0;s_connectionreset(); //启动连接复位error+=s_write_byte(RESET); //发送复位命令return error; //error=1 通讯错误}/*读状态寄存器char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)//----------------------------------------------------------------------------------// reads the status register with checksum (8-bit){unsigned char error=0;s_transstart(); //transmission starterror=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}//写状态寄存器char s_write_statusreg(unsigned char *p_value)// writes the status register with checksum (8-bit){unsigned char error=0;s_transstart(); //transmission starterror+=s_write_byte(STATUS_REG_W);//send command to sensorerror+=s_write_byte(*p_value); //send value of status registerreturn 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)// 进行温度或者湿度转换,由参数mode决定转换内容;{// enum {TEMP,HUMI}; //已经在头文件中定义unsigned error=0;unsigned int i;s_transstart(); //启动传输switch(mode) //选择发送命令{case TEMP : error+=s_write_byte(MEASURE_TEMP); break; //测量温度case HUMI : error+=s_write_byte(MEASURE_HUMI); break; //测量湿度default : break;}for (i=0;i<65535;i++) if(DA TA==0) break; //等待测量结束if(DATA) error+=1; // 如果长时间数据线没有拉低,说明测量错误*(p_value) =s_read_byte(ACK); //读第一个字节,高字节(MSB)*(p_value+1)=s_read_byte(ACK); //读第二个字节,低字节(LSB)*p_checksum =s_read_byte(noACK); //read CRC校验码return error; // error=1 通讯错误}//温湿度值标度变换及温度补偿void calc_sth10(float *p_humidity ,float *p_temperature){const float C1=-4.0; // 12位湿度精度修正公式const float C2=+0.0405; // 12位湿度精度修正公式const float C3=-0.0000028; // 12位湿度精度修正公式const float T1=+0.01; // 14位温度精度5V条件修正公式const float T2=+0.00008; // 14位温度精度5V条件修正公式float rh=*p_humidity; // rh: 12位湿度float t=*p_temperature; // t: 14位温度float rh_lin; // rh_lin: 湿度linear值float rh_true; // rh_true: 湿度ture值float t_C; // t_C : 温度℃t_C=t*0.01 - 40; //补偿温度rh_lin=C3*rh*rh + C2*rh + C1; //相对湿度非线性补偿rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //相对湿度对于温度依赖性补偿if(rh_true>100)rh_true=100; //湿度最大修正if(rh_true<0.1)rh_true=0.1; //湿度最小修正*p_temperature=t_C; //返回温度结果*p_humidity=rh_true; //返回湿度结果}//从相对温度和湿度计算露点/*float calc_dewpoint(float h,float t){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;} *//****************************************************************************** *****************************************************************************/ DS1602程序(1602.c):#include<tou.h>//内部等待函数************************************************************** unsigned char LCD_Wait(void){LcdRs=0;LcdRw=1; _nop_();LcdEn=1; _nop_();LcdEn=0;return DBPort;}//向LCD写入命令或数据******************************************************** #define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 光标返回原点void LCD_Write(bit style, unsigned char input){LcdEn=0;LcdRs=style;LcdRw=0; _nop_();DBPort=input; _nop_();//注意顺序LcdEn=1; _nop_();//注意顺序LcdEn=0; _nop_();LCD_Wait();}//设置显示模式************************************************************ #define LCD_SHOW 0x04 //显示开#define LCD_HIDE 0x00 //显示关#define LCD_CURSOR 0x02 //显示光标#define LCD_NO_CURSOR 0x00 //无光标#define LCD_FLASH 0x01 //光标闪动#define LCD_NO_FLASH 0x00 //光标不闪动void LCD_SetDisplay(unsigned char DisplayMode){LCD_Write(LCD_COMMAND, 0x08|DisplayMode);}//设置输入模式************************************************************ #define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default#define LCD_MOVE 0x01 // 画面可平移#define LCD_NO_MOVE 0x00 //defaultvoid LCD_SetInput(unsigned char InputMode){LCD_Write(LCD_COMMAND, 0x04|InputMode);}//初始化LCD************************************************************ void LCD_Initial(){LcdEn=0;LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动}//液晶字符输入的位置************************void GotoXY(unsigned char x, unsigned char y){if(y==0)LCD_Write(LCD_COMMAND,0x80|x);if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));}//将字符输出到液晶显示void Print(unsigned char *str){while(*str!='\0'){LCD_Write(LCD_DA TA,*str);str++;}}/****************************************************************************** *****************************************************************************/ 主函数(main.c):#include<tou.h>typedef union //定义共用同类型{unsigned int i;float f;} value;//延时函数void delay(int z) //z为毫秒数{int x,y;for(x=z;x>0;x--)for(y=125;y>0;y--);}void main(){unsigned int temp,humi;value humi_val,temp_val; //定义两个共同体,一个用于湿度,一个用于温度// float dew_point; //用于记录露点值unsigned char error; //用于检验是否出现错误unsigned char checksum; //CRCuchar wendu[6]; //用于记录温度uchar shidu[6]; //用于记录湿度LCD_Initial(); //初始化液晶GotoXY(0,0); //选择温度显示位置Print("TEMP: %C"); //5格空格GotoXY(0,1); //选择湿度显示位置Print("HUMI: %RH"); //5格空格s_connectionreset(); //启动连接复位while(1){error=0; //初始化error=0,即没有错误error+=s_measure((unsigned char*)&temp_val.i,&checksum,TEMP); //温度测量error+=s_measure((unsigned char*)&humi_val.i,&checksum,HUMI); //湿度测量if(error!=0) s_connectionreset(); ////如果发生错误,系统复位else{humi_val.f=(float)humi_val.i; //转换为浮点数temp_val.f=(float)temp_val.i; //转换为浮点数calc_sth10(&humi_val.f,&temp_val.f); //修正相对湿度及温度// dew_point=calc_dewpoint(humi_val.f,temp_val.f); //计算e dew_point temp=temp_val.f*10;humi=humi_val.f*10;GotoXY(5,0); //设置温度显示位置wendu[0]=temp/1000+'0'; //温度百位wendu[1]=temp%1000/100+'0'; //温度十位wendu[2]=temp%100/10+'0'; //温度个位wendu[3]=0x2E; //小数点wendu[4]=temp%10+'0'; //温度小数点后第一位Print(wendu); //输出温度GotoXY(5,1); //设置湿度显示位置shidu[0]=humi/1000+'0'; //湿度百位shidu[1]=humi%1000/100+'0'; //湿度十位shidu[2]=humi%100/10+'0'; //湿度个位shidu[3]=0x2E; //小数点shidu[4]=humi%10+'0'; //湿度小数点后第一位Print(shidu); //输出湿度}delay(800); //等待足够长的时间,以现行下一次转换}}/****************************************************************************** *****************************************************************************/ 仿真图:。
附录1 SHT10系统原理图附录2 SHT10系统程序//温湿度监控C语言源程序#include <reg51.h>#include <intrins.h>#include <math.h>#include <stdio.h>/******************** LCD1602设置****************************************/#define LCD_DB P0sbit LCD_RS=P2^5;sbit LCD_RW=P2^6;sbit LCD_E=P2^7;/******定义函数****************/#define uchar unsigned char#define uint unsigned intvoid LCD_init(void); //初始化函数void LCD_write_command(uchar command); //写指令函数void LCD_write_data(uchar dat); //写数据函数void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2) void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602显示字符串函数void delay_n10us(uint n); //延时函数/**************************************模块名称:LCD_init(); 功能:初始化LCD1602***************************************/void LCD_init(void){delay_n10us(10);LCD_write_command(0x38);//设置8位格式,2行,5x7delay_n10us(10);LCD_write_command(0x0c);//整体显示,关光标,不闪烁delay_n10us(10);LCD_write_command(0x06);//设定输入方式,增量不移位delay_n10us(10);LCD_write_command(0x01);//清除屏幕显示delay_n10us(100); //延时清屏,延时函数,延时约n个10us}/*****************************************模块名称:LCD_write_command();功能:LCD1602写指令函数******************************************/void LCD_write_command(uchar dat){delay_n10us(10);LCD_RS=0; //指令LCD_RW=0; //写入LCD_E=1; //允许LCD_DB=dat;delay_n10us(10); // 用for循环1次就能完成普通写指令。
#i f n d e f__S H T11_H__ #define __SHT11_H__/*************************SHT11相关命令**************************/#define TEM_TEST 0x03//温度检测命令#define HUM_TEST 0x05//湿度检测命令#define REG_READ 0x07//读寄存器#define REG_WRITE 0x06//写寄存器#define FUNCTION_SET 0x01//设置SHT11的工作精度为8位/湿度 12位温度/**************************SHT11端口定义***************************/sbit SHT11_DATA=P2^0;sbit SHT11_SCK=P2^2;uchar flag_tempeture=0; //显示温度位置的标志uchar flag_humidity=0; //显示湿度位置的标志uchar code str1[]={ 0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//温度图标uchar code str6_sht11[]="%RH ";uchar code str4_sht11[]="humi=";uchar code str2_sht11[]="temp=";uchar code str7_sht11[]=" ";//清除没不要的显示/***************************函数名称:Delay()函数功能:SHT11内部延时****************************/void Delay(){ ;;}/***************************函数名称:Delay_Ms()函数功能:SHT11检测等待延时函数说明:11ms/55ms/210ms 分别对应8位/12位/14位测量结果对应的形参为N 则延时Nms****************************/void Delay_Ms(uint ms){uint i,j;for(i=ms;i>0;i--)for(j=112;j>0;j--);}/**************************函数功能:SHT11启动时序***************************/void SHT11_Start(){SHT11_SCK=1;SHT11_DATA=1;Delay();SHT11_DATA=0;Delay();SHT11_SCK=0;Delay();SHT11_SCK=1;Delay();SHT11_DATA=1;}/******************************函数名称:SHT11_Sendbyte(uchar dat) 函数功能: 向SHT11发送8bite数据******************************/ void SHT11_Sendbyte(uchar dat){uchar i;SHT11_SCK=0;Delay();for(i=0;i<8;i++){if(dat&0x80){SHT11_DATA=1;Delay();}else{SHT11_DATA=0;Delay();}dat=dat<<1;SHT11_SCK=1;Delay();SHT11_SCK=0;}}/*********************************函数名称SHT11_Answer():函数功能:检测SHT11的响应信号(在第九个时钟周期) ***********************************/void SHT11_Answer(){SHT11_SCK=1;Delay();while(SHT11_DATA==1);SHT11_SCK=0;SHT11_DATA=1;}/************************************函数名称:SHT11_Test_Finish()函数功能:检测SHT11温湿度检测是否完毕*************************************/void SHT11_Test_Finish(){while(SHT11_DATA==1);}/************************************函数名称:SHT11_Receivebyte()函数功能:从SHT11接收8bite数据*************************************/uchar SHT11_Receivebyte(){ uchar i;uchar dat;SHT11_SCK=0;Delay();for(i=0;i<8;i++){SHT11_SCK=1;Delay();dat=dat<<1;if(SHT11_DATA){dat=dat|0x01;Delay();}else{dat=dat&0xfe;Delay();}SHT11_SCK=0;Delay();}SHT11_DATA=1; //释放数据总线return(dat);}/***********************************函数名称:MCU_Answer()函数功能:单片机向SHT11发送应答信号*************************************/void MCU_Answer(){SHT11_SCK=0;Delay();SHT11_DATA=0;Delay();SHT11_SCK=1;Delay();SHT11_SCK=0;Delay();SHT11_DATA=1; //释放数据总线这条指令非常重要不加的话导致单片机不能读取低8位}/***********************************函数名称:SHT11_End()当接收两个8byte数据后部接收CRC校验码************************************/void SHT11_End(){SHT11_DATA=1;SHT11_SCK=1;Delay();SHT11_SCK=0;Delay();}/*************************************函数名称:void SHT11_Write_Register(uchar command ,uchar dat)函数说明:向SHT11的状态寄存器设置功能command为REG_WRITE 0x06写寄存器dat为设置SHT11的功能可以设置检测的数据位数***************************************/void SHT11_Write_Register(uchar command ,uchar dat){SHT11_Start();SHT11_Sendbyte(command);SHT11_Answer();SHT11_Sendbyte(dat);SHT11_Answer();}/***************************************函数名称:uchar SHT11_Read_Register(uchar command)函数说明:command为REG_READ 0x07//读寄存器返回值为状态寄存器的值位6显示当前检测完一次数据后电源供电情况当位6为0时表明VDD> 当位6为1时表明VDD<即电量不足位0表明当前的测量分辨率当位0为1时表明测量精度:8位/湿度 12位温度当位0为0时表明测量精度:12位湿度 14位温度默认为0*******************************************/uchar SHT11_Read_Register(uchar command){uchar dat;SHT11_Start();SHT11_Sendbyte(command);SHT11_Answer();dat=SHT11_Receivebyte();SHT11_End();return(dat);}/***************************************函数名称:SHT11_Measure(uchar command,uint time);函数功能:设置SHT11检测功能,并返回相应的检测结果函数说明:command形参用于设定温度检测还是湿度检测,time形参用于设定检测过程中的等待时间,以确定检测结果的位数11ms/55ms/210ms 分别对应8位/12位/14位****************************************/uint SHT11_Measure(uchar command,uchar time){uint dat=0;uchar data_high,data_low;SHT11_Start();SHT11_Sendbyte(command);SHT11_Answer();Delay_Ms(time);SHT11_Test_Finish();data_high=SHT11_Receivebyte();MCU_Answer();data_low=SHT11_Receivebyte();SHT11_End();dat=(dat|data_high);dat=(dat<<8)|data_low;return(dat);}/****************************************函数名称:Convert_Tempeture(uint dat);函数功能:将检测到的数据转化为相应的温度数据函数说明:温度转换公式--T=d1+d2*SOt公式中的参数d1=-40,d2=适用于14位测量精度*****************************************/float SHT11_Convert_Tempeture14bit(uint dat){float tempeture1;tempeture1=-40+*dat;if(tempeture1>{flag_tempeture=1;}else if(tempeture1<{flag_tempeture=1;}else{flag_tempeture=0;}return(tempeture1);}/*****************************************函数名称:SHT11_Convert_Humidity(uint dat,float temp)函数功能:将检测到的数据转化为相应的湿度数据函数说明:相对湿度转换公式-----RHline=C1+C2*SOrh+C3*SOrh*SOrh(检测数据的线性化SOrh为单片机接收到的数据)-----RHtrue=(tempeture-25)*(t1+t2*SOrh)+RHline公式中的参数:C1=-4,C2=0,0405,C3=t1=,t2=适用于12位测量精度******************************************/float SHT11_Convert_Humidity12bit(uint dat,float temp) {float RHline,RHtrue;RHline=-4+**dat*dat;RHtrue=(temp-25)*+*dat)+RHline;if(RHtrue<{flag_humidity=1;}else{flag_humidity=0;}return(RHtrue);}/****************************************函数名称:Convert_Tempeture12bit(uint dat);函数功能:将检测到的数据转化为相应的温度数据函数说明:温度转换公式--T=d1+d2*SOt公式中的参数d1=-40,d2=适用于12位测量精度float SHT11_Convert_Tempeture12bit(uint dat){float tempeture1;tempeture1=-40+*dat;if(tempeture1>{flag_tempeture=1;}else{flag_tempeture=0;}return(tempeture1);}*****************************************//*****************************************函数名称:SHT11_Convert_Humidity8bit(uint dat,float temp)函数功能:将检测到的数据转化为相应的湿度数据函数说明:相对湿度转换公式-----RHline=C1+C2*SOrh+C3*SOrh*SOrh(检测数据的线性化SOrh为单片机接收到的数据)-----RHtrue=(tempeture-25)*(t1+t2*SOrh)+RHline 公式中的参数:C1=-4,C2=0,648,C3=t1=,t2=适用于12位测量精度float SHT11_Convert_Humidity8bit(uint dat,float temp){float RHline,RHtrue;RHline=-4+**dat*dat;RHtrue=(temp-25)*+*dat)+RHline;if(RHtrue<{flag_humidity=1;}else{flag_humidity=0;}return(RHtrue);}******************************************/#endif。