找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机温度监控仿真程序,按键控制上下限设计

[复制链接]
跳转到指定楼层
楼主
基于51单片机的温度监控设计,并通过按键可以调节温度的上下限。
并在Proteus上仿真成功,温度测量通过18b20,显示在1602的显示屏上。
希望给大家带来参考。


单片机源程序如下:
  1. #include <reg51.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define DQ P3&0x07

  6. sbit DQ0=P3^0;

  7. sbit DQ1= P3^1;
  8. //sbit DQ2= P3^2;
  9. sbit key0=P1^0;
  10. sbit key1=P1^1;
  11. sbit key2=P1^2;


  12. sbit BEEP=P3^6;//蜂鸣器器驱动线  
  13. uchar presence;//检测18b20是否插好
  14. sbit LCD_RS=P2^0;
  15. sbit LCD_RW=P2^1;
  16. sbit LCD_E=P2^2;  
  17. uchar code cdis1[]={"WWW.RICHMCU.COM"};
  18. uchar code cdis2[]={"WENDU: _ C"};
  19. uchar code cdis3[]={"DS18B20ERROR"};
  20. uchar code cdis4[]={"PLEASE CHECK"};
  21. unsigned char code mytab[8]={0x0c,0x12,0x12,0x0C,0x00,0x00,0x00,0x00};
  22. void beep();
  23. uint wd0=0,wd1=0,wd2=0;
  24. uchar dat0,dat1,dat2;
  25. uchar min=10;
  26. uchar max=50;
  27. #define delayNOP();{_nop_();_nop_();_nop_();_nop_();};
  28. /**************************************/
  29. void delay1(int ms)
  30. {
  31. unsigned char y ;
  32. while(ms--)
  33. {
  34. for(y = 0 ; y<250 ; y++)
  35. {
  36. _nop_() ;
  37. _nop_() ;
  38. _nop_() ;
  39. _nop_() ;
  40. }
  41. }
  42. }
  43. /******************************************************************/ /*检查LCD忙状态 */
  44. /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
  45. /******************************************************************/
  46. bit lcd_busy()
  47. {
  48. bit result ;
  49. LCD_RS = 0 ;
  50. LCD_RW = 1 ;
  51. LCD_E = 1 ;
  52. delayNOP() ;
  53. result = (bit)(P0&0x80) ;
  54. LCD_E = 0 ;
  55. return(result) ;
  56. }
  57. /*写指令数据到LCD */
  58. /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
  59. /*******************************************************************/

  60. void lcd_wcmd(uchar cmd)
  61. {
  62. while(lcd_busy()) ;
  63. LCD_RS = 0 ;
  64. LCD_RW = 0 ;
  65. LCD_E = 0 ;
  66. _nop_() ;
  67. _nop_() ;
  68. P0 = cmd ;
  69. delayNOP() ;
  70. LCD_E = 1 ;
  71. delayNOP() ;
  72. LCD_E = 0 ;
  73. }
  74. /*******************************************************************/
  75. /*写显示数据到LCD */
  76. /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
  77. /*******************************************************************/
  78. void lcd_wdat(uchar dat)
  79. {
  80. while(lcd_busy()) ;
  81. LCD_RS = 1 ;
  82. LCD_RW = 0 ;
  83. LCD_E = 0 ;
  84. P0 = dat ;
  85. delayNOP() ;
  86. LCD_E = 1 ;
  87. delayNOP() ;
  88. LCD_E = 0 ;
  89. delay1(1);
  90. }
  91. /* LCD初始化设定 */
  92. /*******************************************************************/
  93. void lcd_init()
  94. {

  95. delay1(15) ;
  96. lcd_wcmd(0x01) ; //清除LCD的显示内容
  97. lcd_wcmd(0x38) ; //16*2显示,5*7点阵,8位数据
  98. delay1(5) ;
  99. lcd_wcmd(0x38) ;
  100. delay1(5) ;
  101. lcd_wcmd(0x38) ;
  102. delay1(5) ;

  103. lcd_wcmd(0x0c) ; //显示开,关光标
  104. delay1(5) ;
  105. lcd_wcmd(0x06) ; //移动光标
  106. delay1(5) ;
  107. lcd_wcmd(0x01) ; //清除LCD的显示内容
  108. delay1(5) ;
  109. }
  110. void writetab()
  111. {
  112. unsigned char i ;
  113. lcd_wcmd(0x40) ; //写CGRAM
  114. for (i = 0 ; i< 8 ; i++)
  115. lcd_wdat(mytab[ i ]) ;
  116. }
  117. void dis_string(uchar dir,uchar a[])
  118. {
  119. uchar i=0;
  120. lcd_wcmd(dir);
  121. while(a[i]!='\0')
  122. {
  123. lcd_wdat(a[i]);
  124. i++;
  125. }

  126. }
  127. /*us级延时函数 */
  128. /*******************************************************************/
  129. void Delay(unsigned int num)
  130. {
  131. while( --num ) ;
  132. }

  133. /*初始化ds1820 */

  134. /*******************************************************************/ uchar Init_DS18B20(void)
  135. {
  136. DQ0 = 1 ; //DQ复位
  137. DQ1 = 1 ;
  138. //DQ2 = 1 ;
  139. Delay(10) ; //稍做延时
  140. DQ0 = 0 ; //单片机将DQ拉低
  141. DQ1 = 0 ;
  142. //DQ2 = 0 ;
  143. Delay(100) ; //精确延时 大于 480us
  144. DQ0 = 1 ; //拉高总线
  145. DQ1 = 1 ;
  146. //DQ2 = 1 ;
  147. Delay(8) ;
  148. presence =DQ;
  149. Delay(100) ;
  150. DQ0 = 1 ;
  151. DQ1 = 1 ;
  152. //DQ2 = 1 ;
  153. return(presence) ; //返回信号,表示初始化成功,否则表示初始化失败
  154. }
  155. /* 读一个字节 */
  156. /*******************************************************************/

  157. void ReadOneChar(void)

  158. {
  159. unsigned char i = 0 ;
  160. dat0 = 0 ;
  161. dat1 = 0 ;
  162. dat2 = 0 ;
  163. for (i = 8 ; i > 0 ; i--)
  164. {
  165. DQ0 = 0 ; // 给脉冲信号
  166. DQ1 = 0 ;
  167. //DQ2 = 0 ;
  168. dat0 >>= 1 ;
  169. dat1 >>= 1 ;
  170. dat2 >>= 1 ;
  171. DQ0 = 1 ; // 给脉冲信号
  172. DQ1 = 1 ;

  173. //DQ2 = 1 ;
  174. Delay(1);
  175. if(DQ0)
  176. dat0 |= 0x80 ;
  177. if(DQ1)
  178. dat1 |= 0x80 ;
  179. //if(DQ2)
  180. dat2 |= 0x80 ;
  181. Delay(6) ;
  182. }
  183. }

  184. /* 写一个字节 */

  185. /*******************************************************************/
  186. void WriteOneChar(unsigned char dat)
  187. {
  188. unsigned char i = 0 ;
  189. for (i = 8 ; i > 0 ; i--)
  190. {
  191. DQ0 = 0 ;
  192. DQ1 = 0 ;
  193. //DQ2 = 0 ;
  194. DQ0 = dat&0x01 ;
  195. DQ1 = dat&0x01 ;
  196. //DQ2 = dat&0x01 ;
  197. Delay(6) ;
  198. DQ0 = 1 ;
  199. DQ1 = 1 ;
  200. //DQ2 = 1 ;
  201. dat>>=1 ;
  202. }
  203. }
  204. /* 读取温度 */
  205. /*******************************************************************/
  206. void Read_Temperature(void)
  207. {
  208. Init_DS18B20() ;
  209. WriteOneChar(0xCC) ; // 跳过读序号列号的操作
  210. WriteOneChar(0x44) ; // 启动温度转换
  211. Init_DS18B20() ;
  212. WriteOneChar(0xCC) ; //跳过读序号列号的操作
  213. WriteOneChar(0xBE) ; //读取温度寄存器
  214. ReadOneChar() ; //温度低8位
  215. wd0=dat0;
  216. wd1=dat1;

  217. wd2=dat2;
  218. ReadOneChar() ; //温度高8位
  219. wd0=wd0+256*dat0;
  220. wd1=wd1+256*dat1;
  221. wd2=wd2+256*dat2;
  222. wd0=wd0*0.625;
  223. wd1=wd1*0.625;
  224. wd2=wd2*0.625;
  225. }

  226. void display_tem()
  227. {
  228. BEEP=1;
  229. if(presence&0x01) //presence最低位为1说明0号测温度传感器没有正常工作。
  230. dis_string(0x80,"T0 ERROR");
  231. else
  232. {
  233. dis_string(0x80,"T0:");
  234. lcd_wdat(wd0%1000/100+48) ;
  235. lcd_wdat(wd0%100/10+48) ;
  236. lcd_wdat('.') ;
  237. lcd_wdat(wd0%10+48) ;
  238. writetab() ; //自定义字符写入CGRAM
  239. lcd_wcmd(0x87);
  240. lcd_wdat(0x00) ; //显示自定义字符
  241. if((wd0>max*10)|(wd0<min*10))
  242. BEEP=0;
  243. }
  244. /*if(presence&0x02) //presence中间位为1说明1号测温度传感器没有正常工作。
  245.   dis_string(0x88,"T1 ERROR");
  246. else
  247. {
  248. dis_string(0x88,"T1:");
  249. lcd_wdat(wd1%1000/100+48) ;
  250. lcd_wdat(wd1%100/10+48) ;
  251. lcd_wdat('.') ;
  252. lcd_wdat(wd1%10+48) ;
  253. writetab() ; //自定义字符写入CGRAM
  254. lcd_wcmd(0x8f);
  255. lcd_wdat(0x00) ; //显示自定义字符
  256. if((wd1>max*10)|(wd1<min*10))
  257. BEEP=0;

  258. }

  259. if(presence&0x04) //presence最高位为1说明2号测温度传感器没有正常工作。
  260.    dis_string(0xc0,"T2 ERROR");
  261. else
  262. {
  263. dis_string(0xc0,"T2:");
  264.    lcd_wdat(wd2%1000/100+48) ;
  265.    lcd_wdat(wd2%100/10+48) ;
  266.    lcd_wdat('.') ;
  267.    lcd_wdat(wd2%10+48) ;
  268. writetab() ; //自定义字符写入CGRAM
  269.    lcd_wcmd(0x8f);
  270. lcd_wdat(0x00) ; //显示自定义字符
  271.    if((wd2>max*10)|(wd2<min*10))
  272. BEEP=0;

  273. }*/

  274. }
  275. uchar set_tem(uchar dat)
  276. {
  277. while(1)
  278. {
  279. lcd_wcmd(0xc8);
  280. lcd_wdat(dat/10+48) ;
  281. lcd_wdat(dat%10+48) ;
  282. if(key1==0)
  283. delay1(10);
  284. if(key1==0)
  285. {
  286.      while(key1==0);
  287.      dat++;
  288. }
  289. if(key2==0)
  290. delay1(10);
  291. if(key2==0)
  292. {
  293. while(key2==0);
  294. dat--;
  295. }
  296. if(key0==0)

  297. delay1(5);
  298. if(key0==0)
  299. break;
  300. }
  301. return dat;
  302. }
  303. /* 主函数 */
  304. /************************************/
  305. void main()
  306. {
  307.   uchar flage=0;
  308. lcd_init() ;
  309. while(1)
  310. {
  311. if(key0==0)
  312. {
  313. delay1(5);
  314. if(key0==0)
  315. {
  316. flage++;
  317. if(flage==3)
  318. flage=0;
  319. }
  320. }
  321. Read_Temperature() ;
  322. switch(flage)
  323. {
  324. case 0: display_tem();break;
  325. case 1:
  326.     lcd_init();
  327.     dis_string(0x80,"set min tem");
  328.     dis_string(0xc0,"min tem:");
  329.     min=set_tem(min) ;
  330.     break;
  331. case 2:
  332.     lcd_init();
  333.     dis_string(0x80,"set max tem");
  334.     dis_string(0xc0,"max tem:");
  335.      max=set_tem(max) ;
  336.     break;
  337. default: display_tem();break;
  338.    
  339. }
  340. }
  341.       
  342. }
复制代码

所有资料51hei提供下载:
温度监控.zip (75.3 KB, 下载次数: 49)



评分

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

查看全部评分

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

使用道具 举报

沙发
ID:737311 发表于 2020-4-27 22:52 | 只看该作者
这是楼主自己设计的吗
回复

使用道具 举报

板凳
ID:734666 发表于 2020-5-16 17:35 | 只看该作者
楼主压缩包里是拿什么软件打开?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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