DS18B20驱动

合集下载

CC2530协议栈的DS18B20驱动

CC2530协议栈的DS18B20驱动

本驱动只适用于Zigbee协议栈中!!!一共两个文件:ds18b20.c和ds18b20.h ds18b20.c#include"iocc2530.h"#include"OnBoard.h"#include "ds18b20.h"#define Ds18b20IO P1_1 //温度传感器引脚void Ds18b20Delay(unsigned int k);void Ds18b20InputInitial(void);void Ds18b20OutputInitial(void);unsigned char Ds18b20Initial(void);void Ds18b20Write(unsigned char infor);unsigned char Ds18b20Read(void);//时钟频率为32Mvoid Ds18b20Delay(unsigned int k){while (k--){asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");}}void Ds18b20InputInitial(void)//设置端口为输入{P0DIR &= 0xfd;}void Ds18b20OutputInitial(void)//设置端口为输出{P0DIR |= 0x02;}//ds18b20初始化初始化成功返回0x00,失败返回0x01unsigned char Ds18b20Initial(void){unsigned char Status = 0x00;unsigned int CONT_1 = 0;unsigned char Flag_1 = 1;Ds18b20OutputInitial();Ds18b20IO = 1; //DQ复位Ds18b20Delay(260); //稍做延时Ds18b20IO = 0; //单片机将DQ拉低Ds18b20Delay(750); //精确延时大于480us 小于960usDs18b20IO = 1; //拉高总线Ds18b20InputInitial();//设置IO输入while((Ds18b20IO != 0)&&(Flag_1 == 1))//等待ds18b20响应,具有防止超时功能{ //等待约60ms左右CONT_1++;Ds18b20Delay(10);if(CONT_1 > 8000)Flag_1 = 0;Status = Ds18b20IO;}Ds18b20OutputInitial();Ds18b20IO = 1;Ds18b20Delay(100);return Status; //返回初始化状态}void Ds18b20Write(unsigned char infor){unsigned int i;Ds18b20OutputInitial();for(i=0;i<8;i++){if((infor & 0x01)){Ds18b20IO = 0;Ds18b20Delay(6);Ds18b20IO = 1;Ds18b20Delay(50);}else{Ds18b20IO = 0;Ds18b20Delay(50);Ds18b20IO = 1;Ds18b20Delay(6);}infor >>= 1;}}unsigned char Ds18b20Read(void){unsigned char Value = 0x00;unsigned int i;Ds18b20OutputInitial();Ds18b20IO = 1;Ds18b20Delay(10);for(i=0;i<8;i++){Value >>= 1;Ds18b20OutputInitial();Ds18b20IO = 0;// 给脉冲信号Ds18b20Delay(3);Ds18b20IO = 1;// 给脉冲信号Ds18b20Delay(3);Ds18b20InputInitial();if(Ds18b20IO == 1) Value |= 0x80;Ds18b20Delay(15);}return Value;}//温度读取函数unsigned char ReadDs18B20(void){unsigned char V1,V2; //定义高低8位缓冲unsigned char temp; //定义温度缓冲寄存器Ds18b20Initial();Ds18b20Write(0xcc); // 跳过读序号列号的操作Ds18b20Write(0x44); // 启动温度转换Ds18b20Initial();Ds18b20Write(0xcc); //跳过读序号列号的操作Ds18b20Write(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度V1 = Ds18b20Read(); //低位V2 = Ds18b20Read(); //高位temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据return temp;}//温度读取函数带1位小数位float floatReadDs18B20(void){unsigned char V1,V2; //定义高低8位缓冲unsigned int temp; //定义温度缓冲寄存器float fValue;Ds18b20Initial();Ds18b20Write(0xcc); // 跳过读序号列号的操作Ds18b20Write(0x44); // 启动温度转换Ds18b20Initial();Ds18b20Write(0xcc); //跳过读序号列号的操作Ds18b20Write(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度V1 = Ds18b20Read(); //低位V2 = Ds18b20Read(); //高位//temp = ((V1 >> 4)+((V2 & 0x07)*16)); //转换数据temp=V2*0xFF+V1;fValue = temp*0.0625;return fValue;}ds18b20.h#ifndef __DS18B20_H__#define __DS18B20_H__extern unsigned char Ds18b20Initial(void);extern unsigned char ReadDs18B20(void);extern float floatReadDs18B20(void);#endif。

温度传感器DS18B20驱动

温度传感器DS18B20驱动

]Linux下的ds18b20驱动原文地址:Linux下的ds18b20驱动作者:王宁运行环境 Fedora9.0交叉编译 arm-linux-gcc-4.3.2一.编译成模块#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/fs.h>#include <linux/init.h>#include <linux/miscdevice.h>#include <asm/irq.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>#include <asm/uaccess.h>#define DEVICE_NAME "DS18B20"#define DS18B20_MAJOR 250#define DS_PIN S3C2410_GPB1#define OUT S3C2410_GPB1_OUTP#define IN S3C2410_GPB1_INP#define DIS_UP 1#define EN_UP 0//#define Search 0x00F0#define Read_ROM 0x0033 //just for one#define Skip_ROM 0x00CC //ds18b20的固定时序,跳过读序号列号的操作#define Convert 0x0044 //ds18b20的固定时序,管脚识别到该信号是开始对测到的温度进行转换#define Write 0x004E //TH---TL---Config#define Read 0x00BE //读取温度寄存器等(共可读9个寄存器)前两个就是温度//#define bit_9 0x001F//#define bit_10 0x003F//#define bit_11 0x005F#define bit_12 0x007F#define uint16 unsigned int//unsigned int ROM_DATA[8];void usdelay(unsigned int i){unsigned int j;for(i=i;i>0;i--)for(j=90;j>0;j--);}void msdelay(unsigned int i) //延时 i ms{for(i=i;i>0;i--)usdelay(1000);}void SetL(void){s3c2410_gpio_cfgpin(DS_PIN,OUT);s3c2410_gpio_setpin(DS_PIN,0);}void SetH(void){s3c2410_gpio_cfgpin(DS_PIN,OUT);s3c2410_gpio_setpin(DS_PIN,1);}unsigned int Read_DS(void){unsigned int i;s3c2410_gpio_cfgpin(DS_PIN,IN);s3c2410_gpio_pullup(DS_PIN,EN_UP);__asm("nop");__asm("nop");__asm("nop");i=s3c2410_gpio_getpin(DS_PIN);if(i!=0)i=1;return i;}unsigned int ds_start(void) //初始化ds18b20{unsigned int flag=1;int err=0;SetH();udelay(2);SetL();udelay(600); //560延时要大于480uSetH();udelay(60); //稍作延时while(Read_DS()!=0) //ds18B20初始化成功会返回一个低电平,此时跳出循环,执行下面的操作{printk(DEVICE_NAME "Wait....n");udelay(5);err++; //初始化的最多次数吧,超过规定的次数,说明初始化失败 if(err==20){printk(DEVICE_NAME "start failn");return -1;}}//printk(DEVICE_NAME "start sucessn");flag=0;SetH();//初始化成功后赋为高电平准备从外界读入温度udelay(400);return flag;}void ds_send(unsigned int uidata) //向18b20写入一个字节的数据{//printk("the send data is %dn",uidata);int i;for(i=0;i<8;i++){SetL();udelay(1);if((uidata&1)!=0){SetH();udelay(80); //等待18b20进行数据采集}else{udelay(80); //等待18b20进行数据采集SetH();}uidata>>=1;}}unsigned int ds_read(void) //从18b20读一个字节的数据{unsigned int uidata=0;unsigned int i;for(i=0;i<8;i++){uidata>>=1;SetL();udelay(1);s3c2410_gpio_setpin(DS_PIN,1);s3c2410_gpio_cfgpin(DS_PIN,IN);udelay(10);if(s3c2410_gpio_getpin(DS_PIN))uidata=(uidata|0x80);udelay(65);SetH();}// printk("ds_read successn");return uidata;}unsigned int read_tem(void){unsigned int th,tl;//int err=0;//ds_init(100,0,bit_12);th=tl=0;ds_start();ds_send(Skip_ROM); //跳过读序号列号的操作ds_send(Convert); //启动温度转换mdelay(50);ds_start();ds_send(Skip_ROM); //跳过读序号列号的操作ds_send(Read); //准备读温度tl=ds_read();th=ds_read();th<<=8; //温度在低两个字节中//printk("the tl data is %dn",tl);tl|=th; //获取温度//printk("the th data is %dn",th);//printk("the tl2 data is %dn",tl);//printk("read_tmp successn");return tl;}static int ds18b20_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg){return 0;}static ssize_t ds18b20_read(struct file *pFile, uint16 __user *pData, size_t count, loff_t *off )uint16 tmp,ret;tmp =read_tem();// printk("the tmpk data is %dn",tmp);ret=copy_to_user(pData, &tmp, sizeof(tmp)); //将读取得的DS18B20数值复制到用户区if(ret>0){printk("copy data failedn");return -1;}//else// printk("copy data succesen");return 0;}static struct file_operations ds18b20_fops = {.owner = THIS_MODULE,.ioctl = ds18b20_ioctl,.read = ds18b20_read,};static int __init ds18b20_init(void){int ret;ret = register_chrdev(DS18B20_MAJOR, DEVICE_NAME, &ds18b20_fops);if (ret < 0) {printk(DEVICE_NAME " can't register major numbern");return ret;}s3c2410_gpio_cfgpin(DS_PIN, OUT);s3c2410_gpio_setpin(DS_PIN, 1);printk(DEVICE_NAME " initializedn");return 0;}static void __exit ds18b20_exit(void){unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME);printk(DEVICE_NAME " rmmodulen");}module_init(ds18b20_init);module_exit(ds18b20_exit);MODULE_AUTHOR("benjamin_xc@"); // 驱动程序的作者MODULE_DESCRIPTION("DS18B20 Driver"); // 一些描述信息MODULE_LICENSE("GPL");下面是将驱动编译成模块的过程:1.将编写好的驱动代码copy或move到你的内核驱动代码中,比如我的是FriendlyARM/mini2440/linux2.6.29/drivers/char2.编辑char目录下的Makefile文件,添加如下obj-m += 18b20.o 注意此处红色的部分要和你自己建的程序代码的文件名保持一致。

Linux下的ds18b20驱动

Linux下的ds18b20驱动
for(i=i;i>0;i--)
for(j=90;j>0;j--);
}
void msdelay(unsigned int i) //延时i ms
{
for(i=i;i>0;i--)
usdelay(1000);
}
void SetL(void)
{
s3c2410_gpio_cfgpin(DS_PIN,OUT);
int i;
for(i=0;i>=1;
}
}
unsignedint ds_read(void) //从18b20读一个字节的数据
{
unsigned int uidata=0;unsigned int i;
for(i=0;i>=1;
SetL();
udelay(1);
s3c2410_gpio_setpin(DS_PIN,1);
mdelay(50);
ds_start();
ds_send(Skip_ROM); //跳过读序号列号的操作
ds_send(Read); //准备读温度
tl=ds_read();
th=ds_read();
th0)
{
printk(copy data failed\n);
return -1;
}
//else
// printk(copy data succese\n);
flag=0;
SetH();//初始化成功后赋为高电平准备从外界读入温度
udelay(400);
return flag;
}
void ds_send(unsigned int uidata) //向18b20写入一个字节的数据

STM32下DS18B20驱动程序,适用于ucos系统

STM32下DS18B20驱动程序,适用于ucos系统
*/
#include "bsp.h"
HAL_DS18B20_T HAL_DS18B20;
/*********************************
硬件配置DATA:PC1
*********************************/
#define DS18B20GPIO GPIOA
#define DS18B20PIN GPIO_Pin_7
*形参:无
*返回值:无
*********************************************************************************************************
*/
int DS18B20_read_bit(void)
{
int ret;
return ret;
}
/*
*********************************************************************************************************
*函数名: DS18B20_write_byte
*功能说明: DS18B20写1个字节,低字节先写;
{
int i;
for(i=0; i<8; i++)
{
DS18B20_write_bit((data>>i)&0x01);
}
}
/*
*********************************************************************************************************

18b20在stm32上驱动并附18b20详细资料

18b20在stm32上驱动并附18b20详细资料
64 位光刻 rom:
光刻 rom 中的 64 位序列号是出厂前被光刻好的,它可以看作是该 ds18b20 的地址序列码。64 位光刻 rom 的排列是:开始 8 位(地址: 28h )是产品类 型标号,接着的 48 位是该 ds18b20 自身的序列号,并且每个 ds18b20 的序 列号都不相同,因此它可以看作是该 ds18b20 的地址序列码;最后 8 位则是 前面 56 位的循环冗余校验码( crc=x8+x5+x4+1 )。由于每一个 ds18b20 的 rom 数据都各不相同,因此微控制器就可以通过单总线对多个 ds18b20 进行寻 址,从而实现一根总线上挂接多个 ds18b20 的目的。
四、ds18b20 使用中注意事项 ............................................................................ 12 五、stm32 下 DS18B20 的驱动........................................................................... 14
三、DS18B20 工作流程
1.DS28B20 芯片 ROM 指令表:
Read ROM(读ROM)[33H] (方括号中的为16进制的命令字) 这个命令允许总线控制器读到DS18B20的64位ROM。只有当总 线上只存在一个DS18B20的时候才可以使用此指令,如果挂接 不只一个,当通信时将会发生数据冲突。
温度传感器的存储器
ds18b20 温度传感器的内部存储器包括一个高速暂存 ram 和一个非易失性 的可电擦除的 e2ram,后者存放高温度和低温度触发器 th 、tl 和结构寄存 器。数据先写入 ram,经校验后再传给 e2ram 。

DS18B20.h 温度传感器驱动

DS18B20.h 温度传感器驱动
DQ = dat&0x01;
Delay_us(66);
//Delay(5); //66us
DQ = 1;
dat>>=1;
}
EA=1;
}
unsigned int DS18B20_ReadTemperature(void)
{
unsigned char a=0;
{
unsigned char i=0;
unsigned char dat = 0;
EA=0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
Delay_us(56);
#ifndef __DS18B20_H__
#define __DS18B20_H__
#include "STC12C5A60S2.h"
#include "intrins.h"
unsigned char Array_Point[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
DQ = 1; //拉高总线
Delay_us(154);
//Delay(14); //154us
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
Delay_us(212);
//Delay(20); //212us
EA=1;
}
unsigned char DS18B20_ReadOneChar(void)

DS18B20驱动程序

DS18B20驱动程序作者: 嵌入式应用软件园目录第1章程序功能 (3)第2章程序代码 (4)第3章DS18B20简介 (11)3.1 DS18B20概述 (11)3.2 DS18B20的内部结构 (11)3.3 DS18B20温度传感器的存储器 (12)3.4 DS18B20使用中注意事项 (13)3.4 DS18B20常用命令详述 (14)DS18B20驱动程序DS18B20_MAIN,您可以直接在你的应用当中使用,直接返回温度的BCD码值。

BCD码值可以直接在数码管或LCD 上显示出来。

驱动程序中包含DS18B20温度传感器用到的全部函数。

如,DS18B20的复位函数(RESET_18B20)、写函数(WRITE_18B20)、读函数(READ_18B20),读出ROM中64的ID函数(READ_18B20ID),搜索DS18B20的ID函数(CHECK_18B20ID),警报搜索(ALARM_18B20ID)。

直接调用函数RE_TEMP,会返回当前的温度值。

再经过函数CONV_TEMP转换后,可以返回温度值的BCD码值。

我们的辛勤付出,需要您的肯定,请访问: 嵌入式应用软件园。

如需源代码/此代码技术支持,请访问: 嵌入式应用软件园。

第3章DS18B20简介3.1 DS18B20概述DS18B20 “一线总线”数字化温度传感器是DALLAS最新单线数字温度传感器,测量温度范围为-55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。

现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。

适合于恶劣环境的现场温度测量,支持3V~5.5V的电压范围,使系统设计更灵活、方便。

而且新一代产品更便宜,体积更小。

DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。

可选更小的封装方式,更宽的电压适用范围。

温度传感器DS18B20驱动程序

#include "ds18b20.h"#include <intrins.h>#if 0/*************************************************************************** *FUNCTION NAME: InitDS18b20*CREATE DATE: 2009/11/12*CREATED BY: XS*FUNCTION: 复位DS18B20和检测存在脉冲*MODIFY DATE: 2009/11/12*INPUT: 无**RETURN: 初始化成功,返回1,否则返回0***************************************************************************/ BOOL InitDs18b20(void){BOOL flag = FALSE;BIT bt;bt = ET0;ET0 = 0;DQ = 1;Delay70us(1); //稍作延时DQ = 0; // 复位Delay70us(8); //精确延时大于480usDQ = 1; //拉高总线,等待存在脉冲Delay70us(1); // 60-75us之间if(0==DQ){flag = TRUE;}Delay70us(8); // 复位后大于480us延时ET0 = bt;return flag;}/*************************************************************************** *FUNCTION NAME: ReadByte*CREATE DATE: 2009/11/12*CREATED BY: XS*FUNCTION: 从DS18B20中读取一个字节的数据*MODIFY DATE: 2009/11/12*INPUT: 无**RETURN: 读取的数据***************************************************************************/ UCHAR ReadByte(void){UCHAR i;UCHAR dat = 0;BIT bt;bt = ET0;ET0 = 0;for (i=0;i<8;i++){dat >>= 1;DQ = 0;Delay5us();DQ = 1;Delay5us();if(1==DQ){dat |=0x80;}Delay70us(1);}ET0 = bt;return(dat);}/*************************************************************************** *FUNCTION NAME: WriteByte*CREATE DATE: 2009/11/12*CREATED BY: XS*FUNCTION: 向DS18B20中写入一个字节的数据*MODIFY DATE: 2009/11/12*INPUT: 写入的数据**RETURN: 无***************************************************************************/ void WriteByte(UCHAR wDat){UCHAR i;BIT bt;bt = ET0;ET0 = 0;for (i=0; i<8; i++){DQ = 0;Delay5us();if((wDat & 0x01)!=0){DQ = 1;}else{DQ = 0;}Delay70us(1);DQ = 1;Delay5us();wDat >>= 1;}ET0 = bt;}/*************************************************************************** *FUNCTION NAME: ReadDs18b20*CREATE DATE: 2009/11/12*CREATED BY: XS*FUNCTION: 从DS18B20储存器中读取多字节数据*MODIFY DATE: 2009/11/12*INPUT: 读取数据存入的地址和需要读取数据的数量**RETURN: 无***************************************************************************/ void ReadScrat(UCHAR *prDat,UCHAR num){UCHAR i;for(i=0;i<num;i++){*prDat = ReadByte();prDat++;}}/*************************************************************************** *FUNCTION NAME: ReadTemp*CREATE DATE: 2009/11/12*CREATED BY: XS*FUNCTION: 读取温度*MODIFY DATE: 2009/11/12*INPUT: 读取的温度存入的地址**RETURN: 成功返回1,否则返回0***************************************************************************/ BOOL ReadTemp(float *prTemperature){UCHAR counter = 0;UCHAR tempBuff[9];float tempDat = 0;ClrWDT();while(1){if(InitDs18b20()){counter = 0;break;}else{counter++;if(counter>=ERR_COUNTER) // 连续3次初始化失败,即认为DS18B20出现故障{return 0;}}}WriteByte(SKIP_ROM); // 跳过读序号列号的操作WriteByte(CONVERT_T); // 启动温度转换Delay70us(20); // 延时至少500us,以供温度转换while(1){if(InitDs18b20()){counter = 0;break;}else{counter++;if(counter>=ERR_COUNTER) // 连续3次初始化失败,即认为DS18B20出现故障{return 0;}}}WriteByte(SKIP_ROM); //跳过读序号列号的操作WriteByte(READ_SCRAT); //读取温度寄存器等(共可读9个寄存器)ReadScrat(tempBuff, 9);if(0==CRC8(tempBuff,9)){if(0==(tempBuff[1]&0x80)) //为正温度{tempDat = (tempBuff[1]&0x07)*0x100 + tempBuff[0];}else{tempDat = ((0xFF-tempBuff[1])&0x07)*0x100 + (0x100-tempBuff[0]);tempDat = -tempDat;}*prTemperature = tempDat * 0.0625;return TRUE;}return FALSE;}/*************************************************************************** *FUNCTION NAME: GetDS18B20Temperature*CREATE DATE: 2009/8/17*CREATED BY: XS*FUNCTION: 采样3次求均值作为温度值*MODIFY DATE: 2009/8/17*INPUT: 温度储存的地址**RETURN: 正常为1,故障为0***************************************************************************/ BOOL GetDS18B20Temperature(float *pgTemperature){UCHAR i;UCHAR counter = 0;float tempDat = 0;float tempVal = 0;for(i=0;i<3;){if(ReadTemp(&tempDat)){tempVal += tempDat;counter = 0;i++;}else{counter++;if(counter>=ERR_COUNTER) //连续10次温度采样错误,则判断为故障,并返回{return FALSE;}}}*pgTemperature = tempVal / 3;// SendStr("boxTemp:");// print(*pgTemperature ,1);// SendChar('\n');return TRUE;}/****************************************************************************FUNCTION NAME: CRC8*CREATE DATE: 2009/8/17*CREATED BY: XS*FUNCTION: CRC效验*MODIFY DATE: 2009/8/17*INPUT: 需要效验的数据地址和个数**RETURN: 效验结果***************************************************************************/UCHAR CRC8(UCHAR *point,UCHAR CRClen) //效验成功则crc返回0{UCHAR i,j,crc_8,crcbuff;crc_8 = 0;for(i=0; i<CRClen; i++){crcbuff=*point++;for(j=0;j<8; j++){if(((crc_8 ^ crcbuff)&0x01)==0){crc_8 >>= 1;}else{crc_8 ^= 0x18;crc_8 >>= 1;crc_8 |= 0x80;}crcbuff >>= 1;}}return crc_8;}/*************************************************************************** *FUNCTION NAME: Delay5us*CREATE DATE: 2009/8/17*CREATED BY: XS*FUNCTION: 延时5us*MODIFY DATE: 2009/8/17*INPUT: 无**RETURN: 无***************************************************************************/ void Delay5us(void){// UCHAR i;// for(i=0;i<7;i++);_nop_();_nop_();}#endif/*************************************************************************** *FUNCTION NAME: Delay70us*CREATE DATE: 2009/8/17*CREATED BY: XS*FUNCTION: 延时70us*MODIFY DATE: 2009/8/17*INPUT: 次数**RETURN: 无***************************************************************************/ void Delay70us(UCHAR timers){UCHAR i,j;for(j=0;j<timers;j++){for(i=0;i<22;i++){// Delay5us();_nop_();_nop_();_nop_();}}}。

DS18B20驱动调试要点

如果要读或者写一个字节,就要重复以上的步骤八次。如以下的C代码,使用for循环,和数据变量的左移和或运算,
实现一个字节读与写。需要把握的一点就是代码里面的延时一定要是在DS18B20时序的允许范围内,因为DS18B20是一个对时序精度要求很高的器件。
/********************************************************************************
3.DS18B20拉低电平的60~240us之间,单片机读取总线的电平,如果是低电平,那么表示复位成功。
4.DS18B20拉低电平60~240us之后,会释放总线。
DS18B20复位C代码:
static void Ini tDS18B20(void)
{
DS18B20_INPUT;
SETDQ;
RESETDQ;
详细的芯片说明具体可参看Datasheet
2.
DS18B20一般都是充当从机的角色,而单片机就是主机。单片机通过一线总线访问DS18B20的话,需要经过以下
几个步骤:
1.DS18B20复位。
2.执行ROM指令。
3.执行DS18B20功能指令(RAM指令)。
一般我们都是使用单点,也就是说单线总线上仅有一个DS18B20存在而已。所以我们无需刻意读取ROM里边的
DS18B20写逻辑0的步骤如下:
1.单片机拉低电平大约10~15us。
2.单片机持续拉低电平大约20~45us的时间。
3.释放总线
DS18B20写逻辑1的步骤如下:
1.单片机拉低电平大约10~15us,。
2.单片机拉高电平大约20~45us的时间。
3.释放总线
DS18B20读逻辑0的步骤如下:

ds18b20驱动程序

/*包含了这么多的头文件,也不知道有的有没有用*/#include<linux/platform_device.h>#include<linux/delay.h>#include<linux/fs.h>#include<linux/module.h>#include<linux/kernel.h>#include<linux/uaccess.h>#include<linux/clk.h>#include<asm-arm/arch-s3c2410/regs-gpio.h>#include<asm/io.h>#include<asm/arch/map.h>#include<asm-arm/plat-s3c24xx/clock.h>#include<asm/arch/regs-clock.h>/*和引脚相关的宏定义*/#define DQ S3C2410_GPH9#define CFG_IN S3C2410_GPH9_INP#define CFG_OUT S3C2410_GPH9_OUTPstatic int opencount = 0;unsigned char init_ds(void)//ds18b20复位,返回0成功,返回1失败{unsigned char ret = 0;s3c2410_gpio_cfgpin(DQ, CFG_OUT);s3c2410_gpio_pullup(DQ, 0);s3c2410_gpio_setpin(DQ, 1);s3c2410_gpio_setpin(DQ, 0);udelay(500);s3c2410_gpio_setpin(DQ, 1);udelay(50);s3c2410_gpio_cfgpin(DQ, CFG_IN);udelay(200);ret = s3c2410_gpio_getpin(DQ);s3c2410_gpio_cfgpin(DQ, CFG_OUT);s3c2410_gpio_pullup(DQ, 0);s3c2410_gpio_setpin(DQ, 1);return ret;}void write_byte(char data)//向18b20写一个字节{char i = 0;s3c2410_gpio_cfgpin(DQ, CFG_OUT);s3c2410_gpio_pullup(DQ, 1);for(i=0; i<8; i++){s3c2410_gpio_setpin(DQ, 0);udelay(10);s3c2410_gpio_setpin(DQ, 1);s3c2410_gpio_setpin(DQ, data&0x01);udelay(60);s3c2410_gpio_setpin(DQ, 1);udelay(2);data >>= 1;}}unsigned char read_byte(void)//从18b20读一个字节{unsigned char i;unsigned char data=0;s3c2410_gpio_cfgpin(DQ, CFG_OUT);s3c2410_gpio_pullup(DQ, 0);for(i=0; i<8; i++){s3c2410_gpio_setpin(DQ, 0);udelay(1);s3c2410_gpio_setpin(DQ, 1);s3c2410_gpio_cfgpin(DQ, CFG_IN);udelay(10);data >>= 1;if(s3c2410_gpio_getpin(DQ))data |= 0x80;udelay(50);s3c2410_gpio_cfgpin(DQ, CFG_OUT);s3c2410_gpio_pullup(DQ, 0);s3c2410_gpio_setpin(DQ, 1);udelay(2);}return data;}/*文件的写函数,没有实际意义,用户不能写文件*/static ssize_t ds18b20_write(struct file*filp,const char*buffer, size_t count, loff_t *ppos){return 10;//随便返回一个正整数}/*18b20的读函数,读出的温度只保留了整数*/static ssize_t ds18b20_read(struct file*filp,char*buffer,size_t count, loff_t *ppos){unsigned char a=0, b=0;unsigned int t=0;unsigned char temp=0;unsigned char flag;flag = init_ds();if(flag&0x01)return-1;write_byte(0x0cc);write_byte(0x44);udelay(500);flag = init_ds();if(flag&0x01)return-1;write_byte(0x0cc);write_byte(0x0be);a = read_byte();b = read_byte();flag = init_ds();temp = ((b & 0x7) << 4)) | (a >> 4);copy_to_user(buffer,&temp, 1);return 1;}static int ds18b20_open(struct inode *node,struct file*file) {unsigned char flag;if(opencount == 1)return-EBUSY;flag = init_ds();if(flag&0x01){printk("uable to open device!/n");return-1;}else{opencount++;printk("device opened!/n");return 0;}}static int ds18b20_release(struct inode *node,struct file*file) {opencount--;printk("device released!/n");return 0;}static struct file_operations ds18b20_fops ={.owner = THIS_MODULE,.write= ds18b20_write,.read= ds18b20_read,.release = ds18b20_release,.open= ds18b20_open,};static int ds18b20_probe(struct platform_device *pdev){int ret;s3c2410_gpio_cfgpin(DQ, CFG_OUT);s3c2410_gpio_setpin(DQ, 0);ret = register_chrdev(0,"ds18b20",&ds18b20_fops);if(!ret)printk("--------------Uable to register driver!-------------------/n");printk("Probe for ds18b20 finished!/n");return 0;}static struct platform_driver ds18b20 ={.probe = ds18b20_probe,.driver ={.name ="s3c2410-ds",.owner = THIS_MODULE,},};int __init ds18b20_init(void){printk("Initial driver for ds18b20....................../n");return platform_driver_register(&ds18b20);}void __exit ds18b20_exit(void){return platform_driver_unregister(&ds18b20);}module_init(ds18b20_init);module_exit(ds18b20_exit);MODULE_AUTHOR("********************"); MODULE_DESCRIPTION("DS18B20 driver for s3c2410"); MODULE_LICENSE("GPL");。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

DS18B20驱动
一.概述
DS18B20是一种单总线数字温度传感器。

测试温度范围-55℃-125℃,温度数据位可配置为9、10、11、12位,对应的刻度值分别为0.5℃、0.25℃、0.125℃、0.0625℃,对应的最长转换时间分别为93.75ms、187.5ms、375ms、750ms。

出厂默认配置为12位数据,刻度值为0.0625℃,最长转换时间为750ms。

从以上数据可以看出,DS18B20数据位越低、转换时间越短、反应越快、精度越低。

单总线,意味着没有时钟线,只有一根通信线。

单总线读写数据是靠控制起始时间和采样时间来完成,所以时序要求很严格,这也是DS18B20驱动编程的难点。

需要注意的是,DS18B20和同一系列的DS18S20,在读写上,时序、命令一致,但因温度值存放的位置不一样,对温度数据的处理也不一样,所以程序不能直接套用。

二.电路设计
在WSF-51DB开发板上,利用AT89S52单片机的P1.1脚来驱动DS18B20,上拉电阻阻值为4.7K欧姆。

DS18B20的上拉电阻的阻值是一个需要注意的参数,如果DS18B20放置的位置离电路板较远,需要用较长的电缆来连接时,上拉电阻要相应减小,以弥补线路损耗,而且连接电缆要选用优质的三芯带屏蔽层的电缆,否则不能正常读写数据。

三.软件设计
/***************************************************************** *程序名称:DS18B20驱动
*程序功能:读写DS18B20,数码管显示温度值,温度值精度为0.1度。

*开发工具:WSF-51DB开发板
* MCU型号:AT89S52-24PU
*时钟频率:11.0592-12MHZ
*程序作者:吴师傅
*版权说明:吴师傅版权所有,转载请注明来源和作者。

*****************************************************************/#i nclude <reg52.h>
#i nclude <intrins.h>
unsigned char tempflag,fraction,tempr;
unsigned char code segmcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0 x7f,0x6f};
//共阴极数码管段码0-9 unsigned char code bitcode[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//8位共阴极数码管位码unsigned char code fractioncode[]={0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};
//将DS18B20的小数部分的0-f刻度转换为0-9刻度的查找表,将精度化为0. 1度
sbit ser=P2^0;//74HC595串行数据输入
sbit oe=P2^1;//74HC595使能
sbit rclk=P2^2; //74HC595数据锁存
sbit srclk=P2^3;// 74HC595串行时钟
sbit DQ=P1^1; //温度总线
//延时函数(12MHZ晶振):
void Delayus(unsigned char t)
{ //此函数精确计算:18+6*(t-1)=延时时间(us)
while(t--);
}
//延时ms延时函数:
void Delayms(unsigned int t)
{
unsigned int i,j;
for(i=t;i>0;i--)
for(j=0;j<120;j++);
}
//任意位数码管显示一个字符函数:
void DTDisplayChar(unsigned char segmd,unsigned char bitd )//数码管段码和数码管位码
{
unsigned char i;
unsigned int dat;
oe=1;//输出为高阻
dat=bitd;
dat=dat<<8|segmd; //位码段码合并为一个int型数据
for(i=0;i<16;i++)//16位数据从高位依次移入74HC595
{
ser=(dat&0x8000)?1:0; //判断最高位,为真取1,为假取0
srclk=1; //上升沿送数据
srclk=0;
dat<<=1; //左移取下一位
}
rclk=1;//74HC595锁存数据
rclk=0;
oe=0;//输出数据
}
//DS18B20复位函数:
void Reset18B20(void)
{
DQ=0;//拉低,开始复位操作
Delayus(100);//延时至少480us
DQ=1;//拉高,释放总线控制权
while(DQ);//等待器件应答(器件拉低),约15-60us后
while(!DQ);//应答脉冲出现后,等待器件拉高,约60-240us后}
//DS18B20写命令函数:
void Write18B20(unsigned char com)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ=0;//开始写操作
_nop_(); _nop_();//至少延时1us
DQ=com&0x01;//写数据
Delayus(2);//延时,器件在45us内采样
DQ=1;//释放总线控制权
com>>=1; //右移1位,写下一位
}
}
//DS18B20读数据函数:
unsigned char Read18B20()
{
unsigned char i,rdata=0;
for(i=0;i<8;i++)
{
DQ=0;//开始读操作
_nop_();_nop_();//至少延时1us
DQ=1;//释放总线控制权,15us内要读取数据
if(DQ==1) rdata|=0x01<<i;
Delayus(10);//延时要大于45us.读0时,45us后器件才拉高总线
}
return rdata;
}
//读出温度函数:
void Read18B20Temperature()
{
unsigned char templ,temph,temp;
unsigned int tempv;
Reset18B20();//复位
Write18B20(0xcc);//写命令,跳过ROM编码命令
Write18B20(0x44);//转换命令
while(!DQ);//等待转换完成
Reset18B20();//复位
Write18B20(0xcc);//写命令,跳过ROM编码命令
Write18B20(0xbe);//读取暂存器字节命令
templ=Read18B20();//读低字节
temph=Read18B20();//读高字节
Reset18B20();//复位
tempv=temph;
tempv=tempv<<8|templ;//两个字节合并为一个int型数据
temp=(unsigned char)(tempv>>4);//去掉小数部分,化成char型数据
if((temph&0x80)==0x80)//如果是负温度
{
tempflag=1; //负号显示
tempr=~temp+1; //实际温度值为读取值的补码
fraction=fractioncode[(~templ+1)&0x0f];
//取小数部分补码,将16刻度转换为10刻度,精度为0.1度}
else//如果是正温度
{
tempflag=0;//正温度,负号不显示
tempr=temp;//
fraction=fractioncode[templ&0x0f];
//取小数部分,将16刻度转换为10刻度,精度为0.1度}
}
//主函数:
int main(void)
{
tempflag=0;
while(1)
{
Read18B20Temperature();//读取温度值
DTDisplayChar(segmcode[fraction],0x7f);//显示小数部分
Delayms(1);
DTDisplayChar(segmcode[tempr%10]|0x80,0xbf);//显示个位和小数点
Delayms(1);
DTDisplayChar(segmcode[tempr%100/10],0xdf);//显示十位Delayms(1);
if(tempflag==1) DTDisplayChar(0x40,0xef);//如果是负温度就显示“-”
else DTDisplayChar(segmcode[tempr/100],0xef);//显示百位
Delayms(1);
DTDisplayChar(0xff,0xff);//均衡数码管亮度
}
return 0;
}。

相关文档
最新文档