發(fā)上來的程序是主要基于stm32f1的驅(qū)動程序,如果你需要清楚了解ds18b20的工作時序,寄存器配置,那么在論壇上找找看看數(shù)據(jù)手冊,如果你想直接用,那么把頭文件和c文件直接添加到你的工程中就可以了。 本程序在實質(zhì)上和51驅(qū)動的沒有區(qū)別,都是模擬I2C。兩者區(qū)別在于大部分51對于IO口的輸入輸出配置沒有硬性規(guī)定,既可以當輸入又可以當輸出,而stm32的輸入輸出必須明確模式配置。而ds18b20是一線通信,所以需要輸入輸出模式來回配置。
本程序我通過硬件明確測試過,可以準確讀出數(shù)據(jù),如果數(shù)據(jù)無法讀出,可能是以下幾點問題:
1、引腳配置未修改。可在h文件中修改宏定義即可
2、請注意該函數(shù)void DS18B20_DQ_DDR(uint8_t ddr),他是用于修改IO輸入輸出模式的,本程序使用的標準庫函數(shù)進行操作,用到的時間可能會有一點長,影響到了I2C的模擬時序,建議可以直接對寄存器進行操作,庫函數(shù)的實質(zhì)也是修改寄存器,只是由于為了程序兼容性,犧牲了時間。
3、由于是模擬的I2C時序,請務必注意中斷對于通信時序的影響。
單片機源程序如下:
- #include "ds18b20.h"//主要包含了一些引腳宏定義,移植時必須包含
- #include "delay.h"//主要是聲明了延時函數(shù),由于是模擬I2C,延時必須精準
- #include "math.h"//使用了庫函數(shù)pow()函數(shù),該函數(shù)為冪次函數(shù),如pow(10,2),相當于10^2,移植時必須包含
- /*******************************************************************************
- 函數(shù)名:DS18B20_DQ_DDR
- 功能:配置IO輸入/輸出狀態(tài)
- 輸入:0/1 輸入0配置為輸入,輸入1配置為輸出
- 輸出:
- 返回值:
- *******************************************************************************/
- void DS18B20_DQ_DDR(uint8_t ddr)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- //使能GPIO時鐘
- RCC_APB2PeriphClockCmd(DS18B20_GPIO_CLK, ENABLE);
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
- //配置為輸出
- if(ddr == 1)
- {
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN;
- GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure);
-
- }
- //配置為輸入
- else
- {
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_PIN;
- GPIO_Init(DS18B20_GPIO_PORT, &GPIO_InitStructure);
- }
- }
- /*******************************************************************************
- 函數(shù)名:DS18B20_Init
- 功能:初始化DS18B20
- 輸入:
- 輸出:
- 返回值:初始化成功為0,不成功為1
- 備注:
- *******************************************************************************/
- u8 DS18B20_Init(void)
- {
- u8 x = 0;
- //改變DQ引腳為輸出
- DS18B20_DQ_DDR(1);
- //先置高
- DS18B20_DQ_H;
- //延時700us,使總線穩(wěn)定
- delay_us(700);
- //復位脈沖,低電位
- DS18B20_DQ_L;
- //保持至少480us,這里500us
- delay_us(500);
- //改變DQ引腳為輸入
- DS18B20_DQ_DDR(0);
- //拉高數(shù)據(jù)線,釋放總線
- DS18B20_DQ_H;
- //等待15-60us,這里40us
- delay_us(40);
- //等待35us
- delay_us(35);
- //聆聽,判斷有沒有初始化成功(DS18B20有沒有發(fā)送應答脈沖)
- x = DS18B20_DQ_ReadPin;
- //至少480us后進入接收狀態(tài),這里500us
- delay_us(500);
- return x;
- }
- /*******************************************************************************
- 函數(shù)名:DS18B20_Wbyte
- 功能:寫一個字節(jié)
- 輸入:uint8_t xbyte
- 輸出:
- 返回值:
- 備注:
- *******************************************************************************/
- void DS18B20_Wbyte(uint8_t xbyte)
- {
- //i:循環(huán)控制變量,x:取位運算變量
- int8_t i ,x = 0;
- //改變DQ引腳為輸出
- DS18B20_DQ_DDR(1);
- //8次循環(huán)實現(xiàn)逐位寫入
- for(i = 1; i <= 8; i++)
- {
- //先取低位
- x = xbyte & 0x01;
- //寫1
- if(x)
- {
- DS18B20_DQ_H;
- //拉低總線
- DS18B20_DQ_L;
- //延時15us
- delay_us(15);
- //總線寫1
- DS18B20_DQ_H;
- //延時15us
- delay_us(15);
- //保持高電平
- DS18B20_DQ_H;
- delay_us(4);
- }
- //寫0
- else
- {
- DS18B20_DQ_H;
- //總線拉低
- DS18B20_DQ_L;
- //延時15us
- delay_us(15);
- //總線寫0
- DS18B20_DQ_L;
- //延時15us
- delay_us(15);
- //保持高電平
- DS18B20_DQ_H;
- delay_us(4);
- }
- //xbyte右移一位
- xbyte = xbyte >> 1;
- }
- }
- /*******************************************************************************
- 函數(shù)名:DS18B20_Rbit
- 功能:從DS18B20讀一個位
- 輸入:
- 輸出:
- 返回值:讀取到的位
- 備注:
- *******************************************************************************/
- uint8_t DS18B20_Rbit(void)
- {
- //rbit是最終位數(shù)據(jù),x是取狀態(tài)變量
- uint8_t rbit = 0x00,x = 0;
- //改變DQ為輸出模式
- DS18B20_DQ_DDR(1);
- DS18B20_DQ_H;
- //總線寫0
- DS18B20_DQ_L;
- //延時15us以內(nèi)
- delay_us(5);
- //釋放總線
- DS18B20_DQ_H;
- //改變DQ為輸入模式
- DS18B20_DQ_DDR(0);
- //延時大約3us
- delay_us(3);
- //獲取總線電平狀態(tài)
- x = DS18B20_DQ_ReadPin;
- //如果是1,則返回0x80,否則返回0x00
- if(x)
- rbit = 0x80;
- //延時大約60us
- delay_us(60);
- return rbit;
- }
- /*******************************************************************************
- 函數(shù)名:DS18B20_Rbyte
- 功能:從DS18B20讀一個字節(jié)
- 輸入:
- 輸出:
- 返回值:讀取到的字節(jié)
- 備注:
- *******************************************************************************/
- uint8_t DS18B20_Rbyte(void)
- {
- //rbyte:最終得到的字節(jié)
- //tempbit:中間運算變量
- uint8_t rbyte = 0,i = 0, tempbit =0;
- for (i = 1; i <= 8; i++)
- {
- //讀取位
- tempbit = DS18B20_Rbit();
- //右移實現(xiàn)高低位排序
- rbyte = rbyte >> 1;
- //或運算移入數(shù)據(jù)
- rbyte = rbyte|tempbit;
- }
- return rbyte;
- }
- int ReadTemperature(void)
- {
- //fg:符號位
- //data:溫度的整數(shù)部分
- int fg;
- int data;
- //DS18B20初始化
- DS18B20_Init();
- //跳過讀序列號
- DS18B20_Wbyte(0xcc);
- //啟動溫度轉(zhuǎn)換
- DS18B20_Wbyte(0x44);
- //等待溫度轉(zhuǎn)換
- delay_ms(1);
- DS18B20_Init();
- DS18B20_Wbyte(0xcc);
- //讀溫度寄存器
- DS18B20_Wbyte(0xbe);
- uint8_t TempL = DS18B20_Rbyte();//讀取低8位
- uint8_t TempH = DS18B20_Rbyte();//讀取高8位
- //符號位為負
- if(TempH > 0x70)
- {
- TempL = ~TempL;
- TempH = ~TempH;
- fg = 0;
- }
- else fg = 1;
-
- //將數(shù)據(jù)高低位合并
- data = TempH;//數(shù)據(jù)高八位
- data <<= 8;//左移8位
- data += TempL;//加上低八位
- //data的"1"相當于0.0625℃
- //換句話說,想要多少精度可以這樣寫:data=(float)data*0.0625*pow(10,n)
- //其中n為保留的小數(shù)精度位數(shù),可以從目前對ds18b20配置情況下看出最高保留小數(shù)的精度位數(shù)為4位
- //這樣只需要對返回值進行處理就可以用于顯示了
- //特別注意的是,int類型的數(shù)據(jù)長度為16位,最大值為65535,因此需要注意使用范圍
- data=(float)data*0.0625*pow(10,1);//這樣寫等同于下面一句
- //data = (float)data*0.625;//這樣相當于精度為0.1℃
- if(fg)
- return data;
- else
- return -data;
- }
復制代碼
51hei.png (2.51 KB, 下載次數(shù): 76)
下載附件
2020-12-19 17:13 上傳
所有資料51hei提供下載:
DS18B20.rar
(2.56 KB, 下載次數(shù): 101)
2020-12-19 16:55 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|