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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6218|回復: 2
收起左側

單片機8路ds18b20溫度采集Proteus仿真+代碼

[復制鏈接]
ID:491242 發表于 2019-3-15 10:07 | 顯示全部樓層 |閱讀模式
8路溫度采集器
0.png

單片機源程序如下:
  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.                                         }
  484.                                 display_ds18b20(i);//顯示 編號 i 的溫度               
  485.                       }
  486.                 }                  

  487.                 else//設置按鍵按下 進行按鍵掃描動作
  488.                 {
  489.                    display_alarm(alarm);
  490.                    keyflag=0;
  491.                    while(1)
  492.                    {
  493.                             if(keyenter==0&&keyflag==0)//進入設置以后,再按設置按鍵,就退出設置,重新顯示每一個通道溫度
  494.                                 {
  495.                                   delay_nms(200);
  496.                                   if(keyenter==0)
  497.                                   {
  498.                                         while(keyenter==0);         
  499.                                         lcdinit();
  500.                                         display_alarm_normal(alarm);//顯示報警溫度
  501.                                         break;//退出按鍵掃描
  502.                                   }
  503.                                 }
  504.                         if(keyup==0)//
  505.                                 {
  506.                                   delay_nms(200);
  507.                                   if(keyup==0&&alarm<125)
  508.                                   {
  509.                                          alarm++;//報警溫度加1
  510.                                   }
  511.                                   display_alarm(alarm);
  512.                                 }
  513.                    if(keydown==0&&alarm>-55)//
  514.                                 {
  515.                                   delay_nms(200);
  516.                                   if(keydown==0)
  517.                                   {
  518.                                         alarm--;//報警溫度減1
  519.                                   }
  520.                                   display_alarm(alarm);
  521.                                 }
  522.                                 delay_nms(50);
  523.                    }
  524.                    EX0=1;       
  525.                 }
  526.                              
  527.         }//while(1)結束  
  528. }

  529. void key_init0(void) interrupt 0
  530. {
  531.         if(keyenter==0)
  532.         {
  533.           delay_nms(10);
  534.           if(keyenter==0)
  535.           {
  536.                   EX0=0;
  537.                 keyflag=1;
  538.           }
  539.         }
  540.        
  541. }
復制代碼

所有資料51hei提供下載:
仿真文件.zip (49.24 KB, 下載次數: 142)

評分

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

查看全部評分

回復

使用道具 舉報

ID:89286 發表于 2019-3-27 00:20 | 顯示全部樓層
thanks for sharing
回復

使用道具 舉報

ID:521711 發表于 2019-5-9 10:34 | 顯示全部樓層
請問有沒有聯系方式,或者你加我qq943120061,想請教問題,謝謝
回復

使用道具 舉報

ID:60453 發表于 2019-5-30 09:00
垃圾,騙人的,不能用

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av电影手机版 | av手机免费在线观看 | 久久精品日产第一区二区三区 | 视频1区2区 | 国产精品成人一区二区三区 | 日韩在线高清 | 精品国产一区二区在线 | 国产激情一区二区三区 | 天天草天天爱 | www.操.com| 黑人粗黑大躁护士 | 久久久久久久国产精品 | 欧美一级免费 | av电影一区| 欧美在线视频观看 | 久久99精品久久久久久 | 国产精品一区二区三 | 99精品免费视频 | 国产精品大全 | 中文字幕成人av | 日韩在线精品视频 | 中文字幕在线一区 | 日本小视频网站 | 成人久久18免费 | 91看片网| av天空| 亚洲精品 在线播放 | 丝袜 亚洲 另类 欧美 综合 | 国产精品久久久久久久久久免费看 | 成人精品视频 | 久久国产精品免费 | 99热视 | a在线视频 | 免费播放一级片 | 亚洲一区精品在线 | 欧美一级高潮片免费的 | 亚洲国产精品久久久 | 日韩在线| 国产精品免费大片 | 国产一区二区三区在线 | 国产视频一区二区三区四区五区 |