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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

我的單片機八路DS18B20溫度采集報警系統Proteus仿真程序設計

  [復制鏈接]
跳轉到指定樓層
樓主
單片機溫度采集報警系統
附件有原理圖,程序代碼
和Proteus仿真工程文件
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>


  3. #define MAXNUM 8 //定義最多有8個 DS18B20

  4. sbit DQ=P2^3;    //定義DS18B20總線端

  5. sbit RS=P2^0;         //液晶端口控制線端口定義
  6. sbit RW=P2^1;         //液晶端口控制線端口定義
  7. sbit E= P2^2;         //液晶端口控制線端口定義

  8. sbit keyenter =P3^2;  //功能按鍵
  9. sbit keyup    =P3^3; //報警溫度加鍵
  10. sbit keydown  =P3^4; //報警溫度減鍵

  11. sbit led=    P1^6;          //亮燈報警
  12. sbit buzzer= P1^7;          //蜂鳴器報警控制腳



  13. unsigned char code lcd0[]={"SEARCH ROMING..."};
  14. unsigned char code lcd1[]={"SEARCH ROM OK!"};
  15. unsigned char code lcd2[]={"THE TOTAL IS:"};
  16. unsigned char code lcd3[]={"NO.[ ]:"};
  17. unsigned char code lcd4[]={'0','1','2','3','4','5','6','7','8','9','.',0xdf,0x43,' '};
  18. unsigned char code setinfo[]={"SET ALARM POINT:"};
  19. unsigned char code pointinfo[]={"ALARM:"};
  20. signed char tempalarm=0;


  21. //0xdf在1602中是“℃”符號的左上角那個圓,0X43是大寫的"C" 他們一起構成了”℃“這個符號

  22. unsigned char dat[6];//用來顯示溫度的參數                                          
  23. unsigned char temp_l,temp_h,negetiveflag=0,temp_over,t;
  24. unsigned char num=0;
  25. unsigned int i;
  26. bit keyflag=0;
  27. idata unsigned char al[MAXNUM];
  28. idata unsigned char ID[MAXNUM][8];

  29. signed char alarm=30; //默認為30攝氏度報警

  30. /***********************液晶模塊**********************************/
  31. void delaylcd(void)//延時程序
  32. {
  33.         unsigned char y;
  34.         for(y=0;y<250;y++);
  35. }

  36. void LCD_write_com(unsigned char com)//液晶寫命令函數
  37. {
  38.         delaylcd();
  39.     RS=0; //RS為1 寫命令
  40.     RW=0;
  41.         E=0;
  42.         E=1;
  43.     P0=com;
  44.            E=0;
  45.         delaylcd();
  46. }

  47. void LCD_write_data(unsigned char dat)//液晶寫數據函數
  48. {
  49.         delaylcd();
  50.         RS=1;   //RS為1 寫數據
  51.         RW=0;
  52.         E=0;
  53.         E=1;
  54.         P0=dat;
  55.         E=0;
  56.         delaylcd();
  57. }
  58. void lcdinit(void)//初始化
  59. {
  60.         LCD_write_com(0x01); //液晶清屏 
  61.         LCD_write_com(0x38); //1602”功能設置命令字“ 顯示2行 每行字體用5*8 ASCII顯示        8位數據接口
  62.         LCD_write_com(0x0c); //顯示控制,開始顯示,不顯示游標,游標不閃爍        
  63.         LCD_write_com(0x06); //輸入方式為增量輸入,不移屏幕
  64. }

  65. /************************ds18b20模塊****************************/
  66. void delay_nus(unsigned int n)//延時 程序 一次8+6(進出)=14us
  67. {
  68.         while(n--);
  69. }

  70. void reset(void)  //ds18b20初始化復位操作
  71. {
  72.          unsigned char x=0;
  73.          DQ = 1;                  //DQ復位
  74.          delay_nus(8);          //稍做延時
  75.          DQ = 0;                  //單片機將DQ拉低
  76.          delay_nus(80);         //精確延時 大于 480us
  77.          DQ = 1;                  //拉高總線
  78.          delay_nus(10);
  79.          x=DQ;                    //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
  80.          delay_nus(5);
  81. }

  82. void write_bit(unsigned char dat)        //DS18B20 寫一位 操作
  83. {
  84.           DQ = 0;
  85.         _nop_();
  86.     _nop_();
  87.          DQ = dat&0x01;
  88.     delay_nus(5);
  89.          DQ = 1;
  90. }

  91. void write_byte(unsigned char dat)//寫一個字節
  92. {
  93.          unsigned char i,j;
  94.          for (i=8; i>0; i--)
  95.          {
  96.                 j=dat&0x01;
  97.                   write_bit(j);
  98.                 dat>>=1;
  99.     }
  100. }

  101. unsigned char read_2bit(void)//讀二位 子程序
  102. {
  103.         unsigned char i;
  104.         unsigned char dat = 0;
  105.         for (i=2;i>0;i--)
  106.         {
  107.                 DQ = 0; // 給脈沖信號
  108.                 dat<<=1;
  109.                 DQ = 1; // 給脈沖信號
  110.                 if(DQ)
  111.                 dat|=0x01;
  112.                 delay_nus(4);
  113.         }
  114.          return(dat);
  115. }

  116. unsigned char read_byte(void)//讀一個字節 子程序
  117. {
  118.         unsigned char i=0;
  119.         unsigned char dat = 0;
  120.         for (i=8;i>0;i--)
  121.         {
  122.                 DQ = 0; // 給脈沖信號
  123.                 dat>>=1;
  124.                 DQ = 1; // 給脈沖信號
  125.                 if(DQ)
  126.                 dat|=0x80;
  127.                 delay_nus(4);
  128.         }
  129.          return(dat);  
  130. }



  131. void delay_nms(unsigned int n)
  132. {
  133.         unsigned int j=0;
  134.         unsigned char i=0;
  135.         for(j=0;j<n;j++)
  136.         {
  137.                 for(i=0;i<120;i++)
  138.                 {
  139.                         _nop_();
  140.                 }
  141.         }
  142. }
  143. /*******************************************************************************
  144. * 函 數 名         : read_temp
  145. * 函數功能                   : 讀取某一個DS18B20的溫度
  146. * 輸    入         : 無
  147. * 輸    出         : 無
  148. *******************************************************************************/
  149. void read_temp(unsigned char num_data)//讀取溫度 子程序 參數表示讀第幾個傳感器
  150. {
  151.         unsigned char f;        
  152.         reset();                 //DS18B20復位
  153.         write_byte(0xcc);//發送跳過ROM號命令
  154.         write_byte(0x44);//發送溫度轉換命令
  155.         delay_nms(2000);//等待溫度轉換完               
  156.         reset();
  157.         write_byte(0x55);//發送匹配ROM號命令
  158.         for(f=0;f<8;f++) //一個ROM為8位
  159.         {
  160.                 write_byte(ID[num_data][f]);//發匹配ROM
  161.         }
  162.         delay_nus(100);
  163.         write_byte(0xbe);//發送讀溫度命令
  164.         delay_nus(100);
  165.         temp_l=read_byte();
  166.         temp_h=read_byte();
  167. }
  168. /*******************************************************************************
  169. * 函 數 名         : temp_convert
  170. * 函數功能                   : 將讀取到的溫度轉換
  171. * 輸    入         : 無
  172. * 輸    出         : 無
  173. *******************************************************************************/

  174. void temp_convert(void)//溫度轉換
  175. {
  176.         negetiveflag=0;          //溫度的符號標志位
  177.         negetiveflag=temp_h&0x80;
  178.         if(negetiveflag)   //溫度為負
  179.         {
  180.                 negetiveflag=1;         //溫度為負,溫度標志位為1
  181.                 temp_h=~temp_h;
  182.                   if(temp_l==0)
  183.                 {
  184.                          temp_h++;  //若低8位全為0且溫度為負,取補時就要向高位進1
  185.                 }
  186.                   temp_l=~temp_l+1;         //若溫度為負,則求溫度的絕對值(補碼)
  187.         }
  188.         temp_h<<=4;
  189.         temp_l>>=4;                         //去除溫度的小數部分
  190.         temp_over=temp_h|temp_l;  //留下8位的溫度整數部分
  191.         tempalarm=temp_over;
  192.         if(negetiveflag==1)
  193.         {
  194.                  tempalarm=tempalarm*(-1);
  195.         }
  196. }

  197. /*******************************************************************************
  198. * 函 數 名         : search_cartoon
  199. * 函數功能                   : 搜索ROM動畫的顯示
  200. * 輸    入         : 無
  201. * 輸    出         : 無
  202. *******************************************************************************/
  203. void search_cartoon(void)//搜索ROM動畫
  204. {
  205.         lcdinit();
  206.         LCD_write_com(0x80);//液晶第一行地址
  207.     for(i=0;i<16;i++)
  208.         {
  209.                 LCD_write_data(lcd0[i]); //顯示"SEARCH ROMING..."字符
  210.         }
  211.         LCD_write_com(0xc0);//液晶第二行地址
  212.     for(i=0;i<16;i++)
  213.         {
  214.                 LCD_write_data(0xff);//顯示類似進度條的黑點
  215.                 delay_nms(num*80);
  216.         }                 
  217. }
  218. /*******************************************************************************
  219. * 函 數 名         : display_alarm_normal
  220. * 函數功能                   : 顯示報警溫度
  221. * 輸    入         : 無
  222. * 輸    出         : 無
  223. *******************************************************************************/
  224. void display_alarm_normal(signed char alarm_data)//顯示報警溫度
  225. {
  226.         unsigned int data_b,data_temp,l,datx[6]={0};
  227.         data_b=alarm_data;
  228.         negetiveflag=0;                  //默認報警溫度為正

  229.     LCD_write_com(0x80);
  230.         for(l=0;l<6;l++)
  231.         {
  232.                 LCD_write_data(pointinfo[l]);         //顯示"ALARM:"字符
  233.         }   

  234.         if(alarm_data>=0)
  235.         {
  236.                 data_b=alarm_data/100;//顯示報警溫度百位
  237.         }
  238.         else
  239.         {
  240.                 negetiveflag=1;                        //報警溫度為負
  241.                 alarm_data=alarm_data*(-1);//變成正溫度
  242.         }

  243.         data_temp=alarm_data%100;//對100取余,也就是十位數和個位數

  244.         datx[0]=data_temp/10;//十位
  245.         datx[1]=data_temp%10;//個位
  246.         datx[2]=13;//空格符號
  247.         datx[3]=13;//空格符號
  248.         datx[4]=11;//攝氏度符號
  249.         datx[5]=12;//攝氏度符號

  250.         LCD_write_com(0x88);

  251.         if(negetiveflag==1)
  252.         {
  253.                 LCD_write_data(0x2d);//顯示"-"  “負號”
  254.         }
  255.         else
  256.         {
  257.                 LCD_write_data(lcd4[data_b]);//如果大于0就顯示百位數,否則百位數就顯示“負號”
  258.         }

  259.         for(l=0;l<6;l++)//顯示報警值和攝氏度符號
  260.         {
  261.           LCD_write_data(lcd4[datx[l]]);
  262.         }        
  263. }
  264. /*******************************************************************************
  265. * 函 數 名         : display_total
  266. * 函數功能                   : 顯示報警溫度
  267. * 輸    入         : 無
  268. * 輸    出         : 無
  269. *******************************************************************************/
  270. void display_total(void)          //顯示搜索到的DS18B20傳感器數目
  271. {
  272.         lcdinit();
  273.         LCD_write_com(0x80);//第一行地址
  274.     for(i=0;i<14;i++)
  275.         {
  276.                 LCD_write_data(lcd1[i]);        //顯示"SEARCH ROM OK!"字符
  277.         }
  278.         LCD_write_com(0xc0);//第二行地址
  279.     for(i=0;i<13;i++)
  280.         {
  281.                 LCD_write_data(lcd2[i]);   //顯示"THE TOTAL IS:"字符
  282.         }
  283.         LCD_write_data(lcd4[num]);
  284.         delay_nms(2000);
  285.         lcdinit();                                        //清屏,準備顯示溫度
  286.         display_alarm_normal(alarm);//顯示報警溫度
  287. }
  288. /*******************************************************************************
  289. * 函 數 名         : display_ds18b20
  290. * 函數功能                   : 顯示編號為i的DS18B20的溫度
  291. * 輸    入         : 無
  292. * 輸    出         : 無
  293. *******************************************************************************/
  294. void display_ds18b20(i)//顯示編號為i的DS18B20的溫度
  295. {
  296.         unsigned int data_b,data_temp,l;
  297.         data_b=temp_over/100;//百位
  298.         data_temp=temp_over%100;
  299.         dat[0]=data_temp/10;//十位
  300.         dat[1]=data_temp%10;//個位
  301.         dat[2]=13; //空格
  302.         dat[3]=13; //空格
  303.         dat[4]=11; //攝氏度符號
  304.         dat[5]=12; //攝氏度符號

  305.         LCD_write_com(0xc0);
  306.         for(l=0;l<7;l++)
  307.         {
  308.                 LCD_write_data(lcd3[l]); //顯示"NO.[ ]:"字符
  309.         }
  310.         LCD_write_com(0xc4);
  311.         LCD_write_data(lcd4[++i]);// 依次顯示"NO.[ ]:"字符串[ ]里的內容12345678
  312.         LCD_write_com(0xc8);

  313.         if(negetiveflag==1)
  314.         {
  315.                 LCD_write_data(0x2d);         //如果溫度為負,顯示“—"負號
  316.         }
  317.         else
  318.         {
  319.                 LCD_write_data(lcd4[data_b]);           //如果溫度為正,顯示溫度百位
  320.         }

  321.         for(l=0;l<6;l++)
  322.                 LCD_write_data(lcd4[dat[l]]);        //顯示溫度的十位和個位
  323.         delay_nms(1000);
  324. }
  325. /*******************************************************************************
  326. * 函 數 名         : display_alarm
  327. * 函數功能                   : 顯示 報警溫度調節  的部分
  328. * 輸    入         : 無
  329. * 輸    出         : 無
  330. *******************************************************************************/
  331. void display_alarm(signed char alarm_data)//顯示報警溫度
  332. {
  333.         unsigned int data_b,data_temp,l;
  334.         data_b=alarm_data;
  335.         negetiveflag=0;
  336.         if(alarm_data>=0)         //報警溫度大于0
  337.         {
  338.          data_b=alarm_data/100;//百位
  339.         }
  340.         else                                //報警溫度小于0
  341.         {
  342.          negetiveflag=1;        //溫度符號標志位
  343.          alarm_data=alarm_data*(-1);//變成正溫度
  344.         }

  345.         data_temp=alarm_data%100;//對100取余,也就是十位數和個位數

  346.         dat[0]=data_temp/10;//十位
  347.         dat[1]=data_temp%10;//個位
  348.         dat[2]=13;//空格符號
  349.         dat[3]=11;//攝氏度符號
  350.         dat[4]=12;//攝氏度符號

  351.         if(keyflag==1)//剛剛進入設置報警溫度
  352.         {
  353.             lcdinit();
  354.                 LCD_write_com(0x80);//第一行地址
  355.             for(l=0;l<16;l++)
  356.                 {
  357.                         LCD_write_data(setinfo[l]);        //顯示"SET ALARM POINT:"字符
  358.                 }
  359.         
  360.                 LCD_write_com(0xc0);//第二行地址
  361.                 for(l=0;l<8;l++)
  362.                 {
  363.                         LCD_write_data(pointinfo[l]); //顯示"ALARM:"字符
  364.                 }
  365.         }
  366.         

  367.         LCD_write_com(0xc7);

  368.         if(negetiveflag==1)                  //報警溫度小于0
  369.         {
  370.                 LCD_write_data(0x2d);//顯示"-"  “負號”
  371.         }
  372.         else                                          //報警溫度大于0
  373.         {
  374.                 LCD_write_data(lcd4[data_b]);//如果大于0就顯示百位數
  375.         }

  376.         for(l=0;l<5;l++)//顯示報警值和攝氏度符號
  377.         {
  378.           LCD_write_data(lcd4[dat[l]]);
  379.         }        
  380. }
  381. /*******************************************************************************
  382. * 函 數 名         : display_alarm
  383. * 函數功能                   : 自動搜索ROM
  384. * 輸    入         : 無
  385. * 輸    出         : 無
  386. *******************************************************************************/
  387. void search_rom(void)//搜索ROM
  388. {
  389.         unsigned char k=0,l=0,chongtuwei=0,m=0,n=0;
  390.         unsigned char s=0;
  391.         unsigned char zhan[MAXNUM];
  392.         unsigned char ss[64];        //用來存放ROM,共m=8行,n=8列,一個RONM存放一行(即8位)
  393.         do
  394.         {
  395.                 reset();
  396.                 write_byte(0xf0);  //發送搜索ROM命令        
  397.                 for(m=0;m<8;m++)  //
  398.                 {
  399.                         for(n=0;n<8;n++)
  400.                         {
  401.                                 k=read_2bit();//讀兩位數據
  402.                                 k=k&0x03;   
  403.                                 s>>=1;
  404.                                 if(k==0x01)//01  有器件相連,在此為數據為上它們的數據為0
  405.                                 {                  
  406.                                         write_bit (0);
  407.                                     ss[(m*8+n)]=0;
  408.                                 }
  409.                                 else if(k==0x02)//01  有器件相連,在此為數據為上它們的數據為1
  410.                                 {
  411.                                         s=s|0x80;
  412.                                         write_bit (1);
  413.                                         ss[(m*8+n)]=1;
  414.                                 }
  415.                                 else if(k==0x00)//00  有器件相連,在此為數據為上它們的數據發送沖突即就有1也有0
  416.                                 {                                //如果沖突位大于棧頂寫0 小于棧頂寫以前數據 等于棧頂寫1
  417.                                         chongtuwei=m*8+n+1;                                       
  418.                                         if(chongtuwei>zhan[l])
  419.                                         {                                                
  420.                                                 write_bit (0);
  421.                                                 ss[(m*8+n)]=0;                                                                                                
  422.                                                 zhan[++l]=chongtuwei;                                                
  423.                                         }
  424.                                         else if(chongtuwei<zhan[l])
  425.                                         {
  426.                                                 s=s|((ss[(m*8+n)]&0x01)<<7);
  427.                                                 write_bit (ss[(m*8+n)]);
  428.                                         }
  429.                                         else if(chongtuwei==zhan[l])
  430.                                         {
  431.                                                 s=s|0x80;
  432.                                                 write_bit (1);
  433.                                                 ss[(m*8+n)]=1;
  434.                                                 l=l-1;
  435.                                         }
  436.                                 }
  437.                                 else
  438.                                 {
  439.                                         goto loop;
  440.                                 }
  441.                         }
  442.                         ID[num][m]=s;               
  443.                 }
  444.                 num++;
  445.         }
  446.         while(zhan[l]!=0&&(num<MAXNUM));               
  447. loop:
  448.         search_cartoon();
  449.         display_total();

  450. }



  451. void main (void)
  452. {
  453.         unsigned char i=0,t=0;
  454.         delay_nms(50);
  455.         IT0=0;
  456.         EX0=1;
  457.         EA=1;

  458.     search_rom();//搜索ROM并且存儲,把18B20的每一個ROM讀取出來,方便下次調用


  459.         reset();
  460.                
  461.         while(1)
  462.         {
  463.                 if(keyflag==0)
  464.                 {
  465.                           for(i=0;i<num;i++)        //每一個 ds18b20 循環顯示
  466.                           {
  467.                                         if(keyflag==1) break;
  468.                                         read_temp(i);   //讀編號 i 的ds18b20 的溫度
  469.                                         if(keyflag==1) break;
  470.                                         temp_convert(); //調用溫度轉換
  471.                                         if(keyflag==1) break;
  472.                                     if(tempalarm>alarm)//報警判斷
  473.                                         {
  474.                                           for(t=0;t<3;t++)
  475.                                           {
  476.                                                    buzzer=0;//打開報警蜂鳴器
  477.                                                  led=0;   //打開報警指示燈
  478.                                                  delay_nms(100);
  479.                                                  buzzer=1;//關閉報警蜂鳴器
  480.                                                  led=1;   //關閉報警指示燈
  481.                                                  delay_nms(100);
  482. ……………………

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

代碼+hex下載:
溫度.rar (77.77 KB, 下載次數: 203)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:433738 發表于 2019-12-30 11:23 | 只看該作者
謝謝樓主的分享,對我很有用,可惜沒有Proteus仿真
回復

使用道具 舉報

板凳
ID:678715 發表于 2019-12-31 23:47 | 只看該作者
十分感謝樓主的幫助
回復

使用道具 舉報

地板
ID:741413 發表于 2020-5-18 14:54 | 只看該作者
幫大忙了
回復

使用道具 舉報

5#
ID:727163 發表于 2020-6-10 11:38 | 只看該作者
強啊,可以改為四路德瑪
回復

使用道具 舉報

6#
ID:891767 發表于 2021-3-14 17:09 | 只看該作者
樓主這個可以調節溫度的上限和下限嗎 請問  
回復

使用道具 舉報

7#
ID:917252 發表于 2021-5-26 10:16 | 只看該作者
大佬負的溫度可以正常顯示嗎
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩免费电影 | 日韩福利在线 | 精品久久国产视频 | 国产一区二区在线播放视频 | 99婷婷 | 超碰美女在线 | 久久久久国 | 一级黄色日本片 | 国产在线看片 | 久久久精品一区二区 | 国产精品毛片一区二区在线看 | 中文字幕在线一区 | 青娱乐自拍 | 国产精品一卡二卡三卡 | 日本涩涩网| av天空| 精品视频999 | 久久国产一区二区三区 | 国产视频中文字幕 | 天天天天天操 | 亚洲顶级毛片 | 中文字幕亚洲一区二区va在线 | 久热久| 国产欧美一区二区三区国产幕精品 | 91精品麻豆日日躁夜夜躁 | 成人欧美一区二区三区色青冈 | 乱码av午夜噜噜噜噜动漫 | 亚洲国产成人精品久久 | 精品一区二区久久久久久久网站 | 免费九九视频 | 欧美爱爱视频 | 国产一二区在线 | 欧美无乱码久久久免费午夜一区 | 国产91在线 | 欧美 | 日本精品一区 | 免费看国产片在线观看 | 国产日韩欧美一区二区 | www亚洲精品 | 91麻豆精品一区二区三区 | 亚洲精品久久久久久久久久久久久 | 亚洲性人人天天夜夜摸 |