久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4984|回復: 4
打印 上一主題 下一主題
收起左側

基于RS-485總線的單片機溫控系統程序Proteus仿真設計

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

圖10-1 系統方案框圖

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

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

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

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

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


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

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


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



  32. //顯示函數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);   //延時顯示
  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) //顯示時間程序母程序 定位
  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)    //顯示時間子程序  取值
  103. {     

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


  116. //顯示函數2  調最值溫度低十位 在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. //顯示函數3  調最值溫度的個位/小數 在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. //按鍵掃描函數
  143. void keyscan()
  144. {  uchar i,j;  //定義i/j
  145.    writelcd_cmd(0x80);  //顯示函數表示以此顯示t3字模里面的字符
  146.    for(i=0;i<16;i++)
  147.    {writelcd_dat(t3[i]);}
  148.    writelcd_cmd(0xc0);
  149.    for(j=0;j<16;j++)   //顯示函數表示以此顯示t4字模里面的字符
  150.    {writelcd_dat(t4[j]);}
  151.   
  152.    while(mode!=0)  //當mode不為0時
  153.    {
  154. display2(htem,0x8b);  //顯示調十位        
  155. display3(time,0xca);   //顯示調個位小數位
  156.                  
  157.    while(mode!=0)
  158.    {
  159.            switch(mode)  //切換模式case語句循環 5個模式 5個循環 6個變量 初始模式為0 切換后對應地方的光標閃爍
  160.            {
  161.                         
  162.            case 1:writelcd_cmd(0xc0+10);writelcd_cmd(0x0f);break;  //調個位
  163.            case 2:writelcd_cmd(0x80+11);writelcd_cmd(0x0f);break;  //調十位
  164.                  case 3:writelcd_cmd(0xc0+10);writelcd_cmd(0x0f);break;  //調小數位                                 
  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時 調最高位的個位
  171.           {
  172.                         delay(50);  //按鍵消抖
  173.             y=0;display3(y,0x80);writelcd_cmd(0xca+11);   //max one 在左上角顯示0 表示調最高溫度
  174.                   
  175.                   if(key2==0)
  176.                 {  
  177.                         delay(10);  //十個循環 對應0-9數字
  178.                    cnt1++;  //計數+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的地方顯示個位值 光標閃爍
  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)  //類似 最低個位
  198.           {
  199.                         delay(50);
  200.             y=1;display3(y,0x80);writelcd_cmd(0xca+11);  //min one 在左上角顯示1 表示調最低溫度
  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 表示調最高
  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表示 調最低
  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)  //最高小數
  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)  //最低小數
  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時執行LCD初始化函數
  351. }




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



  384. //主函數
  385. void main()
  386. {  
  387.   P1=0xe7;     //初始P1口,P14,P13為低電平 使S1 S5 S9 S14 S15 S16變為接地的普通開關 S9與P33短接 用于切換模式和退出報警中斷
  388.          init();                  //中斷初始化
  389.         
  390.         

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

  395.              else if(mode==0)                  //模式為0時
  396.                 {
  397.                                 delay(100);
  398.                     tmpchange();                  //在ds18b20取數據
  399.                         tem=tmp();                         //溫度值獲取 為整數 且小數位實際上是個位 如35.5攝氏度對應的值是355
  400.                         
  401.         if(keyh==0)                 //當S14閉合時 實現小時加一  
  402.         {  
  403.             delay(5);  
  404.             if(keyh==0)  
  405.             {     
  406.                 if(hour!=23)    hour++;                    //hour=23后清零
  407.                 else            hour=0;  
  408.             }  
  409.             while(!keyh);                       //檢測松手      
  410.               
  411.         }  
  412.   
  413.         if(keym==0)              //實現分鐘加一  
  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);       //松手檢測  
  428.               
  429.         }  
  430.   
  431.         if(keys==0)             //實現秒加一  
  432.         {  
  433. ……………………

  434. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

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

使用道具 舉報

沙發
ID:417546 發表于 2020-12-19 20:00 | 只看該作者
好評,謝謝分享
回復

使用道具 舉報

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

使用道具 舉報

地板
ID:285380 發表于 2021-6-14 11:31 | 只看該作者
大家注意了   壓縮包里面   主機.c里面1602和485的引腳定義是錯的。proteus文件里面   485要刪除120歐姆的電阻。
回復

使用道具 舉報

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

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 男女羞羞视频免费看 | 99精品一区二区三区 | av手机免费在线观看 | 国产成人精品一区二区三区四区 | 日韩在线资源 | 国产成人在线一区二区 | 美女福利网站 | 成人av一区二区三区 | 精品欧美一区二区三区久久久 | 精品国产乱码久久久久久蜜臀 | 欧美精品福利 | 精品久久一区二区三区 | 亚洲精品视频导航 | 一区二区三区亚洲 | 久久综合激情 | 久久r精品 | 成人精品 | 亚洲欧洲成人av每日更新 | 久久精品色欧美aⅴ一区二区 | 欧美综合网| 精品欧美色视频网站在线观看 | 久久九七| 亚洲福利在线视频 | 日本免费一区二区三区 | 国产精品高潮呻吟久久 | 国产精品视频500部 a久久 | 久久精品国产久精国产 | 一区二区三区欧美在线 | 久久最新精品 | 欧美精品日韩精品国产精品 | 久草热在线 | www.久| 国产做a爱免费视频 | 欧美日韩在线电影 | 国产高清亚洲 | 欧美亚洲国产一区二区三区 | 欧美精品综合 | 蜜臀网 | 日韩一区二区在线视频 | 国产成人精品一区二区三区视频 | 久久久精品在线 |