找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 5055|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

基于RS-485總線的單片機(jī)溫控系統(tǒng)程序Proteus仿真設(shè)計(jì)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:860602 發(fā)表于 2020-12-18 23:10 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
1. 采用DS18B20數(shù)字溫度傳感器對(duì)兩處進(jìn)行溫度的實(shí)時(shí)測(cè)量,通過LCD1602進(jìn)行顯示,并通過RS-485總線上傳到主機(jī)。
2. 當(dāng)溫度超過設(shè)定值時(shí)能夠報(bào)警,同時(shí)啟動(dòng)相關(guān)降溫設(shè)備。
3. 主機(jī)通過按鍵和無線遙控能夠?qū)囟葓?bào)警上限值及時(shí)間進(jìn)行設(shè)置。
4. 能夠?qū)χ匾獢?shù)據(jù)進(jìn)行保存。                             
二、設(shè)計(jì)方案
主機(jī)和從機(jī)選用STC89C52單片機(jī),通過RS-485總線進(jìn)行數(shù)據(jù)通信。主機(jī)采用LCD2002顯示各從機(jī)的溫度和當(dāng)前時(shí)間,根據(jù)按鍵或無線遙控的輸入命令對(duì)控制溫度上限值、溫度報(bào)警值和時(shí)間進(jìn)行設(shè)置,并通過RS-485總線傳遞溫度報(bào)警值給從機(jī)和讀取從機(jī)溫度。從機(jī)通過DS18B20采集現(xiàn)場(chǎng)溫度,利用LCD1602進(jìn)行顯示,通過RS-485總線接收溫度報(bào)警值,同時(shí)上傳溫度檢測(cè)值給主機(jī)。
整個(gè)系統(tǒng)主要分3大塊(主機(jī)、從機(jī)1和從機(jī)2)和十二個(gè)模塊。(1)主機(jī)鍵盤部分,用來實(shí)現(xiàn)輸入和設(shè)定溫度等工作;(2)主機(jī)LCD1602顯示電路;(3)主機(jī)單片機(jī)最小系統(tǒng);(4)主機(jī)時(shí)鐘電路;(5)主機(jī)存儲(chǔ)電路;(6)主機(jī)繼電器輸出控制電路;(7)主機(jī)蜂鳴器報(bào)警電路;(8)主機(jī)RS-485通信部分;(9)從機(jī)RS-485通信部分;(10)從機(jī)單片機(jī)最小系統(tǒng);(11)從機(jī)LCD1602顯示部分;(12)從機(jī)溫度檢測(cè)電路。從機(jī)1和從機(jī)2硬件電路一樣,都包括第9模塊到第12模塊。整個(gè)系統(tǒng)方案如圖10-1所示。

圖10-1 系統(tǒng)方案框圖

三、硬件設(shè)計(jì)
系統(tǒng)原理圖如圖10-2和圖10-3所示,對(duì)應(yīng)仿真圖如圖10-4所示。
圖10-2 主機(jī)電路原理圖
圖10-3 從機(jī)電路原理圖
圖10-4 整個(gè)系統(tǒng)仿真圖
從圖10-4仿真圖可以看出從機(jī)1當(dāng)前的溫度值為42.0℃,從機(jī)2當(dāng)前的溫度為34.0℃,溫度報(bào)警上限溫度值為39.0℃,主機(jī)與從機(jī)顯示溫度一致,說明Proteus仿真是完全正確的。
1.主機(jī)鍵盤。調(diào)整按鍵8個(gè),其中S2、S3、S4和S5是手動(dòng)按鍵,分別為設(shè)置鍵、加鍵、減鍵、退出鍵。通過調(diào)整按鍵可以對(duì)溫度上限值、時(shí)間、星期、年月日的調(diào)整狀態(tài)。
2.主機(jī)LCD顯示電路。主機(jī)通過LCD1602液晶顯示從機(jī)1和從機(jī)2實(shí)時(shí)采集的溫度值、時(shí)間和日期。
3. 主機(jī)單片機(jī)最小系統(tǒng)。主機(jī)單片機(jī)最小系統(tǒng)是電路的控制中心,主要包括單片機(jī)、時(shí)鐘電路和復(fù)位電路。
4.主機(jī)時(shí)鐘電路。
采用DS1302實(shí)時(shí)時(shí)鐘芯片進(jìn)行年、月、日、時(shí)、分、秒刷新。可以通過按鍵調(diào)整時(shí)間,并具有系統(tǒng)掉電后啟用備用電池向DS1302繼續(xù)供電的功能,使用戶不必每次上電調(diào)整時(shí)間。
5.主機(jī)存儲(chǔ)電路。AT24C02用于存儲(chǔ)用戶設(shè)定的溫度上限值和其他重要數(shù)據(jù)。
6.主機(jī)繼電器輸出控制電路。當(dāng)溫度大于等于用戶設(shè)定的上限值時(shí),P20和P21輸出低電平,通過三極管VT1和VT2驅(qū)動(dòng)繼電器吸合,控制電扇通風(fēng)降溫,同時(shí)繼電器接通指示燈亮。
7.主機(jī)蜂鳴器報(bào)警電路。當(dāng)溫度大于等于用戶設(shè)定的上限值時(shí),主機(jī)蜂鳴器報(bào)警。

8.主機(jī)RS-485通信部分。RS-485通信芯片選用的是SN65HVD3082ED,收發(fā)使能端由主機(jī)P3.7進(jìn)行控制,R2用于防止末端信號(hào)發(fā)射,J5和J6為通信接口。
9.從機(jī)RS-485通信部分。RS-485通信芯片選用的是SN65HVD3082ED,收發(fā)使能端由主機(jī)P3.7進(jìn)行控制,R2用于防止末端信號(hào)發(fā)射,J2和J3為通信接口。
10. 從機(jī)單片機(jī)最小系統(tǒng)。主要包括單片機(jī)、時(shí)鐘電路、復(fù)位電路、電源接口和LED指示、ISP下載。
11.從機(jī)LCD1602顯示部分。第一行顯示主機(jī)發(fā)來的溫度上限值,第二行顯示從機(jī)1所在位置的溫度值和下限值。
12. 從機(jī)溫度檢測(cè)電路。通過DS18B20進(jìn)行溫度采集,數(shù)據(jù)端口DQ連接到單片機(jī)的P3.3。
四、軟件設(shè)計(jì)
1. RS-485總線通信協(xié)議
主機(jī)STC89C52采用查詢方式,從機(jī)STC89C52采用中斷方式,具體協(xié)議如下:
(1)主機(jī)STC89C52發(fā)送查詢地址。
(2)從機(jī)STC89C52都接收查詢地址,并與本從機(jī)地址比較,若一樣則發(fā)送從機(jī)地址、采集溫度十位、采集溫度個(gè)位、采集溫度小數(shù)位和累加和校驗(yàn)。
(3)主機(jī)STC89C52接收數(shù)據(jù)。
(4)主機(jī)STC89C52發(fā)送溫度上限報(bào)警值十位、溫度上限報(bào)警值個(gè)位。
(5)從機(jī)STC89C52接收溫度上限報(bào)警值命令。
(6)主機(jī)STC89C52未查詢完所有的STC89C52,則返回(1)繼續(xù)查詢下一個(gè)從機(jī)。
(7)通信速率9600bps,數(shù)據(jù)幀格式:一位起始位,9位數(shù)據(jù)位,一位停止位,即串行口工作于方式3。
(8)主機(jī)發(fā)送從機(jī)地址和溫度上限值采用奇校驗(yàn)(每幀數(shù)據(jù)的第8位(即D7)為奇校驗(yàn)位);主機(jī)接收從機(jī)發(fā)送的匹配地址和采集到的溫度值時(shí)采用累加和校驗(yàn)。
(9)從機(jī)機(jī)接收主機(jī)發(fā)送的從機(jī)地址和溫度上限值采用奇校驗(yàn)(每幀數(shù)據(jù)的第8位(即D7)為奇校驗(yàn)位);從機(jī)發(fā)送匹配地址和采集到的溫度值時(shí)采用累加和校驗(yàn)。
2.主機(jī)程序設(shè)計(jì)
(1)主機(jī)主程序
主機(jī)主流程圖如圖10-5所示。當(dāng)工作狀態(tài)標(biāo)志為1時(shí),進(jìn)入?yún)?shù)調(diào)整;否則進(jìn)入正常工作狀態(tài)。
圖10-5主機(jī)主程序流程圖
(2)液晶顯示功能程序
圖10-6  主機(jī)液晶顯示界面
主機(jī)LCD1602液晶顯示從機(jī)1和從機(jī)2實(shí)時(shí)采集的溫度值、時(shí)間和日期。如圖10-6所示。從機(jī)1溫度為28.3℃,從機(jī)2溫度為28.7℃,溫度上限為30℃、下限為28℃,當(dāng)前日期為5月16日17點(diǎn)47分。
(3)DS1302實(shí)時(shí)時(shí)鐘功能程序
采用DS1302實(shí)時(shí)時(shí)鐘芯片進(jìn)行年、月、日、時(shí)、分、秒刷新?梢酝ㄟ^按鍵調(diào)整或者無線遙控調(diào)整時(shí)間,并具有系統(tǒng)掉電后啟用備用電池向DS1302繼續(xù)供電的功能,使用戶不必每次上電調(diào)整時(shí)間。
(4)AT24C02 掉電存儲(chǔ)功能程序。用于存儲(chǔ)用戶設(shè)定的溫度上限值。
(5)蜂鳴器報(bào)警功能程序。當(dāng)溫度大于等于用戶設(shè)定的上限值時(shí),主機(jī)蜂鳴器報(bào)警。
(6)繼電器輸出控制程序。當(dāng)溫度大于等于用戶設(shè)定的上限值時(shí),P20和P21輸出低電平,通過三極管VT1和VT2驅(qū)動(dòng)繼電器吸合,控制電扇通風(fēng)降溫,同時(shí)繼電器接通指示燈亮。
(7) 按鍵鍵盤程序
                      圖10-7  按鍵鍵盤布局
按鍵功能如圖10-7所示,當(dāng)set鍵按下時(shí)進(jìn)入調(diào)整模式,并且可以通過set鍵切換進(jìn)入對(duì)溫度上限值、時(shí)間、星期、年月日的調(diào)整狀態(tài)。當(dāng)進(jìn)入某種調(diào)整狀態(tài)時(shí)其對(duì)應(yīng)值會(huì)快速閃爍,通過up鍵或者down鍵進(jìn)行調(diào)整。調(diào)整完畢后按下out鍵保存并退出調(diào)整模式。
(8)主機(jī)通信程序
主機(jī)通信流程圖如圖10-8所示。在數(shù)據(jù)發(fā)送時(shí),采用奇校驗(yàn)校驗(yàn);在接收數(shù)據(jù)時(shí),使用累加和校驗(yàn)。
      
      圖10-8 主機(jī)通信流程圖       圖10-9從機(jī)通信流程圖
3.從機(jī)程序設(shè)計(jì)
(1)從機(jī)通信程序設(shè)計(jì)。從機(jī)通信程序流程圖如圖10-9所示。
(2)從機(jī)主程序設(shè)計(jì)。從機(jī)主程序流程圖如圖10-10所示。首先進(jìn)行系統(tǒng)初始化,然后關(guān)中斷讀取DS18B20中溫度值,讀完溫度值后,開中斷,調(diào)用溫度決策函數(shù)。

圖10-10從機(jī)主程序流程圖
五、實(shí)物照片
系統(tǒng)實(shí)物照片如圖10-11所示。
圖10-11 實(shí)物照片
六、設(shè)計(jì)制作要點(diǎn)
1.STC89C52單片機(jī)多機(jī)通信實(shí)現(xiàn)的原理。 因多機(jī)通信是在方式2和方式3下進(jìn)行,因此SM2位主要用于方式2和方式3。當(dāng)串行口以方式2或方式3接收時(shí),如SM2 =1,則只有當(dāng)接收到的第9位數(shù)據(jù)(RB8)為“1”,才將接收到的前8位數(shù)據(jù)送入SBUF,并置位RI產(chǎn)生中斷請(qǐng)求;否則,將接收到的前8位數(shù)據(jù)丟棄。而當(dāng)SM2=0時(shí),則不論第9位數(shù)據(jù)為“0”還是為“1”,都將前8位數(shù)據(jù)裝入SBUF中,并產(chǎn)生中斷請(qǐng)求。
2. 單片機(jī)晶振頻率建議選擇11.0592MHz。
3. 通信芯片建議選擇TI公司的SN65HVD3082ED,盡量不要選擇MAX485(國產(chǎn))。

單片機(jī)源程序如下:
  1. #include<reg52.h>  //調(diào)用52單片機(jī)庫
  2. #include"1602.h"   //調(diào)用LCD1602庫
  3. #include"ds18b20.h"   //調(diào)用ds18b20溫度傳感器
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. uchar hour,min,sec,count,hour1,hour2,  //定義小時(shí) 分鐘 秒 對(duì)應(yīng)的十位個(gè)位 以及 count計(jì)數(shù)
  7. sec1,sec2,min1,min2;

  8. sbit speaker=P2^1;                  //定義蜂鳴器
  9. sbit key1=P1^0;                          //最低溫度設(shè)置
  10. sbit key2=P1^1;              //最高溫度設(shè)置
  11. sbit key3=P1^2;       //連接切換模式的備用開關(guān) P33和P12口短接 用于切換模式和退出報(bào)警中斷


  12. sbit keyh=P1^5;  //校時(shí)
  13. sbit keym=P1^6;  //校分
  14. sbit keys=P1^7;  //校秒
  15. //定義時(shí)間按鍵

  16. uint  tem;                                  //定義采集溫度
  17. int htem,htem2,time,time2,x,y,z,dot,dot2,maxtem,mintem;                          //定義溫度十位數(shù)、個(gè)位數(shù)、小數(shù),以及其三種模式的標(biāo)記值
  18. int cnt1=1,cnt2=1,cnt3=1,cnt4=1,cnt5=1,cnt6=1,cnt7=1;                  //定義計(jì)數(shù)變量
  19. int i;
  20. uchar mode=0;                          //定義模式變量
  21. uchar code t3[]={"  H/L=0/1:     C"};    //顯示調(diào)最值溫度的十位
  22. uchar code t4[]={"O/D:           C"};    //顯示調(diào)最值溫度的個(gè)位/小數(shù)位字模
  23. uchar code table2[]={  
  24. '0','1','2','3','4','5','6','7','8','9',':'};   //顯示時(shí)間的字模
  25. uchar code t5[]={"Max         . CD"};         //顯示最高溫度的字模
  26. uchar code t6[]={"Min         . CD"};         //顯示最低溫度的字模


  27. //延時(shí)函數(shù)
  28. void delay1(uint i)
  29. {
  30.         while(i--);        
  31. }



  32. //顯示函數(shù)1  初始顯示
  33. void display(uint dat,uchar add)
  34. {
  35. uchar bai,shi ,ge;
  36. bai=dat/100;
  37. shi=dat%100/10;
  38. ge=dat%10;                                                                                   
  39. writelcd_cmd(add);
  40. writelcd_dat(bai+0x30);
  41. writelcd_dat(shi+0x30);
  42. writelcd_cmd(add+3);
  43. writelcd_dat(ge+0x30);
  44. }

  45. void lcd_min()   //定義最小溫度顯示
  46. {
  47.         uchar l;
  48.         
  49. writelcd_cmd(0x38);   //初始化屏那迤粱
  50. delay(5);
  51. writelcd_cmd(0x38);
  52. delay(5);
  53. writelcd_cmd(0x38);
  54. writelcd_cmd(0x08);
  55. writelcd_cmd(0x01);
  56. writelcd_cmd(0x06);
  57. writelcd_cmd(0x0c);
  58. writelcd_cmd(0x80);
  59.         
  60.                 writelcd_cmd(0xc0);
  61.                                                 for(l=0;l<16;l++)                  //依次讀取t6并顯示
  62.                                                 {
  63.                                         writelcd_dat(t6[l]);
  64.                                                 }
  65.                                                 
  66.                                                 display(mintem,0xca);
  67.                                                 delay1(5000000000);   //延時(shí)顯示
  68. }

  69. void lcd_max()  //定義最大溫度顯示
  70. {
  71.         uchar k;
  72.         writelcd_cmd(0x38);   //初始化屏幕清屏
  73. delay(5);
  74. writelcd_cmd(0x38);
  75. delay(5);
  76. writelcd_cmd(0x38);
  77. writelcd_cmd(0x08);
  78. writelcd_cmd(0x01);
  79. writelcd_cmd(0x06);
  80. writelcd_cmd(0x0c);
  81. writelcd_cmd(0x80);
  82.         writelcd_cmd(0xc0);
  83.                                                 for(k=0;k<16;k++)                  //依次讀取t5并顯示
  84.                                                 {
  85.                                         writelcd_dat(t5[k]);
  86.                                                 }
  87.                                                 display(maxtem,0xca);
  88.                                                 delay1(5000000000);
  89. }

  90. void write_Char(unsigned char a,unsigned char b,unsigned char dat) //顯示時(shí)間程序母程序 定位
  91. {      
  92. if (b == 0)   
  93.     {      
  94.     writelcd_cmd(0x80 + a);      
  95.     }      
  96. else   
  97.     {      
  98.     writelcd_cmd(0xC0 + a);      
  99.     }         
  100. writelcd_dat(dat);   
  101. }   

  102. void display4(uchar hour1,uchar hour2,uchar min1,uchar min2,uchar sec1,uchar sec2)    //顯示時(shí)間子程序  取值
  103. {     

  104.    
  105.     write_Char(4,0,table2[hour1]);                    //顯示小時(shí)
  106.     write_Char(5,0,table2[hour2]);  
  107.     write_Char(6,0,table2[0x0a]);                   //顯示冒號(hào)
  108.     write_Char(7,0,table2[min1]);                    //分鐘
  109.     write_Char(8,0,table2[min2]);  
  110.     write_Char(9,0,table2[0x0a]);                    //顯示冒號(hào)
  111.     write_Char(10,0,table2[sec1]);                    //秒
  112.     write_Char(11,0,table2[sec2]);
  113.         
  114.   
  115. }  


  116. //顯示函數(shù)2  調(diào)最值溫度低十位 在LCD上排顯示
  117. void display2(uint dat,uchar add)
  118. {
  119. uchar bai,shi ;
  120. bai=dat/100;
  121. shi=dat%100/10;
  122. //ge=dat%10;                                                                                   
  123. writelcd_cmd(add);
  124. writelcd_dat(shi+0x30);
  125. writelcd_dat(bai+0x30);
  126. writelcd_cmd(add+3);
  127. //writelcd_dat(ge+0x30);
  128. }


  129. //顯示函數(shù)3  調(diào)最值溫度的個(gè)位/小數(shù) 在LCD下排顯示
  130. void display3(uint dat,uchar add)
  131. {
  132. uchar ge;
  133. //bai=dat/100;
  134. //shi=dat%100/10;
  135. ge=dat%10;                                                                                   
  136. writelcd_cmd(add);
  137. //writelcd_dat(shi+0x30);
  138. //writelcd_dat(bai+0x30);
  139. //writelcd_cmd(add+3);
  140. writelcd_dat(ge+0x30);
  141. }


  142. //按鍵掃描函數(shù)
  143. void keyscan()
  144. {  uchar i,j;  //定義i/j
  145.    writelcd_cmd(0x80);  //顯示函數(shù)表示以此顯示t3字模里面的字符
  146.    for(i=0;i<16;i++)
  147.    {writelcd_dat(t3[i]);}
  148.    writelcd_cmd(0xc0);
  149.    for(j=0;j<16;j++)   //顯示函數(shù)表示以此顯示t4字模里面的字符
  150.    {writelcd_dat(t4[j]);}
  151.   
  152.    while(mode!=0)  //當(dāng)mode不為0時(shí)
  153.    {
  154. display2(htem,0x8b);  //顯示調(diào)十位        
  155. display3(time,0xca);   //顯示調(diào)個(gè)位小數(shù)位
  156.                  
  157.    while(mode!=0)
  158.    {
  159.            switch(mode)  //切換模式case語句循環(huán) 5個(gè)模式 5個(gè)循環(huán) 6個(gè)變量 初始模式為0 切換后對(duì)應(yīng)地方的光標(biāo)閃爍
  160.            {
  161.                         
  162.            case 1:writelcd_cmd(0xc0+10);writelcd_cmd(0x0f);break;  //調(diào)個(gè)位
  163.            case 2:writelcd_cmd(0x80+11);writelcd_cmd(0x0f);break;  //調(diào)十位
  164.                  case 3:writelcd_cmd(0xc0+10);writelcd_cmd(0x0f);break;  //調(diào)小數(shù)位                                 
  165.                  case 4:lcd_max();break;                                  //顯示最大溫度
  166.                  case 5:lcd_min();break;  //顯示最小溫度
  167.            default:mode=0;break;
  168.            }
  169.                  
  170.           if(key2==0&&mode==1)  //模式為1 key2為0時(shí) 調(diào)最高位的個(gè)位
  171.           {
  172.                         delay(50);  //按鍵消抖
  173.             y=0;display3(y,0x80);writelcd_cmd(0xca+11);   //max one 在左上角顯示0 表示調(diào)最高溫度
  174.                   
  175.                   if(key2==0)
  176.                 {  
  177.                         delay(10);  //十個(gè)循環(huán) 對(duì)應(yīng)0-9數(shù)字
  178.                    cnt1++;  //計(jì)數(shù)+1
  179.                    while(key2==0);
  180.                    switch(cnt1%11)  //按鍵到10以后清零
  181.                    {
  182.                         case 1:time=0;display3(time,0xca);writelcd_cmd(0xca+11);break;                           //在0xca的地方顯示個(gè)位值 光標(biāo)閃爍
  183.                   case 2:time=1;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  184.             case 3:time=2;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  185.             case 4:time=3;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  186.                         case 5:time=4;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  187.                         case 6:time=5;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  188.                         case 7:time=6;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  189.                         case 8:time=7;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  190.                         case 9:time=8;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  191.                         case 10:time=9;display3(time,0xca);writelcd_cmd(0xca+11);break;                        
  192.                         
  193.                         default:break;        
  194.                    }        
  195.                 }
  196.           }
  197.                 if(key1==0&&mode==1)  //類似 最低個(gè)位
  198.           {
  199.                         delay(50);
  200.             y=1;display3(y,0x80);writelcd_cmd(0xca+11);  //min one 在左上角顯示1 表示調(diào)最低溫度
  201.                   
  202.                   if(key1==0)
  203.                 {  
  204.                         delay(10);
  205.                    cnt4++;
  206.                    while(key1==0);
  207.                    switch(cnt4%11)
  208.                    {
  209.                         case 1:time2=0;display3(time2,0xca);writelcd_cmd(0xca+11);break;         
  210.                   case 2:time2=1;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  211.             case 3:time2=2;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  212.             case 4:time2=3;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  213.                         case 5:time2=4;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  214.                         case 6:time2=5;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  215.                         case 7:time2=6;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  216.                         case 8:time2=7;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  217.                         case 9:time2=8;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  218.                         case 10:time2=9;display3(time2,0xca);writelcd_cmd(0xca+11);break;                        
  219.                         
  220.                         default:break;        
  221.                    }        
  222.                 }
  223.           }
  224.           if(key2==0&&mode==2)  //最高十位
  225.           {
  226.           delay(10);
  227.                         x=00;display2(x,0x80);writelcd_cmd(0x80+11);  //max ten 在左上角顯示00 表示調(diào)最高
  228.           if(key2==0)
  229.                   {
  230.                    cnt2++;
  231.                    while(key2==0);
  232.                    switch(cnt2%11)
  233.                    {
  234.                                 
  235.                     case 1:htem=00;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  236.                     case 2:htem=10;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  237.                     case 3:htem=20;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  238.                           case 4:htem=30;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  239.                     case 5:htem=40;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  240.                     case 6:htem=50;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  241.                     case 7:htem=60;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  242.                     case 8:htem=70;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  243.                     case 9:htem=80;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  244.                     case 10:htem=90;display2(htem,0x8b);writelcd_cmd(0x80+11);break;                  
  245.                                  
  246.         
  247.                                 
  248.                     default:break;
  249.                    }
  250.                   }
  251.                         

  252.           }
  253.                 if(key1==0&&mode==2)
  254.           {
  255.           delay(10);
  256.                         x=10;display2(x,0x80);writelcd_cmd(0x80+11); //min ten 在左上角顯示10表示 調(diào)最低
  257.           if(key1==0)
  258.                   {
  259.                    cnt3++;
  260.                    while(key1==0);
  261.                    switch(cnt3%11)
  262.                    {
  263.                                 
  264.                     case 1:htem2=00;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  265.                     case 2:htem2=10;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  266.                     case 3:htem2=20;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  267.                           case 4:htem2=30;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  268.                     case 5:htem2=40;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  269.                     case 6:htem2=50;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  270.                     case 7:htem2=60;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                 
  271.                     case 8:htem2=70;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                  
  272.                     case 9:htem2=80;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                 
  273.                     case 10:htem2=90;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;                 
  274.                         
  275.                                 
  276.                     default:break;
  277.                    }
  278.                   }
  279.                         

  280.           }
  281.                 if(key2==0&&mode==3)  //最高小數(shù)
  282.           {
  283.                         delay(50);
  284.                           z=00;display2(z,0x80);writelcd_cmd(0xca+11); //max dot
  285.                   
  286.                   if(key2==0)
  287.                 {  
  288.                         delay(10);
  289.                    cnt5++;
  290.                    while(key2==0);
  291.                    switch(cnt5%11)
  292.                    {
  293.                         case 1:dot=0;display3(dot,0xca);writelcd_cmd(0xca+11);break;         
  294.                   case 2:dot=1;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  295.             case 3:dot=2;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  296.             case 4:dot=3;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  297.                         case 5:dot=4;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  298.                         case 6:dot=5;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  299.                         case 7:dot=6;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  300.                         case 8:dot=7;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  301.                         case 9:dot=8;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  302.                         case 10:dot=9;display3(dot,0xca);writelcd_cmd(0xca+11);break;                        
  303.                         
  304.                         default:break;        
  305.                    }        
  306.                 }
  307.           }
  308.                 if(key1==0&&mode==3)  //最低小數(shù)
  309.           {
  310.                         delay(50);
  311.                            z=10;display2(z,0x80);writelcd_cmd(0xca+11);   //min dot
  312.                   
  313.                   if(key1==0)
  314.                 {  
  315.                         delay(10);
  316.                    cnt6++;
  317.                    while(key1==0);
  318.                    switch(cnt6%11)
  319.                    {
  320.                         case 1:dot2=0;display3(dot2,0xca);writelcd_cmd(0xca+11);break;         
  321.                   case 2:dot2=1;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  322.             case 3:dot2=2;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  323.             case 4:dot2=3;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  324.                         case 5:dot2=4;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  325.                         case 6:dot2=5;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  326.                         case 7:dot2=6;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  327.                         case 8:dot2=7;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  328.                         case 9:dot2=8;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  329.                         case 10:dot2=9;display3(dot2,0xca);writelcd_cmd(0xca+11);break;                        
  330.                         
  331.                         default:break;        
  332.                    }        
  333.                 }
  334.           }
  335.                
  336.                 if(mode==4)  //模式4 顯示最大溫度
  337.           {
  338.                         maxtem=htem*10+time*10+dot;
  339.                         lcd_max();                        
  340.           }
  341.                
  342.                 if(mode==5)  //最低溫度
  343.           {
  344.                         mintem=htem2*10+time2*10+dot2;
  345.                         lcd_min();                    
  346.           }
  347.                
  348.    }
  349.   }
  350.   lcd_init();  //模式為0時(shí)執(zhí)行LCD初始化函數(shù)
  351. }




  352. //中斷初始化函數(shù)
  353. void init()
  354. {
  355.   lcd_init();                   //lcd初始化
  356.    speaker=1;  //蜂鳴器口默認(rèn)高電平
  357.    mode=0;  //模式默認(rèn)0
  358.    htem=80;  //最高溫度默認(rèn)80
  359.    time=0;
  360.         htem2=10;  //最低溫度默認(rèn)10
  361.         time2=0;
  362.         dot=0;
  363.         dot2=0;
  364.         EA=1;                                //總中斷開啟
  365.    EX1=1;                                //外部中斷1允許
  366.    ET1=1;                                //定時(shí)器1允許
  367.    TMOD=0X01;                        //定時(shí)中斷1,模式1
  368.    IT1=1;                                //中斷1 下降沿觸發(fā)
  369.    TH1=0Xee;                        //定時(shí)中斷1 0.5us
  370.    TL1=0X00;
  371.          TR1=0;  //定時(shí)中斷1默認(rèn)關(guān)閉
  372.         
  373.           count=0;    //時(shí)間計(jì)數(shù)默認(rèn)為0
  374.     hour=00;    //小時(shí)00
  375.     min=00;    //分鐘00
  376.     sec=00;    //秒00
  377.      
  378.     TH0=(65536-50000)/256;    //內(nèi)部中斷T0初始化
  379.     TL0=(65536-50000)%256;   
  380.     TR0=1;    //內(nèi)部中斷T0開啟
  381.     ET0=1;  
  382.         
  383. }



  384. //主函數(shù)
  385. void main()
  386. {  
  387.   P1=0xe7;     //初始P1口,P14,P13為低電平 使S1 S5 S9 S14 S15 S16變?yōu)榻拥氐钠胀ㄩ_關(guān) S9與P33短接 用于切換模式和退出報(bào)警中斷
  388.          init();                  //中斷初始化
  389.         
  390.         

  391.         while(1)
  392.         {  
  393.                 if(mode!=0)                  //當(dāng)模式不為0
  394.                 {keyscan();}                  //執(zhí)行按鍵掃描 以及調(diào)溫度的程序

  395.              else if(mode==0)                  //模式為0時(shí)
  396.                 {
  397.                                 delay(100);
  398.                     tmpchange();                  //在ds18b20取數(shù)據(jù)
  399.                         tem=tmp();                         //溫度值獲取 為整數(shù) 且小數(shù)位實(shí)際上是個(gè)位 如35.5攝氏度對(duì)應(yīng)的值是355
  400.                         
  401.         if(keyh==0)                 //當(dāng)S14閉合時(shí) 實(shí)現(xiàn)小時(shí)加一  
  402.         {  
  403.             delay(5);  
  404.             if(keyh==0)  
  405.             {     
  406.                 if(hour!=23)    hour++;                    //hour=23后清零
  407.                 else            hour=0;  
  408.             }  
  409.             while(!keyh);                       //檢測(cè)松手      
  410.               
  411.         }  
  412.   
  413.         if(keym==0)              //實(shí)現(xiàn)分鐘加一  
  414.         {  
  415.             delay(5);  
  416.             if(keym==0)  
  417.             {     
  418.                 if(min!=59)                    //59后清零
  419.                 {  
  420.                     min++;  
  421.                 }  
  422.                 else   
  423.                 {  
  424.                     min=0;  
  425.                 }  
  426.             }  
  427.             while(!keym);       //松手檢測(cè)  
  428.               
  429.         }  
  430.   
  431.         if(keys==0)             //實(shí)現(xiàn)秒加一  
  432.         {  
  433. ……………………

  434. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
基于RS-485總線的無線遙控溫控系統(tǒng)設(shè)計(jì).zip (9.66 MB, 下載次數(shù): 124)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂4 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:417546 發(fā)表于 2020-12-19 20:00 | 只看該作者
好評(píng),謝謝分享
回復(fù)

使用道具 舉報(bào)

板凳
ID:285380 發(fā)表于 2021-6-7 21:08 | 只看該作者
多么好的例程,稍微修改能干很多事。
回復(fù)

使用道具 舉報(bào)

地板
ID:285380 發(fā)表于 2021-6-14 11:31 | 只看該作者
大家注意了   壓縮包里面   主機(jī).c里面1602和485的引腳定義是錯(cuò)的。proteus文件里面   485要?jiǎng)h除120歐姆的電阻。
回復(fù)

使用道具 舉報(bào)

5#
ID:99525 發(fā)表于 2022-5-25 12:27 | 只看該作者
Proteus8.9下測(cè)試了下,485無信號(hào),刪了120歐電阻也沒用,不知道樓主的proteus是哪個(gè)版本的!代碼里面錯(cuò)誤比較多,修正后重新編譯了也沒用。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表