欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
stm32驅(qū)動ds18b20溫度讀取源程序
[打印本頁]
作者:
xu2509674896
時間:
2020-12-19 16:57
標題:
stm32驅(qū)動ds18b20溫度讀取源程序
發(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
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1