標(biāo)題: stm32驅(qū)動(dòng)ds18b20溫度讀取源程序 [打印本頁]

作者: xu2509674896    時(shí)間: 2020-12-19 16:57
標(biāo)題: stm32驅(qū)動(dòng)ds18b20溫度讀取源程序
       發(fā)上來的程序是主要基于stm32f1的驅(qū)動(dòng)程序,如果你需要清楚了解ds18b20的工作時(shí)序,寄存器配置,那么在論壇上找找看看數(shù)據(jù)手冊,如果你想直接用,那么把頭文件和c文件直接添加到你的工程中就可以了。       本程序在實(shí)質(zhì)上和51驅(qū)動(dòng)的沒有區(qū)別,都是模擬I2C。兩者區(qū)別在于大部分51對于IO口的輸入輸出配置沒有硬性規(guī)定,既可以當(dāng)輸入又可以當(dāng)輸出,而stm32的輸入輸出必須明確模式配置。而ds18b20是一線通信,所以需要輸入輸出模式來回配置。
       本程序我通過硬件明確測試過,可以準(zhǔn)確讀出數(shù)據(jù),如果數(shù)據(jù)無法讀出,可能是以下幾點(diǎn)問題:
       1、引腳配置未修改。可在h文件中修改宏定義即可
       2、請注意該函數(shù)void DS18B20_DQ_DDR(uint8_t ddr),他是用于修改IO輸入輸出模式的,本程序使用的標(biāo)準(zhǔn)庫函數(shù)進(jìn)行操作,用到的時(shí)間可能會(huì)有一點(diǎn)長,影響到了I2C的模擬時(shí)序,建議可以直接對寄存器進(jìn)行操作,庫函數(shù)的實(shí)質(zhì)也是修改寄存器,只是由于為了程序兼容性,犧牲了時(shí)間。
       3、由于是模擬的I2C時(shí)序,請務(wù)必注意中斷對于通信時(shí)序的影響。

單片機(jī)源程序如下:
  1. #include "ds18b20.h"//主要包含了一些引腳宏定義,移植時(shí)必須包含
  2. #include "delay.h"//主要是聲明了延時(shí)函數(shù),由于是模擬I2C,延時(shí)必須精準(zhǔn)
  3. #include "math.h"//使用了庫函數(shù)pow()函數(shù),該函數(shù)為冪次函數(shù),如pow(10,2),相當(dāng)于10^2,移植時(shí)必須包含
  4. /*******************************************************************************
  5. 函數(shù)名:DS18B20_DQ_DDR
  6. 功能:配置IO輸入/輸出狀態(tài)
  7. 輸入:0/1    輸入0配置為輸入,輸入1配置為輸出
  8. 輸出:
  9. 返回值:
  10. *******************************************************************************/
  11. void DS18B20_DQ_DDR(uint8_t ddr)
  12. {
  13.         GPIO_InitTypeDef  GPIO_InitStructure;
  14.         //使能GPIO時(shí)鐘
  15.   RCC_APB2PeriphClockCmd(DS18B20_GPIO_CLK, ENABLE);       
  16.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;       
  17.   //配置為輸出
  18.   if(ddr == 1)
  19.   {
  20.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        
  21.                 GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN;                                          
  22.                 GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure);               
  23.                
  24.   }
  25.   //配置為輸入
  26.   else
  27.         {
  28.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        
  29.                 GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN;                                          
  30.                 GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure);       
  31.   }
  32. }
  33. /*******************************************************************************
  34. 函數(shù)名:DS18B20_Init
  35. 功能:初始化DS18B20
  36. 輸入:
  37. 輸出:
  38. 返回值:初始化成功為0,不成功為1
  39. 備注:
  40. *******************************************************************************/
  41. u8 DS18B20_Init(void)
  42. {
  43.         u8 x = 0;
  44.   //改變DQ引腳為輸出
  45.   DS18B20_DQ_DDR(1);
  46.   //先置高
  47.   DS18B20_DQ_H;  
  48.   //延時(shí)700us,使總線穩(wěn)定
  49.   delay_us(700);
  50.   //復(fù)位脈沖,低電位
  51.   DS18B20_DQ_L;  
  52.   //保持至少480us,這里500us
  53.   delay_us(500);
  54.   //改變DQ引腳為輸入
  55.   DS18B20_DQ_DDR(0);
  56.   //拉高數(shù)據(jù)線,釋放總線
  57.   DS18B20_DQ_H;  
  58.   //等待15-60us,這里40us
  59.   delay_us(40);
  60.   //等待35us
  61.   delay_us(35);
  62.   //聆聽,判斷有沒有初始化成功(DS18B20有沒有發(fā)送應(yīng)答脈沖)
  63.   x = DS18B20_DQ_ReadPin;   
  64.   //至少480us后進(jìn)入接收狀態(tài),這里500us
  65.   delay_us(500);
  66.   return x;
  67. }
  68. /*******************************************************************************
  69. 函數(shù)名:DS18B20_Wbyte
  70. 功能:寫一個(gè)字節(jié)
  71. 輸入:uint8_t xbyte
  72. 輸出:
  73. 返回值:
  74. 備注:
  75. *******************************************************************************/
  76. void DS18B20_Wbyte(uint8_t xbyte)
  77. {
  78.         //i:循環(huán)控制變量,x:取位運(yùn)算變量
  79.   int8_t i ,x = 0;
  80.   //改變DQ引腳為輸出
  81.   DS18B20_DQ_DDR(1);
  82.   //8次循環(huán)實(shí)現(xiàn)逐位寫入
  83.   for(i = 1; i <= 8; i++)
  84.   {
  85.                 //先取低位
  86.     x = xbyte & 0x01;
  87.     //寫1
  88.     if(x)
  89.     {
  90.       DS18B20_DQ_H;
  91.       //拉低總線
  92.       DS18B20_DQ_L;
  93.       //延時(shí)15us
  94.       delay_us(15);
  95.       //總線寫1
  96.       DS18B20_DQ_H;
  97.       //延時(shí)15us
  98.       delay_us(15);
  99.       //保持高電平
  100.       DS18B20_DQ_H;
  101.       delay_us(4);
  102.                 }
  103.                 //寫0
  104.                 else
  105.     {
  106.                         DS18B20_DQ_H;
  107.       //總線拉低
  108.       DS18B20_DQ_L;
  109.       //延時(shí)15us
  110.       delay_us(15);
  111.       //總線寫0
  112.       DS18B20_DQ_L;
  113.       //延時(shí)15us
  114.       delay_us(15);
  115.       //保持高電平
  116.       DS18B20_DQ_H;
  117.       delay_us(4);
  118.     }
  119.     //xbyte右移一位
  120.     xbyte = xbyte >> 1;
  121.         }
  122. }
  123. /*******************************************************************************
  124. 函數(shù)名:DS18B20_Rbit
  125. 功能:從DS18B20讀一個(gè)位
  126. 輸入:
  127. 輸出:
  128. 返回值:讀取到的位
  129. 備注:
  130. *******************************************************************************/
  131. uint8_t DS18B20_Rbit(void)
  132. {
  133.         //rbit是最終位數(shù)據(jù),x是取狀態(tài)變量
  134.   uint8_t rbit = 0x00,x = 0;
  135.   //改變DQ為輸出模式
  136.   DS18B20_DQ_DDR(1);
  137.   DS18B20_DQ_H;
  138.   //總線寫0
  139.   DS18B20_DQ_L;
  140.   //延時(shí)15us以內(nèi)
  141.   delay_us(5);
  142.   //釋放總線
  143.   DS18B20_DQ_H;
  144.   //改變DQ為輸入模式
  145.   DS18B20_DQ_DDR(0);
  146.   //延時(shí)大約3us
  147.   delay_us(3);
  148.   //獲取總線電平狀態(tài)
  149.   x = DS18B20_DQ_ReadPin;
  150.   //如果是1,則返回0x80,否則返回0x00
  151.   if(x)
  152.                 rbit = 0x80;
  153.   //延時(shí)大約60us
  154.   delay_us(60);
  155.         return rbit;
  156. }
  157. /*******************************************************************************
  158. 函數(shù)名:DS18B20_Rbyte
  159. 功能:從DS18B20讀一個(gè)字節(jié)
  160. 輸入:
  161. 輸出:
  162. 返回值:讀取到的字節(jié)
  163. 備注:
  164. *******************************************************************************/
  165. uint8_t DS18B20_Rbyte(void)
  166. {
  167.   //rbyte:最終得到的字節(jié)
  168.   //tempbit:中間運(yùn)算變量
  169.   uint8_t rbyte = 0,i = 0, tempbit =0;
  170.   for (i = 1; i <= 8; i++)
  171.   {
  172.     //讀取位
  173.     tempbit = DS18B20_Rbit();
  174.     //右移實(shí)現(xiàn)高低位排序
  175.     rbyte = rbyte >> 1;
  176.     //或運(yùn)算移入數(shù)據(jù)
  177.     rbyte = rbyte|tempbit;
  178.   }
  179.   return rbyte;
  180. }
  181. int ReadTemperature(void)
  182. {
  183.   //fg:符號位
  184.   //data:溫度的整數(shù)部分
  185.   int fg;
  186.   int data;
  187.   //DS18B20初始化
  188.   DS18B20_Init();
  189.   //跳過讀序列號
  190.   DS18B20_Wbyte(0xcc);
  191.   //啟動(dòng)溫度轉(zhuǎn)換
  192.   DS18B20_Wbyte(0x44);
  193.   //等待溫度轉(zhuǎn)換
  194.   delay_ms(1);
  195.   DS18B20_Init();
  196.   DS18B20_Wbyte(0xcc);
  197.   //讀溫度寄存器
  198.   DS18B20_Wbyte(0xbe);
  199.   uint8_t TempL = DS18B20_Rbyte();//讀取低8位
  200.   uint8_t TempH = DS18B20_Rbyte();//讀取高8位
  201.   //符號位為負(fù)
  202.   if(TempH > 0x70)
  203.   {
  204.     TempL = ~TempL;
  205.     TempH = ~TempH;
  206.     fg = 0;
  207.   }
  208.   else fg = 1;
  209.                
  210.         //將數(shù)據(jù)高低位合并
  211.   data = TempH;//數(shù)據(jù)高八位
  212.   data <<=  8;//左移8位
  213.   data += TempL;//加上低八位

  214.         //data的"1"相當(dāng)于0.0625℃
  215.         //換句話說,想要多少精度可以這樣寫:data=(float)data*0.0625*pow(10,n)
  216.         //其中n為保留的小數(shù)精度位數(shù),可以從目前對ds18b20配置情況下看出最高保留小數(shù)的精度位數(shù)為4位
  217.         //這樣只需要對返回值進(jìn)行處理就可以用于顯示了
  218.         //特別注意的是,int類型的數(shù)據(jù)長度為16位,最大值為65535,因此需要注意使用范圍
  219.         data=(float)data*0.0625*pow(10,1);//這樣寫等同于下面一句
  220.   //data = (float)data*0.625;//這樣相當(dāng)于精度為0.1℃
  221.   if(fg)
  222.     return data;
  223.   else
  224.      return -data;
  225. }
復(fù)制代碼

所有資料51hei提供下載:
DS18B20.rar (2.56 KB, 下載次數(shù): 101)








歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1