找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 101|回复: 2
打印 上一主题 下一主题
收起左侧

单片机LCD1602温湿显示

[复制链接]
跳转到指定楼层
楼主
LCD1602温湿显示,全部在附件里。
我家原先有个温湿度显示器,用了几年坏了;我想自己做一个,在网上套淘了STH10传感器,用STC15F2K60S2单片机组成最小系统,用C语言编程调试完成。显示温湿度效果还可以见图片。
编者:ROCKER(石头)



单片机源程序如下:
  1. /****************************************************************  
  2. ;功能说明:sht11和1602的温湿度显示  
  3. ;微处理器:STC15f2k60s2
  4. ;编译环境:Keil uVision V4.0
  5. ;创建日期:2025-9-24
  6. ;版    本:V1.0   
  7. ;修改日期:2026.5.25  OK
  8. **********************************************************/

  9. /*************定义接口********************
  10.          P0.x------DB0~DB7(LCD1602)      
  11.          P2.6------RS      (LCD1602)
  12.          P2.5------RW      (LCD1602)
  13.          P2.4------E       (LCD1602)
  14.          P2.1------DATA    (SHT1x/7x)
  15.          P2.2------SCK     (SHT1x/7x)
  16. *****************************************/
  17. #include  "stc15f.h"
  18. #include <intrins.h>  
  19. #include <math.h>      
  20. #include <stdio.h>   

  21. //***************第一部分LCD1602设置 START**********************
  22. #define LCD_DB       P0
  23.         sbit         LCD_RS=P2^6;   
  24.         sbit         LCD_RW=P2^5;
  25.                     sbit         LCD_E=P2^4;   
  26. /******定义函数****************/
  27. #define uchar unsigned char
  28. #define uint unsigned int
  29. bit lcd_busy();
  30. void LCD_init(void);                          //初始化函数
  31. void LCD_write_command(uchar command);        //写指令函数
  32. void LCD_write_data(uchar dat);               
  33. void LCD_disp_char(uchar x,uchar y,uchar dat);
  34. void LCD_disp_str(uchar x,uchar y,uchar *str);
  35. void delay_n10us(uint n);                     

  36. bit lcd_busy()
  37. {        
  38.         bit result;
  39.         LCD_RS= 0;
  40.         LCD_RW=1;
  41.     LCD_E=1;
  42.         _nop_();
  43.         _nop_();
  44.         _nop_();
  45.         _nop_();
  46.         result = (bit)(P0 & 0x80);
  47.     LCD_E=0;
  48.         return result;
  49. }


  50. /*--------------------------------------  
  51. ;模块名称:LCD_init();  
  52. ;功    能:初始化LCD1602  
  53. ;-------------------------------------*/  
  54. void LCD_init(void)
  55. {
  56. delay_n10us(10);
  57. LCD_write_command(0x38);
  58. delay_n10us(10);
  59. LCD_write_command(0x0c);//整体显示,关光标,不闪烁
  60. delay_n10us(10);
  61. LCD_write_command(0x06);//设定输入方式,增量不移位
  62. delay_n10us(10);
  63. LCD_write_command(0x01);
  64. delay_n10us(100);      
  65. }


  66. /*--------------------------------------  
  67. ;模块名称:LCD_write_command();  
  68. ;功    能:LCD1602写指令函数   
  69. ;参数说明:dat为写命令参数
  70. ;-------------------------------------*/  
  71. void LCD_write_command(uchar dat)
  72. {
  73. while(lcd_busy());
  74. delay_n10us(10);
  75. LCD_RS=0;         //指令
  76. LCD_RW=0;         //写入
  77. LCD_E=1;          //允许
  78. LCD_DB=dat;
  79. delay_n10us(10);   
  80. LCD_E=0;
  81. delay_n10us(10);   
  82. }


  83. /*--------------------------------------  
  84. ;模块名称:LCD_write_data();  
  85. ;功    能:LCD1602写数据函数   
  86. ;参数说明:dat为写数据参数
  87. ;-------------------------------------*/
  88. void LCD_write_data(uchar dat)
  89. {
  90. while(lcd_busy());
  91. delay_n10us(10);
  92. LCD_RS=1;          //数据
  93. LCD_RW=0;          //写入
  94. LCD_E=1;           //允许
  95. LCD_DB=dat;
  96. delay_n10us(10);
  97. LCD_E=0;
  98. delay_n10us(10);
  99. }


  100. /*--------------------------------------  
  101. ;模块名称:LCD_disp_char();  
  102. ;功    能:LCD1602显示一个字符函数,在某个屏幕位置上显示一个字符,X(0-15),y(1-2)。  
  103. ;-------------------------------------*/
  104. void LCD_disp_char(uchar x,uchar y,uchar dat)
  105. {
  106.   uchar address;
  107.   if(y==1)
  108.          address=0x80+x;
  109.   else
  110.          address=0xc0+x;
  111.   LCD_write_command(address);
  112.   LCD_write_data(dat);
  113. }
  114. /*--------------------------------------  
  115. ;模块名称:LCD_disp_str();  
  116. ;功    能:LCD1602显示字符串函数,在某个屏幕起始位置{X(0-15),y(1-2)}上显示一个字符串。  
  117. ;-------------------------------------*/
  118. void LCD_disp_str(uchar x,uchar y,uchar *str)
  119. {
  120.   uchar address;
  121.   if(y==1)
  122.          address=0x80+x;
  123.   else
  124.          address=0xc0+x;
  125.   LCD_write_command(address);
  126.   while(*str!='\0')
  127.   {  
  128.     LCD_write_data(*str);   
  129.     str++;
  130.   }
  131. }


  132. /*--------------------------------------  
  133. ;模块名称:delay_n10us();  
  134. ;功    能:延时函数,延时约n个10us
  135. ;修改说明:修改为较精确的延时函数,"_nop_()"延时1us@12M晶振
  136. ;-------------------------------------*/
  137. void delay_n10us(uint n)  
  138. {        
  139.         uint i;            
  140.         for(i=n;i>0;i--)     
  141.         {
  142.          _nop_();_nop_();_nop_();
  143.                                  _nop_();_nop_();_nop_();  
  144.         }
  145. }                                    

  146. //*********************第二部分sht10设置   START****************************************  
  147. sbit SCK  = P2^2;      
  148. sbit DATA = P2^1;      

  149. typedef union   
  150. { unsigned int i;      
  151.   float f;  
  152. }
  153. value;  

  154. enum {TEMP,HUMI};      
  155.   

  156. #define noACK 0             //用于判断是否结束通讯
  157. #define ACK   1             //结束数据传输
  158.                             //adr  command  r/w  
  159. #define STATUS_REG_W 0x06   //000   0011    0  
  160. #define STATUS_REG_R 0x07   //000   0011    1  
  161. #define MEASURE_TEMP 0x03   //000   0001    1  
  162. #define MEASURE_HUMI 0x05   //000   0010    1  
  163. #define RESET        0x1e   //000   1111    0  

  164. /****************定义函数****************/
  165. void s_transstart(void);               
  166. void s_connectionreset(void);         
  167. char s_write_byte(unsigned char value);
  168. char s_read_byte(unsigned char ack);   
  169. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//测量温湿度函数
  170. void calc_dht90(float *p_humidity ,float *p_temperature);//温湿度补偿

  171. /*--------------------------------------  
  172. ;模块名称:s_transstart();  
  173. ;功    能:启动传输函数
  174. ;-------------------------------------*/   
  175. void s_transstart(void)  
  176. // generates a transmission start   
  177. {   
  178.    DATA=1; SCK=0;                    
  179.    _nop_();  
  180.    SCK=1;  
  181.    _nop_();  
  182.    DATA=0;  
  183.    _nop_();  
  184.    SCK=0;   
  185.    _nop_();_nop_();_nop_();  
  186.    SCK=1;  
  187.    _nop_();  
  188.    DATA=1;         
  189.    _nop_();  
  190.    SCK=0;         
  191. }  

  192. /*--------------------------------------  
  193. ;模块名称:s_connectionreset();  
  194. ;功    能:连接复位函数
  195. ;-------------------------------------*/  
  196. void s_connectionreset(void)  

  197. {   
  198.   unsigned char i;   
  199.   DATA=1; SCK=0;                     
  200.   for(i=0;i<9;i++)                  
  201.   {  
  202.     SCK=1;
  203.     SCK=0;  
  204.   }  
  205.   s_transstart();                    
  206. }  


  207. /*--------------------------------------  
  208. ;模块名称:s_write_byte();  
  209. ;功    能:SHT1x/7x写函数
  210. ;-------------------------------------*/  
  211. char s_write_byte(unsigned char value)  
  212. //----------------------------------------------------------------------------------  
  213.   
  214. {   
  215.   unsigned char i,error=0;   
  216.   for (i=0x80;i>0;i/=2)               
  217.   {   
  218.     if (i & value) DATA=1;           
  219.     else DATA=0;                          
  220.     SCK=1;                           
  221.     _nop_();_nop_();_nop_();            
  222.     SCK=0;  
  223.   }  
  224.   DATA=1;                           
  225.   SCK=1;                             
  226.   error=DATA;                        
  227.   _nop_();_nop_();_nop_();
  228.   SCK=0;
  229.   DATA=1;                             
  230.   return error;                     
  231. }  
  232.   

  233. /*--------------------------------------  
  234. ;模块名称:s_read_byte();  
  235. ;功    能:SHT1x/7x读函数

  236. ;-------------------------------------*/  
  237. char s_read_byte(unsigned char ack)   
  238.   
  239. {   
  240.   unsigned char i,val=0;  
  241.   DATA=1;                           
  242.   for (i=0x80;i>0;i/=2)               
  243.   { SCK=1;                           
  244.     if (DATA) val=(val | i);           
  245.         _nop_();_nop_();_nop_();        
  246.     SCK=0;               
  247.   }  
  248.   if(ack==1)DATA=0;                  
  249.   else DATA=1;                     
  250.   _nop_();_nop_();_nop_();           
  251.   SCK=1;                             
  252.   _nop_();_nop_();_nop_();            
  253.   SCK=0;                  
  254.   _nop_();_nop_();_nop_();            
  255.   DATA=1;                           
  256.   return val;  
  257. }  
  258.   
  259. /*--------------------------------------  
  260. ;模块名称:s_measure();  
  261. ;功    能:测量温湿度函数
  262. ;-------------------------------------*/  
  263. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)  
  264.   
  265. {   
  266.   unsigned error=0;  
  267.   unsigned int i;  
  268.   
  269.   s_transstart();                    
  270.   switch(mode)
  271.         {                     
  272.     case TEMP  : error+=s_write_byte(MEASURE_TEMP); break;  
  273.     case HUMI  : error+=s_write_byte(MEASURE_HUMI); break;  
  274.     default     : break;     
  275.   }  
  276.   for (i=0;i<65535;i++) if(DATA==0) break;  
  277.   if(DATA) error+=1;                 
  278.   *(p_value)  =s_read_byte(ACK);      
  279.   *(p_value+1)=s_read_byte(ACK);     
  280.   *p_checksum =s_read_byte(noACK);  
  281.   return error;  
  282. }  
  283.   

  284. /*--------------------------------------  
  285. ;模块名称:calc_dht90();  
  286. ;功    能:温湿度补偿函数   
  287. ;-------------------------------------*/  
  288. void calc_dht90(float *p_humidity ,float *p_temperature)

  289. { const float C1=-4.0;              
  290.   const float C2=+0.0405;           
  291.   const float C3=-0.0000028;        
  292.   const float T1=+0.01;            
  293.   const float T2=+0.00008;           

  294.   float rh=*p_humidity;             // rh:      Humidity [Ticks] 12 Bit  
  295.   float t=*p_temperature;           // t:       Temperature [Ticks] 14 Bit
  296.   float rh_lin;                     // rh_lin:  Humidity linear
  297.   float rh_true;                    // rh_true: Temperature compensated humidity
  298.   float t_C;                        // t_C   :  Temperature [C]

  299.   t_C=t*0.01 - 40;                  //calc. temperature from ticks to [C]
  300.   rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]
  301.   rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH]
  302.   if(rh_true>100)rh_true=100;      
  303.   if(rh_true<0.1)rh_true=0.1;        

  304.   *p_temperature=t_C;               
  305.   *p_humidity=rh_true;              
  306. }

  307. //*********************第二部分SHT1x/7x设置   END****************************************

  308. //*********主函数*****************
  309. void main(void)
  310. {
  311.         value humi_val,temp_val;
  312.         unsigned char error,checksum;  
  313.         unsigned int wendu,shidu;
  314.         LCD_init();         
  315.         s_connectionreset();  
  316.               LCD_disp_str(0,1,"TE ");
  317.               LCD_disp_str(0,2,"RH ");


  318. //*********初始化温度显示区*********
  319.         LCD_disp_str(2,1, "TTT.T \xDF\C");

  320. //*********初始化湿度显示区*********
  321.         LCD_disp_str(2,2, "RRR.R%RH");

  322.         delay_n10us(20000);     //延时0.2s

  323.         while(1)  
  324.         { error=0;  
  325.           error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);   
  326.           error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);  
  327.           if(error!=0) s_connectionreset();                 
  328.           else  
  329.           { humi_val.f=(float)humi_val.i;                    
  330.             temp_val.f=(float)temp_val.i;                  
  331.             calc_dht90(&humi_val.f,&temp_val.f);            
  332.             wendu=10*temp_val.f;
  333.             LCD_disp_char(2,1,wendu/1000+'0');              //显示温度百位
  334.             LCD_disp_char(3,1,(wendu%1000)/100+'0');        //显示温度十位
  335.             LCD_disp_char(4,1,(wendu%100)/10+'0');          //显示温度个位
  336.             LCD_disp_char(6,1,(wendu%10)+'0');              //显示温度小数点后第一位

  337.             shidu=10*humi_val.f;
  338.             LCD_disp_char(2,2,shidu/1000+'0');               //显示湿度百位
  339.             LCD_disp_char(3,2,(shidu%1000)/100+'0');         //显示湿度十位
  340.             LCD_disp_char(4,2,(shidu%100)/10+'0');           //显示湿度个位
  341.             LCD_disp_char(6,2,(shidu%10)+'0');               //显示湿度小数点后第一位
  342.           }  
  343.           //----------wait approx. 0.8s to avoid heating up SHTxx------------------------------        
  344.                   delay_n10us(80000);                                //延时约0.8s
  345.         }
  346. }
  347. //end   2026-5-25    OK
复制代码


程序 原理图: LCD1602温度湿度显示.7z (49.4 KB, 下载次数: 0)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1167385 发表于 2026-6-12 12:34 | 只看该作者
谢谢!
回复

使用道具 举报

板凳
ID:1167385 发表于 2026-6-12 12:34 | 只看该作者
谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表