找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1719|回复: 1
收起左侧

单片机智能水温控制系统程序

[复制链接]
ID:527973 发表于 2019-12-15 18:57 | 显示全部楼层 |阅读模式
智能水温控制系统的相关文件

单片机源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. /*LCD1602显示模块*/
  6. #define LCD1602_DATAPINS P0
  7. sbit LCD1602_RS=P2^6;
  8. sbit LCD1602_RW=P2^5;                                                                           
  9. sbit LCD1602_E=P2^7;
  10. /*按键调节模块*/
  11. sbit k1=P1^1;//功能键
  12. sbit k2=P1^2;//加
  13. sbit k3=P1^3;//减
  14. void keyscan();
  15. void key1_switch();
  16. void key2_add();
  17. void key3_minus();
  18. uchar k_num;
  19. void LCD1602_SetTemp(uchar add,uchar dat);
  20. uchar high=90,low=10,set_t=30,set_d=2;//这里的数据类型可能有问题!!
  21. /*其他模块接口*/
  22. sbit DSPORT=P3^7; //温度传感器单总线端
  23. sbit RELAY=P1^4;//继电器
  24. sbit COOLER=P1^7;//降温装置
  25. /*LCD1602相关函数*/
  26. void Delay1us(uint a);
  27. void LCD1602_WriteCom(uchar com);//LCD1602写入8位命令子函数      
  28. void LCD1602_WriteData(uchar dat);               
  29. void LCD1602_Init();//LCD1602初始化子程序                                                  
  30. void LCD1602_ShowTemp(int temp);
  31. /*DS18B20温度传感器相关函数*/
  32. void  Delay15us(uchar aa);
  33. uchar Ds18b20Init();
  34. void  Ds18b20WriteByte(uchar dat);
  35. uchar Ds18b20ReadByte();
  36. void  Ds18b20SwitchTemp();
  37. int   Ds18b20ReadTemp();
  38. float temp_max=125.00,temp_min=-55.00;
  39. uchar ii=0,jj=0,kk=0;
  40. uchar words_h[2]={"H="};
  41. uchar words_l[2]={"L="};
  42. uchar words_s[4]={"Set="};
  43. void Sound();
  44. void Temp_control(int temp);uchar count=0;//用来解决主程序执行太快,按键光标来不及显示的问题
  45. void Temp_control(int temp)
  46. {               
  47. unsigned int kk=400;      
  48. uchar set_h,set_l;      
  49. set_h=set_t+set_d;      
  50. set_l=set_t-set_d;                       
  51. if (temp<=set_h&&temp>=set_l) //设定温度范围之内               
  52. {                        
  53. RELAY = 0; //继电器断开                       
  54. COOLER=0;//风扇关闭               
  55. }               
  56. else               
  57. {                              
  58. TR0=0;                                                      
  59. RELAY = 1; //继电器打开,外电路(常开触电)闭合加热                       
  60. if (temp>=set_h)//温度过高                       
  61. {                              
  62. RELAY = 0; //继电器断开                              
  63. COOLER=1;//打开                       
  64. }                       
  65. TR0=1;                }}
  66. /*其他模块相关函数*/
  67. void Delay1us(uint a)
  68. {      
  69. uint b,c;
  70.         for(c=a;c>0;c--)               
  71. for(b=110;b>0;b--);
  72. }
  73. void LCD1602_WriteCom(uchar com)          //写入命令
  74. {      
  75. LCD1602_E=0;      
  76. LCD1602_RS=0;//0就写指令
  77.         LCD1602_RW=0; //0就是写
  78.         LCD1602_DATAPINS=com;      
  79. Delay1us(10);      
  80. LCD1602_E=1;      
  81. Delay1us(10);      
  82. LCD1602_E=0;}                  
  83. void LCD1602_WriteData(uchar dat)                        //写入数据
  84. {      
  85. LCD1602_E=0;      
  86. LCD1602_RS=1;      
  87. LCD1602_RW=0;      
  88. LCD1602_DATAPINS=dat;      
  89. Delay1us(10);      
  90. LCD1602_E=1;      
  91. Delay1us(10);      
  92. LCD1602_E=0;
  93. }
  94. void LCD1602_Init()                         //LCD初始化子程序
  95. {
  96. //        uint num;        
  97. LCD1602_WriteCom(0x38);  //开显示
  98.         LCD1602_WriteCom(0x0f);  //开显示不显示光标      
  99. LCD1602_WriteCom(0x06);  //写一个指针加1
  100.         LCD1602_WriteCom(0x01);  //清屏      
  101. LCD1602_WriteCom(0x80);  //设置数据指针起点        
  102. LCD1602_WriteCom(0x80+0x0B);      
  103. for (ii=0;ii<2;ii++)      
  104. {                              
  105. LCD1602_WriteData(words_h[ii]);
  106.         }      
  107. LCD1602_SetTemp(13,high);
  108.         LCD1602_WriteCom(0x80+0x40);      
  109. for (kk=0;kk<4;kk++)      
  110. {                              
  111. LCD1602_WriteData(words_s[kk]);      
  112. }      
  113. LCD1602_SetTemp(4+0x40,set_t);      
  114. LCD1602_WriteCom(0x80+0x47);        
  115. LCD1602_WriteData(0x23);  //显示正负号        
  116. LCD1602_WriteCom(0x80+0x48);      
  117. LCD1602_WriteData(0x30+set_d);                              
  118. LCD1602_WriteCom(0x80+0x4B);      
  119. for (jj=0;jj<2;jj++)
  120.         {               
  121. LCD1602_WriteData(words_l[jj]);      
  122. }      
  123. LCD1602_SetTemp(13+0x40,low);               
  124. TMOD=0X01;      
  125. TH0=(65536-50000)/256;      
  126. TL0=(65536-50000)%256;      
  127. EA=1;//总中断      
  128. ET0=1;        TR0=1;
  129. }
  130. void  Delay15us(uchar aa)
  131. {      
  132. do{        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();        _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();        aa--;      
  133. }
  134. while(aa);      
  135. }
  136. /*DS18B20温度传感器相关函数*/
  137. uchar Ds18b20Init()
  138. {      
  139. uchar flag;      
  140. DSPORT=0;          //总线拉低
  141.         Delay15us(40);//延时480~960us      
  142. DSPORT=1;      
  143. Delay15us(2);      
  144. flag=DSPORT;      
  145. Delay15us(6);//Ds18b20发出应答信号,延时60~240us      
  146. Delay15us(25);      
  147. return         flag;
  148. }   
  149. uchar Ds18b20ReadByte()
  150. {      
  151. uchar byte,bi;        
  152. uint i;      
  153. for (i=0;i<8;i++)      
  154. {               
  155. DSPORT=0;               
  156. _nop_();_nop_();_nop_();_nop_(); //保持低电平至少1us,但不能低于15us               
  157. DSPORT=1;               
  158. bi=        DSPORT;//读取一位数据,循环8次为一个字节               
  159. byte = (byte >> 1) | (bi << 7);//将byte左移一位,然后与上右移7位后的bi,8次合成一个字节                Delay15us(4);        
  160. }      
  161. return         byte;
  162. }  
  163. void  Ds18b20WriteByte(uchar dat)
  164. {      
  165. uint i;      
  166. for (i=0;i<8;i++)      
  167. {               
  168. DSPORT=0;
  169. _nop_();               
  170. DSPORT=dat&0x01;//一位一位得读,从最低位开始               
  171. Delay15us(5);               
  172. DSPORT=1;_nop_();               
  173. dat>>=1;         
  174. }}
  175. void  Ds18b20SwitchTemp()
  176. {               
  177. Ds18b20Init();               
  178. Delay15us(7);               
  179. Ds18b20WriteByte(0xcc);//跳过ROM指令               
  180. Ds18b20WriteByte(0x44);//启动温度转换指令
  181. }
  182. int   Ds18b20ReadTemp()
  183. {      
  184. int temp=0;      
  185. uchar temp_h,temp_l;               
  186. Ds18b20SwitchTemp();      
  187. Ds18b20Init();        Delay1us(1);      
  188. Ds18b20WriteByte(0xcc);         //跳过ROM操作命令      
  189. Ds18b20WriteByte(0xbe);         //发送读取温度命令      
  190. temp_l = Ds18b20ReadByte();                //读取温度值共16位,先读低字节
  191.         temp_h = Ds18b20ReadByte();                       
  192. temp= temp_h;      
  193. temp<<=8;      
  194. temp|= temp_l;      
  195. return temp;}  
  196. void LCD1602_ShowTemp(int temp)
  197. {      
  198. float tt;
  199.         uchar show[5]={0,0,0,0,0};      
  200. if (temp<0)//温度为负
  201.         {               
  202. LCD1602_WriteCom(0x80);                //写地址 80表示初始地址            
  203. LCD1602_WriteData('-');                  //显示负               
  204. temp=temp-1;
  205. temp=~temp;tt=temp;      
  206. temp=tt*0.0625*100;                       
  207. }      
  208. else//温度为正      
  209. {               
  210. LCD1602_WriteCom(0x80);                //写地址 80表示初始地址         
  211. LCD1602_WriteData('+');                  //显示正               
  212. tt=temp;                                       
  213. temp=tt*0.0625*100;                       
  214. }               
  215. show[0]=temp/10000;
  216.         show[1]=temp%10000/1000;      
  217. show[2]=temp%1000/100;      
  218. how[3]=temp%100/10;        show[4]=temp%10;        
  219. LCD1602_WriteCom(0x82);      
  220. LCD1602_WriteData('0'+show[0]); //百位  
  221.         LCD1602_WriteCom(0x83);
  222.         LCD1602_WriteData('0'+show[1]); //十位  
  223.         LCD1602_WriteCom(0x84);      
  224. LCD1602_WriteData('0'+show[2]); //个位  
  225.         LCD1602_WriteCom(0x85);      
  226. LCD1602_WriteData('.');        
  227. LCD1602_WriteCom(0x86);      
  228. LCD1602_WriteData('0'+show[3]); //十分位        
  229. LCD1602_WriteCom(0x87);      
  230. LCD1602_WriteData('0'+show[4]); //百分位        
  231. LCD1602_WriteCom(0x88);               
  232. LCD1602_WriteData(0xdf);        
  233. LCD1602_WriteCom(0x89);               
  234. LCD1602_WriteData('C');      
  235. LCD1602_WriteCom(0x0C);        
  236. temp=temp/100;      
  237. Temp_control(temp);      
  238. }
  239. void key1_switch()//功能切换
  240. {      
  241. uchar set_h,set_l;      
  242. set_h=set_t+set_d;
  243. set_l=set_t-set_d;      
  244. //k1键指令      
  245. if(k1==0)               
  246. {               
  247. Delay1us(10);//延时消抖                       
  248. if(k1==0)                       
  249. {                                       
  250. k_num++;                              
  251. while(!k1);        //按键没有松开                                
  252. if(k_num==1)                              
  253. {                                       
  254. TR0=0; //关掉计时器,使得光标得以显示                                       
  255. LCD1602_WriteCom(0x80+0x46);                                       
  256. LCD1602_WriteCom(0x0f);                                               
  257. Delay15us(6);                              
  258. }                              
  259. if(k_num==2)                              
  260. {                                       
  261. LCD1602_WriteCom(0x80+0x48);                                       
  262. LCD1602_WriteCom(0x0f);                                               
  263. Delay15us(6);                              
  264. }                              
  265. if(k_num==3)                              
  266. {                                       
  267. LCD1602_WriteCom(0x80+0x0F);                                       
  268. LCD1602_WriteCom(0x0f);                                               
  269. Delay15us(6);                              
  270. }                              
  271. if(k_num==4)                              
  272. {                                       
  273. LCD1602_WriteCom(0x80+0x4F);                                       
  274. LCD1602_WriteCom(0x0f);                                               
  275. Delay15us(6);                              
  276. }                              
  277. if(k_num==5)                              
  278. {                                       
  279. k_num=0;                                                                              
  280. LCD1602_WriteCom(0x0C);//光标不显示                                                                              
  281. if (high<low)  //用来default                                       
  282. {                                               
  283. high=90;                                               
  284. low=40;//恢复默认值                                       
  285. }                                       
  286. if(set_h>high||set_l<low)                                       
  287. {                                                
  288. high=90;                                               
  289. low=10;//恢复默认值                                                         
  290. set_t=30;                                                
  291. set_d=2;//恢复默认值                                       
  292. }                                       
  293. TR0=1;//计时器重新打开,使得屏幕得以刷新                              
  294. }                       
  295. }        
  296. }}
  297. void key2_add()//功能加
  298. {               
  299. if(k_num!=0)               
  300. {                       
  301. if(k2==0)                       
  302. {                              
  303. Delay1us(5);                              
  304. if(k2==0)                              
  305. {                                       
  306. while(!k2);                                       
  307. if(k_num==1)                                       
  308. {                                               
  309. set_t++;                                               
  310. if (set_t>=high)                                                
  311. set_t=high;                                                
  312. LCD1602_SetTemp(4+0x40,set_t);                                                  LCD1602_WriteCom(0x80+0x46);                                                                                                                        }                                       
  313. if(k_num==2)                                       
  314. {                                               
  315. set_d++;                                               
  316. if (set_d>9)                                                
  317. set_d=0;                                               
  318. LCD1602_WriteCom(0x80+0x48);                                               
  319. LCD1602_WriteData(0x30+set_d);                                               
  320. LCD1602_WriteCom(0x80+0x48);                                                                                                                        }                                       
  321. if(k_num==3)                                       
  322. {                                               
  323. high++;                                               
  324. if (high>=temp_max)                                                
  325. high=0;                                                  
  326. LCD1602_SetTemp(13,high);                                                
  327. LCD1602_WriteCom(0x80+0x0F);//                                                  LCD1602_WriteCom(0x80+0x40+8);                                                                                                                        }                                       
  328. if(k_num==4)                                       
  329. {                                               
  330. low++;                                               
  331. if (low>=temp_max)                                               
  332. low=0;                                                
  333. LCD1602_SetTemp(13+0x40,low);                                                  LCD1602_WriteCom(0x80+0x4F);//                                                  LCD1602_WriteCom(0x80+0x40+13);                                                                                               
  334. }                              
  335. }                       
  336. }               
  337. }}
  338. void key3_minus()//功能减
  339. {               
  340. if(k_num!=0)               
  341. {                       
  342. if(k3==0)                       
  343. {                              
  344. Delay1us(5);                              
  345. if(k3==0)                              
  346. {                                       
  347. while(!k3);                                       
  348. if(k_num==1)                                       
  349. {                                               
  350. if (set_t<=0)                                               
  351. set_t=high+1;                                               
  352. set_t--;                                                  
  353. LCD1602_SetTemp(4+0x40,set_t);                                                  LCD1602_WriteCom(0x80+0x46);                                                                                                                        }                                       
  354. if(k_num==2)                                       
  355. {                                               
  356. if (set_d<=0)                                               
  357. set_d=10;                                               
  358. set_d--;                                                
  359. LCD1602_WriteCom(0x80+0x48);                                               
  360. LCD1602_WriteData(0x30+set_d);                                               
  361. LCD1602_WriteCom(0x80+0x48);                                                                                                                        }                                       
  362. if(k_num==3)                                       
  363. {                                               
  364. if (high<0)                                               
  365. high=temp_max;                                               
  366. high--;                                                  
  367. LCD1602_SetTemp(13,high);                                                
  368. LCD1602_WriteCom(0x80+0x0F);//                                                  LCD1602_WriteCom(0x80+0x40+8);                                                                                                                        }                                       
  369. if(k_num==4)                                       
  370. {                                               
  371. if (low<=0)                                               
  372. low=high;                                               
  373. low--;                                                  
  374. LCD1602_SetTemp(13+0x40,low);                                                  LCD1602_WriteCom(0x80+0x4F);//                                                  LCD1602_WriteCom(0x80+0x40+16);                                                                                                }                                }                       
  375. }               
  376. }
  377.         }
  378. void keyscan()//按键检测
  379. {          key1_switch();         
  380. key2_add();         
  381. key3_minus();}
  382. void LCD1602_SetTemp(uchar add,uchar dat)//数码管制定位置显示
  383. {         
  384. uchar head,body,end;         
  385. head=dat/100;         
  386. body=dat%100/10;         
  387. end=dat%10;         
  388. LCD1602_WriteCom(0x80+add);         
  389. LCD1602_WriteData(0x30+head);         
  390. LCD1602_WriteData(0x30+body);         
  391. LCD1602_WriteData(0x30+end);}
  392. void main(
  393. ){        
  394. LCD1602_Init();      
  395. while(1)      
  396. {         
  397.         keyscan();                                          
  398. }
  399. }
  400. void timer0() interrupt 1
  401. {         
  402. TH0=(65536-50000)/256;      
  403. TL0=(65536-50000)%256;      
  404. count++;               
  405. if (count==10)//让温度每0.5s刷新一次               
  406. {                        count=0;                  
  407.         LCD1602_ShowTemp(Ds18b20ReadTemp());               
  408. }}
复制代码

新建文件夹.zip

157.53 KB, 下载次数: 8, 下载积分: 黑币 -5

回复

使用道具 举报

ID:689290 发表于 2021-5-27 23:31 | 显示全部楼层
这个有原理图吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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