實現功能
1、溫濕度實時檢測
2、20個點位RS485傳輸
3、上位機顯示20個點位數據
4、上位機對每個點位數據同步保存
器件介紹
1、溫濕度傳感器 SHT11
實物1.jpg (16.75 KB, 下載次數: 64)
下載附件
2019-9-30 21:51 上傳
實物2.jpg (14.4 KB, 下載次數: 65)
下載附件
2019-9-30 21:51 上傳
實物3.jpg (21.9 KB, 下載次數: 60)
下載附件
2019-9-30 21:51 上傳
SHT11.png (30.14 KB, 下載次數: 79)
下載附件
2019-9-30 21:51 上傳
2、RS485芯片
實物1.jpg (8.05 KB, 下載次數: 71)
下載附件
2019-9-30 22:06 上傳
實物2.jpg (6.53 KB, 下載次數: 75)
下載附件
2019-9-30 22:06 上傳
功能表.jpg (42.14 KB, 下載次數: 67)
下載附件
2019-9-30 22:08 上傳
制作完成的實物
001.png (154.94 KB, 下載次數: 67)
下載附件
2019-9-30 22:43 上傳
002.png (254.25 KB, 下載次數: 73)
下載附件
2019-9-30 22:43 上傳
003.png (82.89 KB, 下載次數: 60)
下載附件
2019-9-30 22:43 上傳
上位機讀取數據界面
上位機.png (52.04 KB, 下載次數: 80)
下載附件
2019-9-30 22:46 上傳
溫濕度資料下載
溫濕度傳感器SHT11數據手冊.pdf
(1.44 MB, 下載次數: 42)
2019-9-30 22:46 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
485通訊芯片資料下載
DS75176.pdf
(941.27 KB, 下載次數: 52)
2019-9-30 22:48 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
SHT11液晶顯示源程序
SHT11液晶顯示源程序.rar
(3.23 KB, 下載次數: 73)
2019-9-30 22:57 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
- /***********************************************************************************
- ;功能說明:SHT11與LCD1602的溫濕度顯示
- ;文件名稱:SHT11.c
- ;***********************************************************************************/
- /*************定義接口********************
- P0------DB0~DB7 (LCD1602)
- P2.0------RS (LCD1602)
- P2.1------RW (LCD1602)
- P2.2------E (LCD1602)
- P2.6------SCK (SHT11)
- P2.7------DATA (SHT11)
- *****************************************/
- #include <reg52.h>
- #include <intrins.h>
- #include <math.h>
- #include <stdio.h>
- //第一部分LCD1602設置
- #define LCD_DB P0
- sbit LCD_RS=P2^0;
- sbit LCD_RW=P2^1;
- sbit LCD_E=P2^2;
- /******定義函數****************/
- #define uchar unsigned char
- #define uint unsigned int
- void 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行,5x7
- delay_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); //實踐證明,我的LCD1602上,用for循環1次就能完成普通寫指令。
- LCD_E=0;
- delay_n10us(10); //實踐證明,我的LCD1602上,用for循環1次就能完成普通寫指令。
- }
- /*--------------------------------------
- ;模塊名稱:LCD_write_data();
- ;功 能:LCD1602寫數據函數
- ;-------------------------------------*/
- void LCD_write_data(uchar dat)
- {
- delay_n10us(10);
- LCD_RS=1; //數據
- LCD_RW=0; //寫入
- LCD_E=1; //允許
- LCD_DB=dat;
- delay_n10us(10);
- LCD_E=0;
- delay_n10us(10);
- }
- /*--------------------------------------
- ;模塊名稱:LCD_disp_char();
- ;功 能:LCD1602顯示一個字符函數
- ;-------------------------------------*/
- void LCD_disp_char(uchar x,uchar y,uchar dat)
- {
- uchar address;
- if(y==1)
- address=0x80+x;
- else
- address=0xc0+x;
- LCD_write_command(address);
- LCD_write_data(dat);
- }
- /*--------------------------------------
- ;模塊名稱:LCD_disp_str();
- ;功 能:LCD1602顯示字符串
- ;-------------------------------------*/
- void LCD_disp_str(uchar x,uchar y,uchar *str)
- {
- uchar address;
- if(y==1)
- address=0x80+x;
- else
- address=0xc0+x;
- LCD_write_command(address);
- while(*str!='\0')
- {
- LCD_write_data(*str);
- str++;
- }
- }
- /*--------------------------------------
- ;模塊名稱:delay_n10us();
- ;功 能:延時函數,延時約n個10us
- ;-------------------------------------*/
- void delay_n10us(uint n) //延時n個10us@12M晶振
- {
- uint i;
- for(i=n;i>0;i--)
- {
- _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- }
- }
- //第二部分SHT11設置
- sbit SCK = P2^6; //定義通訊時鐘端口
- sbit DATA = P2^7; //定義通訊數據端口
- typedef union
- { unsigned int i; //定義了兩個共用體
- float f;
- } value;
- enum {TEMP,HUMI}; //TEMP=0,HUMI=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
- /****************定義函數****************/
- void s_transstart(void); //啟動傳輸函數
- void s_connectionreset(void); //連接復位函數
- char s_write_byte(unsigned char value);//SHT11寫函數
- char s_read_byte(unsigned char ack); //SHT11讀函數
- char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//測量溫濕度函數
- void calc_SHT11(float *p_humidity ,float *p_temperature);//溫濕度補償
- /*--------------------------------------
- ;模塊名稱:s_transstart();
- ;功 能:啟動傳輸函數
- ;-------------------------------------*/
- void s_transstart(void)
- {
- 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)
- {
- 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();
- ;功 能:SHT11寫函數
- ;-------------------------------------*/
- char s_write_byte(unsigned char value)
- //----------------------------------------------------------------------------------
- {
- 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 SHT11),DATA在第9個上升沿將被SHT11自動下拉為低電平。
- _nop_();_nop_();_nop_();
- SCK=0;
- DATA=1; //release DATA-line
- return error; //error=1 in case of no acknowledge //返回:0成功,1失敗
- }
- /*--------------------------------------
- ;模塊名稱:s_read_byte();
- ;功 能:DHT11讀函數
- ;-------------------------------------*/
- 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 command 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_SHT11();
- ;功 能:溫濕度補償函數
- ;-------------------------------------*/
- void calc_SHT11(float *p_humidity ,float *p_temperature)
- { 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 [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-3; //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 [C]
- *p_humidity=rh_true; //return humidity[%RH]
- }
- //*********主函數*****************
- void main(void)
- {
- value humi_val,temp_val;
- unsigned char error,checksum;
- unsigned int wendu,shidu;
- LCD_init();
- s_connectionreset();
- LCD_disp_str(0,1,"TE");
- LCD_disp_str(0,2,"RH");
- LCD_disp_str(2,1,"T");
- LCD_disp_str(2,2,"R");
- 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_SHT11(&humi_val.f,&temp_val.f); //calculate humidity, temperature
- wendu=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=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'); //顯示濕度小數點后第一位
- }
- }
- }
復制代碼
|