找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于89C52单片机和SHT10传感器在LCD1602上显示温湿度

[复制链接]
跳转到指定楼层
楼主
程序和原理图如下,蜂鸣器一直响,LCD只亮不显示,什么情况?

程序:
  1. /*************定义接口********************
  2. P0------DB0~DB7 (LCD1602)
  3. P2.5------RS (LCD1602)
  4. P2.6------RW (LCD1602)
  5. P2.7------E (LCD1602)
  6. P3.5------SOUNDER (蜂鸣器)
  7. P3.6------SCK (SHT10) //时钟
  8. P3.7------DATA (SHT10) //数据
  9. *****************************************/
  10. #include <AT89x52.h>
  11. #include <intrins.h>
  12. #include <math.h> //Keil library
  13. #include <stdio.h> //Keil library
  14. #define TEMPUP 24 //温度上限, 达到该温度蜂鸣器报警
  15. typedef unsigned char BYTE;
  16. typedef unsigned int WORD;
  17. typedef bit BOOL ;
  18. /*******************************************/
  19. sbit buzzer = P3^5; //蜂鸣器
  20. BOOL start;
  21. /******************************************/

  22. //************第一部分LCD1602设置******
  23. //START*************************************/
  24. #define LCD_DB P0
  25. sbit LCD_RS=P2^5; //P2^5是p2.5
  26. sbit LCD_RW=P2^6; //P2^6是p2.6
  27. sbit LCD_E=P2^7; //P2^7是p2.7
  28. /******定义函数****************/
  29. #define uchar unsigned char
  30. #define uint unsigned int
  31. void LCD_init(void); //初始化函数
  32. void LCD_write_command(uchar command); //写指令函数
  33. void LCD_write_data(uchar dat); //写数据函数
  34. void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
  35. void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602显示字符串函数
  36. void delay_n10us(uint n); //延时函数

  37. /*--------------------------------------
  38. ;初始化LCD1602
  39. ;-------------------------------------*/
  40. void LCD_init(void)
  41. {
  42. delay_n10us(10);
  43. LCD_write_command(0x38);//设置8位格式,2行,5x7
  44. delay_n10us(10);
  45. LCD_write_command(0x0c);//整体显示,关光标,不闪烁
  46. delay_n10us(10);
  47. LCD_write_command(0x06);//设定输入方式,增量不移位
  48. delay_n10us(10);
  49. LCD_write_command(0x01);//清除屏幕显示
  50. delay_n10us(100); //延时清屏,延时函数,延时约n个10us
  51. }

  52. /*--------------------------------------
  53. ;LCD1602写指令函数
  54. ;-------------------------------------*/
  55. void LCD_write_command(uchar dat)
  56. {
  57. delay_n10us(10);
  58. LCD_RS=0; //指令
  59. LCD_RW=0; //写入
  60. LCD_E=1; //允许
  61. LCD_DB=dat;
  62. delay_n10us(10);
  63. LCD_E=0;
  64. delay_n10us(10);
  65. }

  66. /*--------------------------------------
  67. ;LCD1602写数据函数
  68. ;-------------------------------------*/
  69. void LCD_write_data(uchar dat)
  70. {
  71. delay_n10us(10);
  72. LCD_RS=1; //数据
  73. LCD_RW=0; //写入
  74. LCD_E=1; //允许
  75. LCD_DB=dat;
  76. delay_n10us(10);
  77. LCD_E=0;
  78. delay_n10us(10);
  79. }
  80. /*--------------------------------------
  81. ;LCD1602显示一个字符函数,在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
  82. ;-------------------------------------*/
  83. void LCD_disp_char(uchar x,uchar y,uchar dat)
  84. {
  85. uchar address;
  86. if(y==1)
  87. address=0x80+x;
  88. else
  89. address=0xc0+x;
  90. LCD_write_command(address);
  91. LCD_write_data(dat);
  92. }

  93. /*--------------------------------------
  94. ;LCD1602显示字符串函数,在某个屏幕起始位置{X(0-15),y(1-2)}上显示一个字符串
  95. ;-------------------------------------*/
  96. void LCD_disp_str(uchar x,uchar y,uchar *str)
  97. {
  98. uchar address;
  99. if(y==1)
  100. address=0x80+x;
  101. else
  102. address=0xc0+x;
  103. LCD_write_command(address);
  104. while(*str!='\0')
  105. {
  106. LCD_write_data(*str);
  107. str++;
  108. }
  109. }

  110. /*--------------------------------------
  111. ;延时函数,延时约n个10us
  112. ;-------------------------------------*/
  113. void delay_n10us(uint n) //延时n个10us@12M晶振
  114. {
  115. uint i;
  116. for(i=n;i>0;i--)
  117. {
  118. _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  119. }
  120. }
  121. //***************第一部分LCD1602设置*******
  122. //END****************************************
  123. //*************第二部分SHT10设置*************
  124. //START****************************************
  125. sbit SCK = P3^6; //定义通讯时钟端口
  126. sbit DATA = P3^7; //定义通讯数据端口
  127. typedef union         //定义了两个共用体
  128. { unsigned int i;
  129. float f;
  130. }value;

  131. enum {TEMP,HUMI}; //TEMP=0,HUMI=1

  132. #define noACK 0 //用于判断是否结束通讯
  133. #define ACK 1 //结束数据传输
  134.               //adr command r/w
  135. #define STATUS_REG_W 0x06 //000 0011 0
  136. #define STATUS_REG_R 0x07 //000 0011 1
  137. #define MEASURE_TEMP 0x03 //000 0001 1
  138. #define MEASURE_HUMI 0x05 //000 0010 1
  139. #define RESET 0x1e //000 1111 0

  140. /****************定义函数****************/
  141. void s_transstart(void); //启动传输函数
  142. void s_connectionreset(void); //连接复位函数
  143. char s_write_byte(unsigned char value);//SHT10写函数
  144. char s_read_byte(unsigned char ack); //SHT10读函数
  145. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//测量温湿度函数
  146. void calc_SHT10(float *p_humidity ,float *p_temperature);//温湿度补偿

  147. /*--------------------------------------
  148. ;启动传输函数
  149. ;-------------------------------------*/
  150. void s_transstart(void)
  151. {
  152. DATA=1; SCK=0; //Initial state
  153. _nop_();
  154. SCK=1;
  155. _nop_();
  156. DATA=0;
  157. _nop_();
  158. SCK=0;
  159. _nop_();_nop_();_nop_();
  160. SCK=1;
  161. _nop_();
  162. DATA=1;
  163. _nop_();
  164. SCK=0;
  165. }

  166. /*--------------------------------------
  167. ;连接复位函数
  168. ;-------------------------------------*/
  169. void s_connectionreset(void)
  170. {
  171. unsigned char i;
  172. DATA=1; SCK=0;
  173. for(i=0;i<9;i++)
  174. {
  175. SCK=1;
  176. SCK=0;
  177. }
  178. s_transstart();
  179. }

  180. /*--------------------------------------
  181. ;SHT10写函数
  182. ;-------------------------------------*/
  183. char s_write_byte(unsigned char value)
  184. {
  185. unsigned char i,error=0;
  186. for (i=0x80;i>0;i/=2) //shift bit for masking
  187. {
  188. if (i & value) DATA=1; //masking value with i , write to SENSI-BU
  189. else DATA=0;
  190. SCK=1; //clk for SENSI-BUS
  191. _nop_();_nop_();_nop_(); //pulswith approx. 3 us
  192. SCK=0;
  193. }
  194. DATA=1; //release DATA-line
  195. SCK=1; //clk #9 for ack
  196. error=DATA; //check ack (DATA will be pulled down by SHT11),DATA在第9个上升沿将被SHT10自动下拉为低电
  197. _nop_();_nop_();_nop_();
  198. SCK=0;
  199. DATA=1; //release DATA-line
  200. return error; //error=1 in case of no acknowledge //返回:0成功,1失败
  201. }

  202. /*--------------------------------------
  203. ;SHT10读函数
  204. ;-------------------------------------*/
  205. char s_read_byte(unsigned char ack)
  206. {
  207. unsigned char i,val=0;
  208. DATA=1;
  209. for (i=0x80;i>0;i/=2)
  210. { SCK=1;
  211. if (DATA) val=(val | i);
  212. _nop_();_nop_();_nop_();
  213. SCK=0;
  214. }
  215. if(ack==1)DATA=0;
  216. else DATA=1; //如果是校验(ack==0),读取完后结束通讯
  217. _nop_();_nop_();_nop_();
  218. SCK=1;
  219. _nop_();_nop_();_nop_();
  220. SCK=0;
  221. _nop_();_nop_();_nop_();
  222. DATA=1;
  223. return val;
  224. }
  225. /*--------------------------------------
  226. ;测量温湿度函数
  227. ;-------------------------------------*/
  228. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
  229. {
  230. unsigned error=0;
  231. unsigned int i;

  232. s_transstart();
  233. switch(mode)
  234. {
  235. case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
  236. case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
  237. default : break;
  238. }
  239. for (i=0;i<65535;i++)
  240. if(DATA==0) break;
  241. if(DATA) error+=1;
  242. *(p_value) =s_read_byte(ACK);
  243. *(p_value+1)=s_read_byte(ACK);
  244. *p_checksum =s_read_byte(noACK);
  245. return error;
  246. }
  247. /*--------------------------------------
  248. ;温湿度补偿函数
  249. ;-------------------------------------*/
  250. void calc_SHT10(float *p_humidity ,float *p_temperature)
  251. { const float C1=-4.0;
  252. const float C2=+0.0405;
  253. const float C3=-0.0000028;
  254. const float T1=+0.01;
  255. const float T2=+0.00008;
  256. float rh=*p_humidity;
  257. float t=*p_temperature;
  258. float rh_lin;
  259. float rh_true;
  260. float t_C;

  261. t_C=t*0.01 - 40;
  262. rh_lin=C3*rh*rh + C2*rh + C1;
  263. rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;
  264. if(rh_true>100)rh_true=100;
  265. if(rh_true<0.1)rh_true=0.1;
  266. *p_temperature=t_C;
  267. *p_humidity=rh_true;
  268. }
  269. //**********第二部分SHT10设置***************
  270. //END****************************************
  271. //*********主函数*****************
  272. void main(void)
  273. {
  274. value humi_val,temp_val;
  275. unsigned char error,checksum;
  276. unsigned int wendu,shidu;
  277. LCD_init();
  278. s_connectionreset();
  279. LCD_disp_str(0,1,"TE ");
  280. LCD_disp_str(0,2,"RH ");
  281. //*********初始化温度显示区*********
  282. LCD_disp_str(2,1,"TTT.T C");
  283. //*********初始化湿度显示区*********
  284. LCD_disp_str(2,2,"RRR.R%");
  285. delay_n10us(20000); //延时0.2s
  286. while(1)
  287. { error=0;
  288. error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);
  289. error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);
  290. if(error!=0) s_connectionreset();
  291. else
  292. { humi_val.f=(float)humi_val.i;
  293. temp_val.f=(float)temp_val.i;
  294. calc_SHT10(&humi_val.f,&temp_val.f);
  295. wendu=10*temp_val.f;
  296. LCD_disp_char(2,1,wendu/1000+'0'); //显示温度百位
  297. LCD_disp_char(3,1,(wendu%1000)/100+'0'); //显示温度十位
  298. LCD_disp_char(4,1,(wendu%100)/10+'0'); //显示温度个位
  299. LCD_disp_char(6,1,(wendu%10)+'0'); //显示温度小数点后第一位
  300. shidu=10*humi_val.f;
  301. LCD_disp_char(2,2,shidu/1000+'0'); //显示湿度百位
  302. LCD_disp_char(3,2,(shidu%1000)/100+'0'); //显示湿度十位
  303. LCD_disp_char(4,2,(shidu%100)/10+'0'); //显示湿度个位
  304. LCD_disp_char(6,2,(shidu%10)+'0'); //显示湿度小数点后第一位
  305. }
  306. delay_n10us(80000); //延时约0.8s }
  307. }
  308. }
复制代码

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

使用道具 举报

沙发
ID:259178 发表于 2017-12-9 13:05 | 只看该作者
我怀疑这程序有问题,我用protues把你这个程序和图都做出来,结果是:可以显示温度和湿度,可以调节,但蜂鸣器一直在响(无论我把温度湿度改为多少),你这程序是哪里来的?还是找其他程序吧,或者你看懂的话可以改程序
回复

使用道具 举报

板凳
ID:259414 发表于 2017-12-9 14:58 | 只看该作者
在主函数里没有循环或中断,程序只执行一次,你多执行几次看看现象
回复

使用道具 举报

地板
ID:259741 发表于 2017-12-10 13:31 | 只看该作者
这是什么问题
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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