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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

DS18B20溫度傳感器程序及仿真

  [復制鏈接]
跳轉到指定樓層
樓主
DS18B20數字溫度傳感器
PROTEUS仿真
LCD顯示屏LM016L
AT89C51




所有文件下載 : DS18B20溫度傳感器proteus仿真.zip (64.02 KB, 下載次數: 50)

  1. /***********************lcd1602.c文件程序源代碼*************************/
  2. #include <reg51.h>
  3. #define LCD1602_DB   P0
  4. sbit LCD1602_RS = P1^0;
  5. sbit LCD1602_RW = P1^1;
  6. sbit LCD1602_E  = P1^5;
  7. void LcdWaitReady()  //等待液晶準備好
  8. {
  9.     unsigned char sta;
  10.    
  11.     LCD1602_DB = 0xFF;
  12.     LCD1602_RS = 0;
  13.     LCD1602_RW = 1;
  14.     do
  15.     {
  16.         LCD1602_E = 1;
  17.         sta = LCD1602_DB; //讀取狀態字
  18.         LCD1602_E = 0;
  19.     } while (sta & 0x80); //bit7等于1表示液晶正忙,重復檢測直到其等于0為止
  20. }
  21. void LcdWriteCmd(unsigned char cmd)  //寫入命令函數
  22. {
  23.     LcdWaitReady();
  24.     LCD1602_RS = 0;
  25.     LCD1602_RW = 0;
  26.     LCD1602_DB = cmd;
  27.     LCD1602_E  = 1;
  28.     LCD1602_E  = 0;
  29. }
  30. void LcdWriteDat(unsigned char dat)  //寫入數據函數
  31. {
  32.     LcdWaitReady();
  33.     LCD1602_RS = 1;
  34.     LCD1602_RW = 0;
  35.     LCD1602_DB = dat;
  36.     LCD1602_E  = 1;
  37.     LCD1602_E  = 0;
  38. }
  39. void LcdShowStr(unsigned char x, unsigned char y, const unsigned char *str)  //顯示字符串,屏幕起始坐標(x,y),字符串指針str
  40. {
  41.     unsigned char addr;
  42.    
  43.     //由輸入的顯示坐標計算顯示RAM的地址
  44.     if (y == 0)
  45.         addr = 0x00 + x; //第一行字符地址從0x00起始
  46.     else
  47.         addr = 0x40 + x; //第二行字符地址從0x40起始
  48.    
  49.     //由起始顯示RAM地址連續寫入字符串
  50.     LcdWriteCmd(addr | 0x80); //寫入起始地址
  51.     while (*str != '\0')      //連續寫入字符串數據,直到檢測到結束符
  52.     {
  53.         LcdWriteDat(*str);
  54.         str++;
  55.     }
  56. }
  57. void LcdInit()  //液晶初始化函數
  58. {
  59.     LcdWriteCmd(0x38);  //16*2顯示,5*7點陣,8位數據接口
  60.     LcdWriteCmd(0x0C);  //顯示器開,光標關閉
  61.     LcdWriteCmd(0x06);  //文字不動,地址自動+1
  62.     LcdWriteCmd(0x01);  //清屏
  63. }
  64. /***********************DS18B20.c文件程序源代碼*************************/
  65. #include <reg51.h>
  66. #include <intrins.h>
  67. sbit IO_18B20 = P3^2;  //DS18B20通信引腳
  68. void DelayX10us(unsigned char t)  //軟件延時函數,延時時間(t*10)us
  69. {
  70.     do {
  71.         _nop_();
  72.         _nop_();
  73.         _nop_();
  74.         _nop_();
  75.         _nop_();
  76.         _nop_();
  77.         _nop_();
  78.         _nop_();
  79.     } while (--t);
  80. }
  81. bit Get18B20Ack(void)  //復位總線,獲取存在脈沖,以啟動一次讀寫操作
  82. {
  83.     bit ack;
  84.    
  85.     EA = 0;   //禁止總中斷
  86.     IO_18B20 = 0;     //產生500us復位脈沖
  87.     DelayX10us(50);
  88.     IO_18B20 = 1;
  89.     DelayX10us(6);    //延時60us
  90.     ack = IO_18B20;   //讀取存在脈沖
  91.     while(!IO_18B20); //等待存在脈沖結束
  92.     EA = 1;   //重新使能總中斷
  93.    
  94.     return ack;
  95. }
  96. void Write18B20(unsigned char dat)  //向DS18B20寫入一個字節數據
  97. {
  98.     unsigned char mask;
  99.    
  100.     EA = 0;   //禁止總中斷
  101.     for (mask=0x01; mask!=0; mask<<=1)  //低位在先,依次移出8個bit
  102.     {
  103.                 IO_18B20 = 0;         //產生2us低電平脈沖
  104.         _nop_();
  105.                 _nop_();
  106.         if ((mask&dat) == 0)  //輸出該bit值
  107.             IO_18B20 = 0;
  108.         else
  109.             IO_18B20 = 1;
  110.                 DelayX10us(6);        //延時60us
  111.                 IO_18B20 = 1;         //拉高通信引腳
  112.     }
  113.     EA = 1;   //重新使能總中斷
  114. }
  115. unsigned char Read18B20(void)  //從DS18B20讀取一個字節數據
  116. {
  117.     unsigned char dat;
  118.     unsigned char mask;
  119.    
  120.     EA = 0;   //禁止總中斷
  121.             for (mask=0x01; mask!=0; mask<<=1)  //低位在先,依次采集8個bit
  122.     {
  123.         IO_18B20 = 0;         //產生2us低電平脈沖
  124.                 _nop_();
  125.                 _nop_();
  126.                 IO_18B20 = 1;         //結束低電平脈沖,等待18B20輸出數據
  127.                 _nop_();              //延時2us
  128.                 _nop_();
  129.         if (!IO_18B20)        //讀取通信引腳上的值
  130.                 dat &= ~mask;
  131.         else
  132.             dat |= mask;
  133.                 DelayX10us(6);        //再延時60us
  134.             }
  135.     EA = 1;   //重新使能總中斷
  136.     return dat;
  137. }
  138. bit Start18B20()  //啟動一次18B20溫度轉換,返回值代表是否啟動成功
  139. {
  140.     bit ack;
  141.    
  142.     ack = Get18B20Ack();   //執行總線復位,并獲取18B20應答
  143.     if (ack == 0)          //如18B20正確應答,則啟動一次轉換
  144.     {
  145.             Write18B20(0xCC);  //跳過ROM操作
  146.             Write18B20(0x44);  //啟動一次溫度轉換
  147.     }
  148.     return ~ack;  //ack==0表示操作成功,所以返回值為其取反值
  149. }
  150. bit Get18B20Temp(int *temp)  //讀取DS18B20溫度值,返回值代表是否讀取成功
  151. {
  152.     bit ack;
  153.     unsigned char LSB, MSB; //16bit溫度值的低字節和高字節
  154.    
  155.     ack = Get18B20Ack();    //執行總線復位,并獲取18B20應答
  156.     if (ack == 0)           //如18B20正確應答,則讀取溫度值
  157.     {
  158.             Write18B20(0xCC);   //跳過ROM操作
  159.             Write18B20(0xBE);   //發送讀命令
  160.             LSB = Read18B20();  //讀溫度值的低字節
  161.             MSB = Read18B20();  //讀溫度值的高字節
  162.         *temp = ((int)MSB << 8) + LSB;  //合成為16bit整型數
  163.     }
  164. return ~ack;  //ack==0表示操作應答,所以返回值為其取反值
  165. }
  166. /***********************main.c文件程序源代碼*************************/
  167. #include <reg51.h>
  168. bit flag1s = 0;          //1s定時標志
  169. unsigned char T0RH = 0;  //T0重載值的高字節
  170. unsigned char T0RL = 0;  //T0重載值的低字節
  171. void ConfigTimer0(unsigned int ms);
  172. unsigned char IntToString(unsigned char *str, int dat);
  173. extern bit Start18B20();
  174. extern bit Get18B20Temp(int *temp);
  175. extern void LcdInit();
  176. extern void LcdShowStr(unsigned char x, unsigned char y, const unsigned char *str);
  177. void main ()
  178. {
  179.     bit res;
  180.     int temp;        //讀取到的當前溫度值
  181.     int intT, decT;  //溫度值的整數和小數部分
  182.     unsigned char len;
  183.     unsigned char str[12];
  184.     LcdInit();        //初始化液晶
  185.     Start18B20();     //啟動DS18B20
  186.     ConfigTimer0(10); //T0定時10ms
  187.     EA = 1;           //開總中斷
  188.    
  189.     while(1)
  190.     {
  191.         if (flag1s)  //每秒更新一次溫度
  192.         {
  193.             flag1s = 0;
  194.             res = Get18B20Temp(&temp);  //讀取當前溫度
  195.             if (res)                    //讀取成功時,刷新當前溫度顯示
  196.             {
  197.                 intT = temp >> 4;             //分離出溫度值整數部分
  198.                 decT = temp & 0xF;            //分離出溫度值小數部分
  199.                 len = IntToString(str, intT); //整數部分轉換為字符串
  200.                 str[len++] = '.';             //添加小數點
  201.                 decT = (decT*10) / 16;        //二進制的小數部分轉換為1位十進制位
  202.                 str[len++] = decT + '0';      //十進制小數位再轉換為ASCII字符
  203.                 while (len < 6)               //用空格補齊到6個字符長度
  204.                 {
  205.                     str[len++] = ' ';
  206.                 }
  207.                 str[len] = '\0';              //添加字符串結束符
  208.                 LcdShowStr(3, 0, "temperature");
  209.                 LcdShowStr(7, 1, str);        //顯示到液晶屏上
  210.             }
  211.             else                        //讀取失敗時,提示錯誤信息
  212.             {
  213.                 LcdShowStr(6, 0, "error!");
  214.             }
  215.             Start18B20();               //重新啟動下一次轉換
  216.         }
  217.     }
  218. }
  219. unsigned char IntToString(unsigned char *str, int dat)  //整型數轉換為十進制字符串,返回值為轉換后的字符串長度
  220. {
  221.     signed char i;
  222.     unsigned char len = 0;
  223.     unsigned char buf[6];
  224.    
  225.     if (dat < 0)  //如果為負數,首先取絕對值,并添加負號
  226.     {
  227.         dat = -dat;
  228.         *str++ = '-';
  229.         len++;
  230.     }
  231.     for (i=0; i<=4; i++)  //由低到高轉換為十進制位
  232.     {
  233.         buf[ i] = dat % 10;
  234.         dat /= 10;
  235.     }
  236.     for (i=4; i>=1; i--)  //查找有效數字最高位,以忽略更高位的‘0’
  237.     {
  238.         if (buf[ i] != 0)
  239.         {
  240.             break;
  241.         }
  242.     }
  243.     for ( ; i>=0; i--)  //有效數字位轉換為ASCII碼
  244.     {
  245.         *str++ = buf[ i] + '0';
  246.         len++;
  247.     }
  248.     *str = '\0';        //添加字符串結束符
  249.    
  250.     return len;  //返回字符串長度
  251. }
  252. void ConfigTimer0(unsigned int ms)  //T0配置函數
  253. {
  254.     unsigned long tmp;
  255.    
  256.     tmp = 11059200 / 12;      //定時器計數頻率
  257.     tmp = (tmp * ms) / 1000;  //計算所需的計數值
  258.     tmp = 65536 - tmp;        //計算定時器重載值
  259.     tmp = tmp + 12;           //修正中斷響應延時造成的誤差
  260.    
  261.     T0RH = (unsigned char)(tmp >> 8);  //定時器重載值拆分為高低字節
  262.     T0RL = (unsigned char)tmp;
  263.     TMOD &= 0xF0;   //清零T0的控制位
  264.     TMOD |= 0x01;   //配置T0為模式1
  265.     TH0 = T0RH;     //加載T0重載值
  266.     TL0 = T0RL;
  267.     ET0 = 1;        //使能T0中斷
  268.     TR0 = 1;        //啟動T0
  269. }
  270. void InterruptTimer0() interrupt 1  //T0中斷服務函數
  271. {
  272.     static unsigned char tmr1s = 0;
  273.    
  274.     TH0 = T0RH;  //定時器重新加載重載值
  275.     TL0 = T0RL;
  276.     tmr1s++;
  277.     if (tmr1s >= 100)  //定時1s
  278.     {
  279.         tmr1s = 0;
  280.         flag1s = 1;
  281.     }
  282. }
復制代碼


評分

參與人數 2黑幣 +55 收起 理由
天才2333333 + 5 很給力!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:130007 發表于 2016-7-12 13:14 | 只看該作者
可以放兩個溫度傳感器嗎
回復

使用道具 舉報

板凳
ID:48580 發表于 2016-7-20 10:40 | 只看該作者
sdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
回復

使用道具 舉報

地板
ID:980762 發表于 2021-11-16 09:41 | 只看該作者
這個顯示器會亂碼嗎
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中国91av | 成人精品 | 国产精品久久久久久久久久免费看 | 成人av一区二区亚洲精 | 国产电影一区二区在线观看 | 亚洲精品国产第一综合99久久 | 国产视频h | 国产一区www| 91精品久久久久久久久中文字幕 | 在线亚洲免费 | 亚洲三级国产 | 色婷婷国产精品综合在线观看 | 久久精品欧美一区二区三区不卡 | 久久精品国产一区老色匹 | 久久国产成人 | 九九在线精品视频 | 欧美日韩在线一区 | 91视频在线观看免费 | 精品久久久网站 | 国产免费观看一区 | 久久天堂网 | 一区二区久久 | 日韩一级| 国产亚洲网站 | 精品伦精品一区二区三区视频 | 久久国产成人精品国产成人亚洲 | 亚洲精品电影在线观看 | 琪琪午夜伦伦电影福利片 | 日韩欧美二区 | 久久午夜视频 | 北条麻妃99精品青青久久主播 | 亚洲精品久久久一区二区三区 | 日本电影韩国电影免费观看 | 午夜精品一区 | 在线免费观看毛片 | 91国内视频在线 | 久久久www成人免费精品张筱雨 | 我爱操 | 午夜播放器在线观看 | 人人干人人草 | 亚洲综合色丁香婷婷六月图片 |