【摘要】 當前文章介紹如何在Linux系統(tǒng)下編寫一個DS18B20溫度傳感器驅(qū)動,測量環(huán)境溫度,并將DS18B20注冊成字符設(shè)備,通過文件接口將溫度數(shù)據(jù)傳遞給應(yīng)用層。
1. 前言
當前文章介紹如何在Linux系統(tǒng)下編寫一個DS18B20溫度傳感器驅(qū)動,測量環(huán)境溫度,并將DS18B20注冊成字符設(shè)備,通過文件接口將溫度數(shù)據(jù)傳遞給應(yīng)用層。
當前使用的開發(fā)板是友善之臂的Tiny4412開發(fā)板,CPU是三星的Exynos-4412,主頻是4核1.5GHZ,當前運行的Linux內(nèi)核版本是3.5。使用的溫度傳感器是DS18B20,是一個數(shù)字溫度傳感器,非常經(jīng)典的一款溫度傳感器,常年應(yīng)用在各大高校畢設(shè)、實驗室、畢設(shè)、課設(shè)場景。DS1820接線比較簡單,只需要一根線就行,加上兩根電源線,一共3根線,并且DS18B20支持硬件序列號尋址,支持一個IO口上掛載多個DS18B20。
2. DS18B20介紹
DS18B20特性:
(1)全數(shù)字溫度轉(zhuǎn)換及輸出。
(2)先進的單總線數(shù)據(jù)通信。
(3)最高 12 位分辨率,精度可達土 0.5 攝氏度。
(4)12 位分辨率時的最大工作周期為 750 毫秒。
(5)可選擇寄生工作方式。
(6)檢測溫度范圍為–55° C ~+125° C (–67° F ~+257° F)
(7)內(nèi)置 EEPROM,限溫報警功能。
(8)64 位光刻 ROM,內(nèi)置產(chǎn)品序列號,方便多機掛接。
(9)多樣封裝形式,適應(yīng)不同硬件系統(tǒng)。
![image-20220102202650673](https://file.elecfans.com//web2/M00/6A/5A/poYBAGMlQOKAKM_UAAFHggQ-2gY273.png)
DS18B20引腳功能
GND 電壓地
DQ 單數(shù)據(jù)總線
VDD 電源電壓
NC 空引腳
DS18B20讀取溫度的步驟:
發(fā)送復(fù)位信號-->
檢測回應(yīng)信號--->
發(fā)送0xCC-->發(fā)送0x44->
發(fā)送復(fù)位信號—>
檢測回應(yīng)信號—>
寫0xcc--->
寫0xbe--->
循環(huán)8次讀取溫度低字節(jié)--->
循環(huán)8次讀取溫度高字節(jié)---->
打印溫度信息
DS18B20溫度轉(zhuǎn)換示例:
u16 temp;
u8 TL,TH;
u16 intT,decT; //溫度值的整數(shù)和小數(shù)部分
TL=DS18B20_Read_Byte(); //讀取溫度低8位LSB
TH=DS18B20_Read_Byte(); //讀取溫度高8位MSB
temp=((u16)TH<<8)|TL; //將讀出的溫度高低位組合成16位的值
intT = temp >> 4; //分離出溫度值整數(shù)部分
decT = temp & 0xF; //分離出溫度值小數(shù)部分
printf("A: %d.%d\r\n",(int)intT,(int)decT); //打印實際溫度值
3. 硬件接線圖
Tiny4412開發(fā)板擴展GPIO口:
![image-20220102203315453](https://file.elecfans.com//web2/M00/6A/5A/poYBAGMlQOSAR364AAGHH_WPUvk960.png)
![image-20220102203906312](https://file.elecfans.com//web2/M00/6A/5A/poYBAGMlQOiAY488AAfzlzhz8XU114.png)
![image-20220102203919777](https://file.elecfans.com//web2/M00/6A/F1/pYYBAGMlQO6ALZVvAAiQYROyi5Y617.png)
4. 示例代碼
#include
#include
#include /*雜項字符設(shè)備頭文件*/
#include /*文件操作集合*/
#include /*延時函數(shù)*/
#include
#include
/*DS18B20 GPIO接口: GPB_4*/
/*定義指針,用于接收虛擬地址*/
volatile unsigned int *DS18B20_GPBCON;
volatile unsigned int *DS18B20_GPBDAT;
#define DS18B20_INPUT() {*DS18B20_GPBCON &= ~(0xf << 4 * 4);}
#define DS18B20_OUTPUT() {*DS18B20_GPBCON &= ~(0xf << 4 * 4);*DS18B20_GPBCON |= (0x1 << 4 * 4);}
/*
函數(shù)功能:等待DS18B20的回應(yīng)
返回1:未檢測到DS18B20的存在
返回0:存在
*/
unsigned char DS18B20_Check(void)
{
unsigned char retry=0;
DS18B20_INPUT() ///SET PG11 INPUT
while((*DS18B20_GPBDAT & (1 << 4))&&retry<200)
{
retry++;
udelay(1);
};
if(retry>=200)return 1;
else retry=0;
while(!(*DS18B20_GPBDAT & (1 << 4))&&retry<240)
{
retry++;
udelay(1);
};
if(retry>=240)return 1;
return 0;
}
/*
從DS18B20讀取一個位
返回值:1/0
*/
unsigned char DS18B20_Read_Bit(void) // read one bit
{
unsigned char data;
DS18B20_OUTPUT();
*DS18B20_GPBDAT &= ~(1 << 4);//輸出0
udelay(2);
*DS18B20_GPBDAT |= (1 << 4);//輸出1
DS18B20_INPUT()
udelay(12);
if((*DS18B20_GPBDAT & (1 << 4)))data=1;
else data=0;
udelay(50);
return data;
}
/*
從DS18B20讀取一個字節(jié)
返回值:讀到的數(shù)據(jù)
*/
unsigned char DS18B20_Read_Byte(void) // read one byte
{
unsigned char i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=DS18B20_Read_Bit();
dat=dat>>1;
if(j) //主機對總線采樣的數(shù) 判斷-------讀數(shù)據(jù)-1就是1,否則就是0
dat|=0x80; //先收低位數(shù)據(jù)--一步一步向低位移動>>
}
return dat;
}
/*
寫一個字節(jié)到DS18B20
dat:要寫入的字節(jié)
*/
void DS18B20_Write_Byte(unsigned char dat)
{
unsigned char j;
unsigned char testb;
DS18B20_OUTPUT();
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)
{
*DS18B20_GPBDAT &= ~(1 << 4);//輸出0// Write 1
udelay(2);
*DS18B20_GPBDAT |= (1 << 4);//輸出1
udelay(60);
}
else
{
*DS18B20_GPBDAT &= ~(1 << 4);//輸出0// Write 0
udelay(60);
*DS18B20_GPBDAT |= (1 << 4);//輸出1
udelay(2);
}
}
}
/*
從ds18b20得到溫度值
精度:0.1C
返回值:溫度值 (-550~1250)
*/
short DS18B20_Get_Temp(void)
{
unsigned short aaa;
unsigned char temp;
unsigned char TL,TH;
DS18B20_OUTPUT();
*DS18B20_GPBDAT &= ~(1 << 4);//輸出0 //拉低DQ
udelay(750); //拉低750us
*DS18B20_GPBDAT |= (1 << 4);//輸出1 //DQ=1
udelay(15); //15US
DS18B20_Check();
DS18B20_Write_Byte(0xcc);
DS18B20_Write_Byte(0x44);
DS18B20_OUTPUT();
*DS18B20_GPBDAT &= ~(1 << 4);//輸出0 //拉低DQ
udelay(750); //拉低750us
*DS18B20_GPBDAT |= (1 << 4);//輸出1 //DQ=1
udelay(15); //15US
DS18B20_Check();
DS18B20_Write_Byte(0xcc);// skip rom
DS18B20_Write_Byte(0xbe);// convert
TL=DS18B20_Read_Byte(); // LSB
TH=DS18B20_Read_Byte(); // MSB
aaa=((unsigned short)TH<<8)|TL;
return aaa;
}
/*
雜項字符設(shè)備注冊示例----->DS18B20
*/
static int tiny4412_open(struct inode *my_inode, struct file *my_file)
{
/*映射物理地址*/
DS18B20_GPBCON=ioremap(0x11400040,4);
DS18B20_GPBDAT=ioremap(0x11400044,4);
printk("DS18B20初始化成功!\r\n");
/*設(shè)置ds18b20為輸出模式*/
*DS18B20_GPBCON &= ~(0xf << 4 * 4);
*DS18B20_GPBCON |= (0x1 << 4 * 4);
return 0;
}
static int tiny4412_release(struct inode *my_inode, struct file *my_file)
{
/*釋放虛擬地址*/
iounmap(DS18B20_GPBCON);
iounmap(DS18B20_GPBDAT);
printk("DS18B20釋放成功\r\n");
return 0;
}
static ssize_t tiny4412_read(struct file *my_file, char __user *buf, size_t len, loff_t *loff)
{
/*讀取溫度信息*/
short temp=DS18B20_Get_Temp();
copy_to_user(buf,&temp,2); //拷貝溫度至應(yīng)用層
return 0;
}
static ssize_t tiny4412_write(struct file *my_file, const char __user *buf, size_t len, loff_t *loff)
{
return 0;
}
/*文件操作集合*/
static struct file_operations tiny4412_fops=
{
.open=tiny4412_open,
.read=tiny4412_read,
.write=tiny4412_write,
.release=tiny4412_release
};
/*
核心結(jié)構(gòu)體
*/
static struct miscdevice tiny4412_misc=
{
.minor=MISC_DYNAMIC_MINOR, /*自動分配次設(shè)備號*/
.name="DS18B20", /*設(shè)備文件,指定/dev/生成的文件名稱*/
.fops=&tiny4412_fops
};
static int __init DS18B20_dev_init(void)
{
/*雜項設(shè)備注冊*/
misc_register(&tiny4412_misc);
return 0;
}
static void __exit DS18B20_dev_exit(void)
{
/*雜項設(shè)備注銷*/
misc_deregister(&tiny4412_misc);
}
module_init(DS18B20_dev_init);
module_exit(DS18B20_dev_exit);
MODULE_LICENSE("GPL");
-
溫度傳感器
+關(guān)注
關(guān)注
48文章
2975瀏覽量
156388 -
驅(qū)動
+關(guān)注
關(guān)注
12文章
1851瀏覽量
85646 -
DS18B20
+關(guān)注
關(guān)注
10文章
780瀏覽量
81120
發(fā)布評論請先 登錄
相關(guān)推薦
基于FPGA的溫度傳感器(ds18b20)驅(qū)動設(shè)計
![基于FPGA的溫度傳感器(<b class='flag-5'>ds18b20</b>)<b class='flag-5'>驅(qū)動</b>設(shè)計](https://file1.elecfans.com/web3/M00/06/3D/wKgZO2eIormAOWczAAAXbuN3_4g281.jpg)
《DNESP32S3使用指南-IDF版_V1.6》第二十九章 DS18B20實驗
CW32模塊使用 DS18B20溫度傳感器
![CW32模塊使用 <b class='flag-5'>DS18B20</b>溫度傳感器](https://file1.elecfans.com//web3/M00/00/03/wKgZO2dFmReAH7XGAAA_DkdnFNs959.jpg)
ds18b20傳感器的使用方法
ds18b20溫度傳感器怎么接線
ds18b20溫度傳感器如何使用
ds18b20溫度傳感器是什么類型
ds18b20溫度傳感器和dht11的區(qū)別
STC32和STC8H驅(qū)動DS18B20測溫串口發(fā)送數(shù)據(jù)
![STC32和STC8H<b class='flag-5'>驅(qū)動</b><b class='flag-5'>DS18B20</b>測溫串口發(fā)送數(shù)據(jù)](https://file1.elecfans.com/web2/M00/F3/A4/wKgZomZ9IZyAbWtfAANlMQJiQrg121.jpg)
評論