基于某Proteus的温湿度采集系统设计.doc
word基于Proteus的温湿度采集系统设计1 设计目的:1. 熟悉Proteus的操作环境,能够使用keil u-vision和Proteus对单片机程序进展联合调试的方法。2. 熟悉单片机的编程,学习根据时序图编写程序的方法,理解模块化编程的思想。3. 掌握1602液晶显示模块程序的编写。2. 设计要求:通过SHT10土壤温湿度传感器对当前的温度和湿度进展采集,并将采集的结果送1602液晶进展实时显示。3. 设计方案:1. 硬件电路设计(1) 单片机最小系统单片机最小系统由晶振电路和上电复位电路组成。图一单片机最小系统21602液晶显示电路本设计采用LCD1602液晶作为显示器件,1602液晶也叫1602字符型液晶 它是一种专门用来显示字母、数字、符号等的点阵型液晶模块 它有假如干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。每位之间有一个点距的间隔 每行之间也有也有间隔 起到了字符间距和行间距的作用,正因为如此 所以他不能显示图形。1602LCD是指显示的容为16X2,即可以显示两行,每行16个字符液晶模块显示字符和数字。目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全一样的,因此基于HD44780写的控制程序可以很方便地应用于市面上大局部的字符型液晶。图二液晶显示电路(3) SHT10温湿度传感器电路SHT10系列单芯片传感器是一款含有已校准数字信号输出的温湿度复合传感器。该传感器包括一个电容式聚合体测湿元件和一个能隙式测温元件组成,并与一个14位的AD转换器和串行接口电路进展无缝连接。采用两线式串行方式与单片机进展通信,但通信协议并不是IIC总线式。2. 软件设计8 / 8(1) 液晶显示局部程序/*端口定义* P1.0-SCK (SHT10) P1.1-DATA (SHT10) P0-DB0DB7 (LCD1602) P2.0-RS (LCD1602) P2.1-RW (LCD1602) P2.2-E (LCD1602)*/#include <reg52.h>#include <intrins.h>#include <stdio.h>#include <string.h>#include <absacc.h>#include <math.h>#define uchar unsigned char#define uint unsigned int/1602液晶端口定义sbit LcdRs= P20;sbit LcdRw= P21;sbit LcdEn= P22;sbit ACC0 = ACC0;sbit ACC7 = ACC7;uchar str7;uchar dis4;/向LCD写入命令或数据#define LCD_MAND0 / mand#define LCD_DATA1 / Data#define LCD_CLEAR_SCREEN0x01 / 清屏#define LCD_HOMING 0x02 / 光标返回原点/设置显示模式*#define LCD_SHOW0x04 /显示开#define LCD_HIDE0x00 /显示关 #define LCD_CURSOR0x02 /显示光标#define LCD_NO_CURSOR0x00 /无光标 #define LCD_FLASH0x01 /光标闪动#define LCD_NO_FLASH 0x00 /光标不闪动/设置输入模式*#define LCD_AC_UP0x02#define LCD_AC_DOWN0x00 / default#define LCD_MOVE0x01 / 画面可平移#define LCD_NO_MOVE0x00 /defaultunsigned char LCD_Wait(void);void LCD_Write(bit style, unsigned char input);/*1602液晶显示局部子程序*/void delay(uint z)uint x,y;for(x=z;x>0;x-)for(y=110;y>0;y-);void LCD_Write(bit style, unsigned char input)LcdRs=style;P0=input; delay(5);LcdEn=1;delay(5);LcdEn=0;void LCD_SetDisplay(unsigned char DisplayMode)LCD_Write(LCD_MAND, 0x08|DisplayMode);void LCD_SetInput(unsigned char InputMode)LCD_Write(LCD_MAND, 0x04|InputMode);/初始化LCD*void LCD_Initial()LcdEn=0;LCD_Write(LCD_MAND,0x38); /8位数据端口,2行显示,5*7点阵LCD_Write(LCD_MAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); /开启显示, 无光标LCD_Write(LCD_MAND,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_MAND,0x80|x);if(y=1)LCD_Write(LCD_MAND,0x80|(x-0x40);/将字符输出到液晶显示void Print(unsigned char *str)while(*str!='0')LCD_Write(LCD_DATA,*str);str+;void zhuanhuan(float a)/浮点数转换成字符串函数 memset(str,0,sizeof(str);sprintf (str,"%f", a); void Dataconv(unsigned char dat)uchar temp;temp=dat/100;dis0=temp+0x30;temp=dat%100;dis1=temp/10+0x30;dis2=temp%10+0x30;void wele()LCD_Initial();GotoXY(0,0);Print(" Wele! ");GotoXY(0,1);Print(" Code of sht10 ");delay(200);/*- ;模块名称:delay_n10us(); ;功 能:延时函数,延时约n个10us较准确的延时函数,"_nop_()"延时1us12M晶振;-*/void delay_n10us(uint n) /延时n个10us12M晶振 uint i; for(i=n;i>0;i-) _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 2. SHT10测量温湿度程序sbit SCK = P23; /定义通讯时钟端口sbit DATA = P24; /定义通讯数据端口typedef union unsigned int i; /定义了两个共用体 float f; value; enum TEMP,HUMI; /TEMP=0,HUMI=1#define noACK 0 /用于判断是否完毕通讯#define ACK 1 /完毕数据传输 /adr mand 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); /启动传输函数void s_connectionreset(void); /连接复位函数char s_write_byte(unsigned char value);/DHT90写函数char s_read_byte(unsigned char ack); /DHT90读函数char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);/测量温湿度函数void calc_dht90(float *p_humidity ,float *p_temperature);/温湿度补偿/*- ;模块名称:s_transstart(); ;功 能:启动传输函数;-*/ void s_transstart(void) / generates a transmission start DATA=1; SCK=0; /Initial state _nop_(); SCK=1; _nop_(); DATA=0; _nop_(); SCK=0; _nop_();_nop_();_nop_(); SCK=1; _nop_(); DATA=1; _nop_(); SCK=0; /*- ;模块名称:s_connectionreset(); ;功 能:连接复位函数;-*/ void s_connectionreset(void) / munication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart / unsigned char i; DATA=1; SCK=0; /Initial state for(i=0;i<9;i+) /9 SCK cycles SCK=1; SCK=0; s_transstart(); /transmission start /*- ;模块名称:s_write_byte(); ;功 能:SHT10写函数;-*/ char s_write_byte(unsigned char value) /- / writes a byte on the Sensibus and checks the acknowledge unsigned char i,error=0; for (i=0x80;i>0;i/=2) /shift bit for masking if (i & value) DATA=1; /masking value with i , write to SENSI-BUS else DATA=0; SCK=1; /clk for SENSI-BUS _nop_();_nop_();_nop_(); /pulswith approx. 3 us SCK=0; DATA=1; /release DATA-line SCK=1; /clk #9 for ack error=DATA; /check ack (DATA will be pulled down by DHT90),DATA在第9个上升沿将被DHT90自动下拉为低电平。 _nop_();_nop_();_nop_(); SCK=0; DATA=1; /release DATA-line return error; /error=1 in case of no acknowledge /返回:0成功,1失败 /*- ;模块名称:s_read_byte(); ;功 能:SHT10读函数;-*/ char s_read_byte(unsigned char ack) / reads a byte form the Sensibus and gives an acknowledge in case of "ack=1" unsigned char i,val=0; DATA=1; /release DATA-line for (i=0x80;i>0;i/=2) /shift bit for masking SCK=1; /clk for SENSI-BUS if (DATA) val=(val | i); /read bit _nop_();_nop_();_nop_(); /pulswith approx. 3 us SCK=0; if(ack=1)DATA=0; /in case of "ack=1" pull down DATA-Line else DATA=1; /如果是校验(ack=0),读取完后完毕通讯 _nop_();_nop_();_nop_(); /pulswith approx. 3 us SCK=1; /clk #9 for ack _nop_();_nop_();_nop_(); /pulswith approx. 3 us SCK=0; _nop_();_nop_();_nop_(); /pulswith approx. 3 us DATA=1; /release DATA-line return val; /*- ;模块名称:s_measure(); ;功 能:测量温湿度函数;-*/ 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 mand to sensor 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; /wait until sensor has finished the measurement if(DATA) 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 return error; /*- ;模块名称:calc_dht90(); ;功 能:温湿度补偿函数;-*/ void calc_dht90(float *p_humidity ,float *p_temperature)/ calculates temperature C and humidity %RH / input : humi Ticks (12 bit) / temp Ticks (14 bit)/ output: humi %RH/ temp C 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 pensated humidity float t_C; / t_C : Temperature C t_C=t*0.01 - 40; /calc. temperature from ticks to C 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 pensated 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 C *p_humidity=rh_true; /return humidity%RH3. 主程序void main(void)value humi_val,temp_val; unsigned char error,checksum; LcdRw=0; s_connectionreset(); wele();/显示欢迎画面 delay(2000);LCD_Initial(); 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_dht90(&humi_val.f,&temp_val.f); /计算湿度与温度GotoXY(0,0);/ Print("Tep:"); GotoXY(0,1); Print("Hum:"); zhuanhuan(temp_val.f);/转换温度为uchar方便液晶显示 Dataconv(unsigned char)temp_val.f);GotoXY(5,0);str5=0xDF;/的符号 str6=0x43;str7='0' Print(str);zhuanhuan(humi_val.f);/转换湿度为uchar方便液晶显示 GotoXY(5,1);str5='%'/%的符号 str6='0'/字符串完毕标志 Print(str); /-wait approx. 0.8s to avoid heating up SHTxx- 4 心得体会通过这次Proteus的学习,我熟悉了Proteus的操作环境,掌握了使用Proteus和keil软件对单片机程序进展联合调试的方法。学会了根据芯片时序图对其进展编程的方法,完成了SHT10温湿度采集和1602液晶显示程序的编写和调试。进一步加深了我对所学知识的理解,同时也对使用Proteus进展设计的新型方式进展了了解。5 参考文献1. 周润景等 。 基于PROTUES的电路与单片机设计与仿真 .航空航天,20062. 董普松。PROTEUS在单片机系统设计中的应用。 现代电子技术 2008年14期3. 映群。PROTEUS与KEIL整合构建单片机虚拟实验室 中国现代教育装备2005