非常好的18B20驱动程序
温度传感器18B20驱动程序(C语言)
温度传感器18B20驱动程序(C语言)我精心整理的一个温度传感器18B20的程序包,可直接调用这个程序适用于12MHz晶振的51单片机,默认为89C52系列,如果是89C51的话,把头文件改为#include "reg51.h"就可以了,下面是头文件和C文件,大家在工程里加入C文件,在主程序中加入头文件,直接调用read_temp();函数,就可以返回浮点型的温度值,为10进制,可以处理后直接用LCD或数码管显示,很方便,是我做温控的子程序。
/*************头文件******************/#include "reg52.h"#include "intrins.h" //_nop_();延时函数用#define uchar unsigned char#define uint unsigned intsbit DQ="P3"^4; //温度输入口ow_reset(void);//18B20复位void write_byte(uchar val);//写命令uchar read_byte(void);//读数据/***********读出温度函数**********输入:无输出:zs+xs,格式为123.4即为浮点型数的温度格式===================================*/float read_temp();/***************C文件**********************/#include "reg52.h"#include "18B20.h" //_nop_();延时函数用//*******温度小数部分用查表法**********//uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; /***********11微秒延时函数**********///void delay(uint t){for(;t>0;t--);}///***********18B20复位函数**********/ow_reset(void){char presence="1";while(presence){while(presence){DQ=1;_nop_();_nop_();DQ=0; //delay(50); // 550usDQ=1; //delay(6); // 66uspresence=DQ; // presence="0继续下一步"}delay(45); //延时500uspresence = ~DQ;}DQ=1;}/////**********18B20写命令函数*********///向 1-WIRE 总线上写一个字节void write_byte(uchar val){uchar i;for (i=8; i>0; i--) //{DQ=1;_nop_();_nop_();DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us DQ = val&0x01; //最低位移出delay(6); //66usval=val/2; //右移一位}DQ = 1;delay(1);}///*********18B20读1个字节函数********///从总线上读取一个字节uchar read_byte(void){uchar i;uchar value = 0;for (i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ = 0; //_nop_();_nop_();_nop_();_nop_(); //4usDQ = 1;_nop_();_nop_();_nop_();_nop_(); //4usif(DQ)value|=0x80;delay(6); //66us}DQ=1;return(value);}///***********读出温度函数**********输入:无输出:zs+xs,格式为123.4即为浮点型数的温度格式===================================*/ //float read_temp(){float zs,xs;//存放整数和小数uchar temp_data[2];//读出温度暂存EA=0;//禁止中断,防止读错ow_reset(); //总线复位write_byte(0xCC); // 发Skip ROM命令write_byte(0xBE); // 发读命令temp_data[0]=read_byte(); //温度低8位temp_data[1]=read_byte(); //温度高8位ow_reset();write_byte(0xCC); // Skip ROMwrite_byte(0x44); // 发转换命令xs=ditab[temp_data[0]&0x0f];//小数位xs=xs/10;zs=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);//整数位return (zs+xs);EA=1;//开中断}//结束当然,大家做数字温度计的话直接使用这个程序就可以了,但是如果要做多点温控的话,大家还要自己写查找序列号的程序!加油!/************************************************************ *18B20驱动程序,DQ为数据口,接于P2.1*11.0592M晶振,上拉4.7k电阻*Author:fyb*2005-3-25 11:23,OK!*************************************************************/ #i nclude<reg51.h>#i nclude<intrins.h>#define uchar unsigned char#define uint unsigned intsbit dq = P1^7;bit flag;uint Temperature;uchar temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节uchar id_buff[8];uchar *p;uchar crc_data;uchar code CrcTable [256]={0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62 , 96, 130, 220,35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 12 8, 222, 60, 98,190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29 , 67, 161, 255,70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, 140, 210,48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 2 05,17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 2 38,50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 1 45, 207, 45, 115,202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 2 44, 170, 72, 22,233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 2 15, 137, 107, 53};///************************************************************ *Function:延时处理*parameter:*Return:*Modify:*************************************************************/ void TempDelay (uchar us){while(us--);}/************************************************************ *Function:18B20初始化*parameter:*Return:*Modify:*************************************************************/ void Init18b20 (void){dq=1;_nop_();dq=0;TempDelay(86); //delay 530 uS//80_nop_();dq=1;TempDelay(14); //delay 100 uS//14_nop_();_nop_();_nop_();if(dq==0)flag = 1; //detect 1820 success!elseflag = 0; //detect 1820 fail!TempDelay(20); //20_nop_();_nop_();dq = 1;}/************************************************************ *Function:向18B20写入一个字节*parameter:*Return:*************************************************************/ void WriteByte (uchar wr) //单字节写入{uchar i;for (i=0;i<8;i++){dq = 0;_nop_();dq=wr&0x01;TempDelay(5); //delay 45 uS //5_nop_();_nop_();dq=1;wr >>= 1;}}/************************************************************ *Function:读18B20的一个字节*parameter:*Return:*Modify:*************************************************************/ uchar ReadByte (void) //读取单字节{uchar i,u=0;for(i=0;i<8;i++){dq = 0;u >>= 1;if(dq==1)u |= 0x80;TempDelay (4);_nop_();}return(u);}/************************************************************ *Function:读18B20*parameter:*Return:*Modify:*************************************************************/ void read_bytes (uchar j){uchar i;for(i=0;i<j;i++){*p = ReadByte();p++;}}/************************************************************ *Function:CRC校验*parameter:*Return:*Modify:*************************************************************/ uchar CRC (uchar j)uchar i,crc_data=0;for(i=0;i<j;i++) //查表校验crc_data = CrcTable[crc_data^temp_buff[i]];return (crc_data);}/************************************************************ *Function:读取温度*parameter:*Return:*Modify:*************************************************************/ void GemTemp (void){read_bytes (9);if (CRC(9)==0) //校验正确{Temperature = temp_buff[1]*0x100 + temp_buff[0];// Temperature *= 0.625;Temperature /= 16;TempDelay(1);}}/************************************************************ *Function:内部配置*parameter:*Return:*Modify:*************************************************************/ void Config18b20 (void) //重新配置报警限定值和分辨率Init18b20();WriteByte(0xcc); //skip romWriteByte(0x4e); //write scratchpadWriteByte(0x19); //上限WriteByte(0x1a); //下限WriteByte(0x7f); //set 11 bit (0.125)Init18b20();WriteByte(0xcc); //skip romWriteByte(0x48); //保存设定值Init18b20();WriteByte(0xcc); //skip romWriteByte(0xb8); //回调设定值}/************************************************************ *Function:读18B20ID*parameter:*Return:*Modify:*************************************************************/ void ReadID (void)//读取器件 id{Init18b20();WriteByte(0x33); //read romread_bytes(8);}/************************************************************ *Function:18B20ID全处理*parameter:*Return:*Modify:*************************************************************/ void TemperatuerResult(void){p = id_buff;ReadID();Config18b20();Init18b20 ();WriteByte(0xcc); //skip romWriteByte(0x44); //Temperature convertInit18b20 ();WriteByte(0xcc); //skip romWriteByte(0xbe); //read Temperaturep = temp_buff;GemTemp();}。
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);
}
}
/*
*********************************************************************************************************
12864 18b20好使的C程序
void LCDSendWord(unsigned char *p) //向LCD发送一个字符串,
{
while(*p>0) //比如void LCDSendWord('你好');就是让LCD显示"你好"
{
WriteDataLCD(*p);
uchar TX=0; //转换后的温度值小数部分 //DS18B20的数据线
void delay(uint x);
void reset (void);
void write(uchar val);
uchar read(void);
Delay(5);
}
/******************给LCD写入指令**********************/
void WriteCommandLCD(unsigned char WCLCD) //BuysC为0时忽略忙检测
{
CheckBusy(); //检测忙
void LCDTestWord(bit i,unsigned char word);
void Delay(unsigned char num);
/**********定义温度传感器DS18B20的数据线和相关函数*************/
sbit DQ=P2^7;
char TZ=0; //转换后的温度值整数部分
val=val>>1;
}
}
uchar read(void) //18b20读字节
{
uchar i,d=0;
uchar value=0; //读t;0;i--)
DS18B20 arm驱动程序
dat=(j>1);
}
returndat;
}
voidDS18B20_writebyte(unsignedchardat)
{
unsignedinti;
unsignedcharj;
for(i=1;i{
j=dat&0x01;
dat=dat>>1;
if(j)
{
#include
#include
#include
#include
#defineDEVICE_NAMEDS18B20
#defineDS18B20_MAJOR231
#defineDQS3C2410_GPG0
#defineCLKS3C2410_GPB0
#defineW1S3C2410_GPH9
#defineW2S3C2410_GPE10
s3c2410_gpio_cfgpin(DQ,OUT);
s3c2410_gpio_setpin(DQ,LOW);
udelay(10);
s3c2410_gpio_setpin(DQ,HIGH);
udelay(45);
}
else
{
s3c2410_gpio_cfgpin(DQ,OUT);
s3c2410_gpio_setpin(DQ,LOW);
udelay(15);
s3c2410_gpio_cfgpin(DQ,IN);
bit=s3c2410_gpio_getpin(DQ);
udelay(45);
returnbit;
}
unsignedcharDS18B20_readbyte(void)
51单片机写DS18B20的驱动
51单片机写DS18B20的驱动初始化操作方法:单片机先给总线一个高电平,略微延时,然后拉低总线,至少延时480us(我们取600us),然后拉高总线,等待15~60us 的时间(我们取80us),此后DS18B20 如果响应,则会发出0,拉低总线,否则为1,单片机检测是否响应的时间在60~240us 之内,之后释放总线,程序如下:bitDS18B20_init()//初始化{uchar i;bit flag_response=0;DQ=1;_nop_();_nop_();DQ=0;delay_us(90); //延时600usDQ=1;delay_us(10); //延时80usfor(i=0;i{_nop_();_nop_();_nop_();_nop_(); _nop_();if(!DQ){ flag_response=1;break;}}delay_us(63);//延时420usDQ=1;//释放总线return(flag_response);}写操作方法:由于是单总线,读写操作都分为写0 和写1,从一个字节的最低位逐次往DS18B20 里写,先使总线产生一个由1 到0 的跳变,等待15us(我们取13us),然后判断要写的那位是1 还是0,如果是1,则拉高总线,0 则不去操作总线(因为总线开始产生跳变时已被拉低),等待45us(我们取64us)以后释放总线(这段时间DS18B20 会采样,如上图所示),程序如下:void DS18B20_write(uchar dat)//写1 个字节{uchar i;for(i=0;i{DQ=1;_nop_(); _nop_();DQ=0;delay_us(1);//延时13usif(dat&0x01)DQ=1;delay_us(8);//延时64usDQ=1;//释放总线dat>>=1;}}读操作方法:使总线产生一个由1 到0 的跳变,等待1us,马上拉高总线,等待大约12 个us(datasheet 推荐的采样时间是快接近15us 的时候,我们略微提前),单片机采样,如果总线被拉低,则读出的是0,否则就读出1,然后延。
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驱动程序
DS18B20_SET_OUT(); DS18B20_DelayUs(90); if( DS18B20_READ_IN() ) rBit = 1; else rBit = 0; if( gIE ) // 恢复当前全局中断的状态 __enable_interrupt(); DS18B20_DelayUs(200); DS18B20_DelayUs(200); $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$ ** DS18B20 读位函数 ** 注意: (1)时序的准确性 (2)开关全局中断 */ static BOOLEAN DS18B20_ReadBit(void) { BOOLEAN rBit; BOOLEAN gIE = 0; if( __get_SR_register() & GIE ) // 保存当前全局中断的状态 {
#define COM_MEM_COPY_SCR 0X48 #define COM_MEM_RECALL_E 0XB8 #define COM_MEM_READ_POWER 0XB4 /*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$ ** US 延迟函数 ** 注意:必须根据不同的 MCU、晶体频率而做更改 */ static void DS18B20_DelayUs(INT8U us) // @8MHZ { for(; us>0; us--) {
gIE = 1; __disable_interrupt(); } DS18B20_CLR_OUT(); DS18B20_DelayUs(4); DS18B20_SET_OUT(); DS18B20_DelayUs(4); if( DS18B20_READ_IN() ) rBit = 1; else rBit = 0; DS18B20_DelayUs(60); if( gIE ) // 恢复当前全局中断的状态
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");。
51单片机驱动DS18B20温度传感器程序及心得
51单片机驱动DS18B20温度传感器程序及心得关于DS18B20温度传感器,在没有硬件设备的辅助下,写内部程序有些困难,因为看不到实际信号波形。
对于单片机,我。
渐渐的有些心灰意冷。
虽然掌握了1_WIRE总线,却少了很多喜悦,下雨了。
它是我的爱好,我付出了很多,可是我看不到实际的前景。
以我个人之力,要步入尖端芯片领域,很困难,在这里,采棉花是个普遍性的大问题,大型机械设备缺陷很多,如果以微控制芯片提高精度,我想效益会相当可观,可是技术瓶颈难以逾越。
硬件研发,失败了,所有投入赴之东流,成功了,回报丰厚。
现在,各行各业都处于饱和,没有成熟先进的技术,很难有立足之地,,,,,我开始重新审视我的选择。
艰难。
/*建立时间: 2013年5月2日;前言: 我用软件仿真,测算延时时间,效果不错,但是根据教程,复位时,先释放总线(wd高电平),然后主机拉低wd,持续时间为400--960微妙.后主机拉高wd,持续15-60微妙,后从机,会拉低电平持续时间是60--240微妙(此时表示复位成功),如果从机没有将总线拉低,则复位失败.然后,主机拉高电平60--240微妙.复位结束;可,实验证明,在,从机,拉低总线电平后,持续一定时间,从机还会将总线拉高!这是教程中的一个重大错误!temperature sensor reset module finishing time: 23:08:00(温度传感器复位模块完成时间 )temperature sensor 操作过程:1. reset DS18B20;2. 发出Skip ROM 命令(CCH); (跳跃ROM命令)3. 发出Convert T命令(44H); (温度转换命令)4. reset DS18B20;5. 发出Skip ROM命令(CCH);(跳跃ROM命令)6. 发出读取命令(BEH);7. 读出两个字节的温度;8. 温度格式转换;2013年5月8日22:56:44DS18B20 Temperature sensor read data module accomplish;(温度传感器读数据模块完成)现在还有温度显示模块没有完成,硬件是1602液晶屏......2013年5月9日19:32:31今天,温度传感器的程序主体结构全部完成!!!!! 不容易啊,值得庆祝一下!!!!!!一共写了7天程序!{陆陆续续};喝个品酸乳果汁.......*/#include ;typedef unsigned char uint8 ;typedef unsigned int uint16;sbit wd = P3^2; //定义数据单总线;sbit e =P1^5; // 定义1602液晶显示器数据使能端口; sbit rs=P1^0; // 定义数据/指令选择端口;sbit rw=P1^1; // 定义读/写选择端口;sbit BF=P0^7; // 定义繁忙位;bit w=0; //定义一个全局一位变量;//===========1602液晶显示器模块;=============== busy() //液晶屏繁忙检测函数;{ e=0;rs=0;rw=0;P0=0xff;do{ e=0;//使能位清零;rs=0;//指令;rw=1;//读;e=1;//数据传输启动;}while(BF); //如果BF==0;则液晶处于空闲状态; e=0;}play_data(uint8 wr) //液晶写入数据;{busy();//繁忙检测;P0=wr;//装载数据;rs=1;//数据;rw=0;//写入;e=1;//传输开始;e=0;//传输结束;}play_cmd(uint8 cmd) //液晶写入指令; {busy(); //繁忙检测;P0=cmd; //装载数据;rs=0;//指令;rw=0;//写入;e=1;//传输开始;e=0;//传输结束;}reset_1602()//1602液晶显示器初始化函数;play_cmd(0x38);play_cmd(0x0c);play_cmd(0x06);play_cmd(0x01);}//=========温度传感器延时模块============================// sbit led= P1^0;delay(uint8 num )//如果unm等于1;延时16.28微妙; {while(num--); //如果num大于一,则16.28+(num-1)*6.51.}delay2()//此函数延时3.26微秒;{uint8 j=0;j=9;}delay3()uint16 s=60000;while(s--);}reset_1820() //========复位温度传感器; ======== {while(wd){wd=1;delay(140);//拉高总线,延时大概921微妙左右;(延时值自定); wd=0;//总线由单片机拉低,下为延时函数,大概800微秒左右;delay(61); //1个此函数会延时400微妙左右;delay(61); //两个是800微妙左右;wd=1;//主机拉高总线,68微秒左右;delay(9);//延时68微妙左右if(wd==0)//如果wd是0就终止复位;(代表复位成功);{while(wd==0);//总线一旦为低,那么就等待从机再将总线拉高. break;//终止while循环;(reset function end)}else{wd=1;delay(20);//延时140微妙;}}delay(30); //此时总线为高电平并延时205微妙,复位成功!;// if(wd)led=0;//此语句为检验是否复位成功;P1^0外接9012三极管接led小灯;}write_byte(uint8 dat){uint8 i=0;for(i=0;i;>;=1;delay(6); //A点到此处用时65.11微秒;wd=1;//总线释放;delay2(); //延时3.26微秒;}}//========此函数执行完成之后总线为高电平; uint8 read_byte() //=====读8位数据;==================={uint8 j=0, dat =0;for(j=0;j;>;=1;wd=0; // A点 mcu拉低电平3.26微秒;delay2();// 延时3.26微秒;wd=1;if(wd){dat|=0x80;}//读完数据后A点到此处是11.93微秒,保持在15微秒之内;delay(9);// A点到此处80.29微秒; 理想时间范围是60--120微秒;wd=1; //释放总线;delay2(); //延时3.26微秒;}return dat;}start_sensor()//启动传感器;{reset_1820();write_byte(0xcc); //跳跃命令;write_byte(0x44); //转换temperature(温度)命令; }uint8 read_temp()//从温度传感器度温度数据过程;{uint8 ak[2];uint16 dat=0 , j=0;reset_1820();//复位温度传感器write_byte(0xcc); //跳跃rom命令;write_byte(0xbe) ; // 发出读数据命令;ak[0]=read_byte(); //读取第一个字节数据;ak[1]=read_byte(); //读取第二个字节数据;dat=ak[1];//要把两个八位数据载入1个16位变量里;dat;>;11)==0x1f) //此语句是负温度进入.0x1f是二进制5个全1;{dat=(~dat)+1;//负温度要取反加一操作;dat/=16;//传感器给的温度系数要除以16后,得到的数才是常规温度系数;w=0;//此语句是在主函数中用来判断是正温度还是负温度;return dat; //向主函数返回数据,并终止函数; }j=dat;if((j>;>;11)==0)//如果是零则是正温度;{dat/=16;//数据直接除以16,就得到了常规温度系数;w=1;//1代表正;return dat; //向主函数返回数据,并终止函数;}return 130; //向主函数返回数据,并终止函数;}delay_ms() //延时1秒;{uint8 i=250;uint16 j=608;while(j--){ while(i--);i=250;}}error() //测温出错;{uint8 i=5, j=0 ,ak[]="Error!"; while(i--)play_cmd(0x82);while(ak[j]!='\0'){play_data(ak[j++]);} j=0;delay3();play_cmd(0x01);delay3();}}main(){uint8dat=0 ,j=3,len=0 ,num[]="start.....";reset_1602();while(j--)//这是启动电源时,液晶显示:start....(并闪烁3次){play_cmd(0x82);while(num[len]!='\0'){play_data(num[len++]);}len=0;delay3();play_cmd(0x01);delay3();}while(1){start_sensor();//启动温度传感器;delay_ms();//等待1秒;dat = read_temp(); //读取温度数据并赋给dat变量;if(dat==130)//如果返回来的数据是130,表明采集温度出错;{error();}else if(w==1) //如果w是1,就代表正温度.输出;{play_cmd(0x83);play_data(dat/10+'0');play_data(dat%10+'0');}else//否则,就是负温度,输出时前面加一个负号;{play_cmd(0x82);play_data('-');play_data(dat/10+'0');play_data(dat%10+'0');}} //我的亲娘四舅奶奶啊!!!!!!终于完成了!!!!2013年5月9日19:32:10}。
温度传感器18B20驱动程序(C语言)
//1楼主:温度传感器18B20驱动程序(C语言)/*************************************************************18B20驱动程序,DQ为数据口,接于P2.1*11.0592M晶振,上拉4.7k电阻*************************************************************/#define uchar unsigned char#define uint unsigned intsbit dq = P1^7;bit flag;uint Temperature;uchar temp_buff[9]; //存储读取的字节,read scratchpad为9字节,read rom ID为8字节uchar id_buff[8];uchar *p;uchar crc_data;uchar code CrcTable [256]={0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176,238,50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};///*************************************************************Function:延时处理*parameter:*Return:*Modify:*************************************************************/void TempDelay (uchar us){while(us--);}/*************************************************************Function:18B20初始化*parameter:*Return:*Modify:*************************************************************/void Init18b20 (void){dq=1;_nop_();dq=0;TempDelay(86); //delay 530 uS//80_nop_();dq=1;TempDelay(14); //delay 100 uS//14_nop_();_nop_();_nop_();if(dq==0)flag = 1; //detect 1820 success!elseflag = 0; //detect 1820 fail!TempDelay(20); //20_nop_();_nop_();dq = 1;}/************************************************************ *Function:向18B20写入一个字节*parameter:*Return:*Modify:*************************************************************/ void WriteByte (uchar wr) //单字节写入{uchar i;for (i=0;i<8;i++){dq = 0;_nop_();dq=wr&0x01;TempDelay(5); //delay 45 uS //5_nop_();_nop_();dq=1;wr >>= 1;}}/************************************************************ *Function:读18B20的一个字节*parameter:*Return:*Modify:*************************************************************/ uchar ReadByte (void) //读取单字节{uchar i,u=0;for(i=0;i<8;i++){dq = 0;u >>= 1;dq = 1;if(dq==1)u |= 0x80;TempDelay (4);_nop_();}return(u);}/************************************************************ *Function:读18B20*parameter:*Return:*Modify:*************************************************************/ void read_bytes (uchar j){uchar i;for(i=0;i {*p = ReadByte();p++;}}/************************************************************ *Function:CRC校验*parameter:*Return:*Modify:*************************************************************/ uchar CRC (uchar j){uchar i,crc_data=0;for(i=0;i crc_data = CrcTable[crc_data^temp_buff[i]]; return (crc_data);}/************************************************************ *Function:读取温度*parameter:*Return:*Modify:*************************************************************/ void GemTemp (void){read_bytes (9);if (CRC(9)==0) //校验正确{Temperature = temp_buff[1]*0x100 + temp_buff[0];// Temperature *= 0.625;Temperature /= 16;TempDelay(1);}}/************************************************************ *Function:内部配置*parameter:*Return:*Modify:*************************************************************/ void Config18b20 (void) //重新配置报警限定值和分辨率{Init18b20();WriteByte(0xcc); //skip romWriteByte(0x4e); //write scratchpadWriteByte(0x19); //上限WriteByte(0x1a); //下限WriteByte(0x7f); //set 11 bit (0.125)Init18b20();WriteByte(0xcc); //skip romWriteByte(0x48); //保存设定值Init18b20();WriteByte(0xcc); //skip romWriteByte(0xb8); //回调设定值}/************************************************************ *Function:读18B20ID*parameter:*Return:*Modify:*************************************************************/ void ReadID (void)//读取器件 id{Init18b20();WriteByte(0x33); //read romread_bytes(8);}/************************************************************ *Function:18B20ID全处理*parameter:*Return:*Modify:*************************************************************/ void TemperatuerResult(void){p = id_buff;ReadID();Config18b20();Init18b20 ();WriteByte(0xcc); //skip romWriteByte(0x44); //Temperature convertInit18b20 ();WriteByte(0xcc); //skip romWriteByte(0xbe); //read Temperaturep = temp_buff;GemTemp();}/*急什么?急着买吗?还是要程序?我给你提供一段吧!也是网友写的。
基于Linux的温度传感器DS18B20驱动程序设计
基于Linux的温度传感器DS18B20驱动程序设计传统的模拟温度测量抗干扰能力差,放大零点漂移大,导致测量值误差大,难以达到所需精度。
在实际应用中,采纳抗干扰能力强的数字温度是解决上述问题的有效方法。
DS18B20是Dallas公司生产的数字,具有体积小、适用宽、经济灵便的特点。
它内部用法了onboard专利技术,所有传感元件及转换电路集成在一个形如的内。
DS18B20有电源线、地线及数据线3根引脚线,工作电压范围为3~5.5 V,支持单接口。
精确的温度测量是无数系统中重要的一点。
在操作系统下用法数字温度传感器DS18B20,不仅可以得到高精度的温度测量值,而且硬件容易牢靠。
1 Linux的设备驱动程序在Linux中,驱动程序是内核的一部分,它屏蔽了硬件详情,是囫囵操作系统的基础。
驱动程序与Linux内核结合有两种方式:在编译内核时,静态地链接进内核;在系统运行时,以模块加载的方式加载进内核。
驱动的对象是存储器和外设。
Linux将存储器和外设分为3个基础类:字符设备、块设备、网络设备。
字符设备是指必需以串行挨次依次举行拜访的设备,不需要经过系统的迅速缓冲;而块设备要经过系统的迅速缓冲,可以随意挨次举行拜访,以块为单位举行操作。
字符设备和块设备并没有严格的界限,有些设备 (如Flash)既可看作字符设备,也可作为块设备来拜访。
网络设备面对数据包的接收和发送而设计,并不对应于文件系统节点。
内核与网络设备的通信方式彻低不同于内核与字符设备、块设备的通信方式。
DS18B20是单总线温度传感器,主机只能以“位”为单位对其举行拜访。
因此,在Linux系统中,将DS18B20作为一种典型的字符设备来拜访。
2 DS18B20的结构和工作原理2.1 DS18B20的内外结构第1页共2页。
DS18B20驱动程序(LPC213)
#define SetOut() IO0DIR|=0x04 //设置P0.2口为输出#define SetIn() IO0DIR&=~0x04 //设置P0.2口为输入//====================================================== // 函数名称: Delay()// 函数功能: 10微秒延时// 入口参数: time 延时的毫秒数// 出口参数:无//====================================================== void Delay(uint32 time){uint32 i;for(;time>0;time--)for(i=84;i>0;i--);}//====================================================== // 函数名称: Delay_1()// 函数功能: 1微秒延时// 入口参数: time 延时的毫秒数// 出口参数:无//====================================================== void Delay_1(uint32 time){uint32 i;for(;time>0;time--)for(i=6;i>=0;i--);}//====================================================== // 函数名称: void 18B20_Initial_IO(void)// 函数功能:端口初始化子程序// 入口参数:无// 出口参数:无//====================================================== void F_18B20_Initial_IO(void){PINSEL0&=~(3<<4); // 设置管脚P0.2连接GPIO// IO0DIR|=0x04; //设置P0.2口为输出}//====================================================== // 函数名称: uint8 18B20_Reset(void)// 函数功能:一线总线复位及从设备应答控制程序// 入口参数:无// 出口参数: 0表示复位失败 1表示复位成功uint8 F_18B20_Reset(){uint8 flag=0;SetOut();IO0SET=0x04;Delay(5); //延时50usIO0CLR = 0x04; //P0.2置低,初始化开始Delay(70); //延时700usIO0SET = 0x04; //拉高总线Delay(2); //延时20usSetIn();/*等待18B20发出存在脉冲--低电平*/Delay(3); //延时30usif((IO0PIN&0x04)==0){flag=1;}else{flag=0;}return flag;}//=================================================================== ==// 函数名称: uint8 DS18B20_Initial(void)// 函数功能: DS18B20初始化// 包括对端口的初始化,以及对DS18B20进行一次复位(总线)// 入口参数:无// 出口参数:初始化结果,返回0表示初始化失败//=================================================================== ==uint8 DS18B20_Initial(void){uint8 uiTemp=0;F_18B20_Initial_IO();uiTemp = F_18B20_Reset(); //一线总线复位及从设备应答控制return uiTemp;}// 函数名称: void F_18B20_Write_1(void)// 函数功能:向一线总线写1// 入口参数:无// 出口参数:无//======================================================void F_18B20_Write_1(){SetOut();/*先置高再置低,告诉18B20 写开始*/ IO0SET = 0x04; //P0.2置高Delay(120); //延时120usIO0CLR = 0x04; //P0.2置低Delay(1); //延时10usIO0SET = 0x04; //P0.2置高,写 1 开始Delay(6); //延时60usSetIn();Delay_1(5); //保证写2位数据的间隙大于 1 us }//======================================================// 函数名称: void F_18B20_Write_0(void)// 函数功能:向一线总线写0// 入口参数:无// 出口参数:无//======================================================void F_18B20_Write_0(){SetOut();/*先置高再置低,告诉18B20写开始*/IO0SET = 0x04; //P0.2置高Delay(120); //延时130usIO0CLR = 0x04; //P0.2置低,写 0 开始Delay(7); //延时70usIO0SET = 0x04; //P0.2置高,释放总线Delay_1(5); //保证写2位数据的间隙大于 1 usSetIn();}// 函数名称: uint8 F_18B20_Read_DQ(void)// 函数功能:读一位一线总线的数据// 入口参数:无// 出口参数:当前读回的位的值0/1//======================================================uint8 F_18B20_Read_DQ(){uint8 read_byte;SetOut();/*先置高再置低,告诉18B20 读开始*/IO0SET = 0x04; //P0.2置高Delay(2); //延时20usIO0CLR = 0x04; //P0.2置低Delay(1); //延时10usSetIn();Delay_1(5); //延时5usif(IO0PIN & 0x04)read_byte=0x80;elseread_byte=0;SetOut(); //设置P0.2口为输出IO0SET = 0x04; //P0.2置高,释放总线SetIn();return read_byte;}//=================================================================== ==// 函数名称: void DS18B20_WriteByte(uint8 Data)// 函数功能: DS18B20字节写入子程序// 入口参数: Data 要写入的数值// 出口参数:无//=================================================================== ==void DS18B20_WriteByte(uint8 Data){uint8 i;for(i=0;i<8;i++){if(Data&0x0001)F_18B20_Write_1();elseF_18B20_Write_0();Data = Data>>1;}}//=================================================================== ==// 函数名称: uint8 DS18B20_ReadByte(void)// 函数功能: DS18B20字节读出子程序// 入口参数:无// 出口参数:读出的字节数据//=================================================================== ==uint8 DS18B20_ReadByte(void){uint8 i,Data=0;for(i=0;i<8;i++){Data = Data>>1;Data = Data|F_18B20_Read_DQ();}return Data;}//=================================================================== ==// 函数名称: float DS18B20_ReadTemp(void)// 函数功能:启动一次DS18B20测温,并读取测温结果,以浮点数返回// 在本函数中,启动测温后在程序里面作了等待,以待测DS18B20// //完成本次测温转换如用户觉得不合适// 入口参数:无// 出口参数:测温值,浮点数以摄氏度为单位//=================================================================== ==float DS18B20_ReadTemp(void){float fTemp=0.0;uint16 t=0;if(F_18B20_Reset()) //如果一线总线复位及从设备应答控制成功则向下执行{DS18B20_WriteByte(0xcc); //跳过读序号列号的操作DS18B20_WriteByte(0x44); //启动温度转换Delay(50);F_18B20_Reset(); //一线总线复位及从设备应答控制DS18B20_WriteByte(0xcc); //跳过读序号列号的操作DS18B20_WriteByte(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=DS18B20_ReadByte();b=DS18B20_ReadByte();t=b;t<<=8;t=t|a;fTemp=t*0.0625;}return fTemp;}//=================================================================== ==// 语法格式: uint8 DS18B20_SetConfig(uint8 Config)// 实现功能:设置DS18B20中的config寄存器,可通过该寄存器的设置选择温// 度转换结果的有效位数// 参数: Config 要设置的值// 返回值:如返回0则表示设置失败//=================================================================== ==uint8 DS18B20_SetConfig(uint8 Config){uint8 uiTemp = 0;uint8 Data[2];if(F_18B20_Reset()) //如果一线总线复位及从设备应答控制成功则向下执行{DS18B20_WriteByte(0xcc); //跳过ROMDS18B20_WriteByte(0xbe); //读暂存存储器uiTemp = DS18B20_ReadByte();uiTemp = DS18B20_ReadByte();Data[0] = DS18B20_ReadByte();Data[1] = DS18B20_ReadByte();F_18B20_Reset();DS18B20_WriteByte(0xcc); //跳过ROMDS18B20_WriteByte(0x4e); //写暂存存储器DS18B20_WriteByte(Data[0]);DS18B20_WriteByte(Data[1]);DS18B20_WriteByte(Config);uiTemp = F_18B20_Reset();}return uiTemp;}//=================================================================== ==// 语法格式: unsigned int DS18B20_GetConfig(void)// 实现功能:获取DS18B20中的config寄存器的值// 参数:无// 返回值: Config 当中的值//=================================================================== ==uint8 DS18B20_GetConfig(void){uint8 uiTemp = 0;if(F_18B20_Reset()){DS18B20_WriteByte(0xcc); //Skip ROMDS18B20_WriteByte(0xbe); //Read Scratchadfor(uiTemp=0;uiTemp<5;uiTemp++)uiTemp = DS18B20_ReadByte();uiTemp = F_18B20_Reset();}return uiTemp;}。
MSP430单片机驱动ds18b20程序
MSP430单片机驱动ds18b20程序#include<msp430g2553.h>#define DS18B20_DIR P1DIR#define DS18B20_OUT P1OUT#define DS18B20_IN P1IN#define DS18B20_DQ BIT0#define DS18B20_H DS18B20_OUT|=DS18B20_DQ //DQ置位#define DS18B20_L DS18B20_OUT&=~DS18B20_DQ //DQ复位#define DQ_IN DS18B20_DIR &= ~DS18B20_DQ //设置DQ为输入#define DQ_OUT DS18B20_DIR |= DS18B20_DQ //设置DQ为输出#define READ_DQ (DS18B20_IN&DS18B20_DQ) //读DQ电平#define CPU_F ((double)1000000)#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))void DS18B20_init(); //DS18B20初始化unsigned char DS18B20_Reset(); //DS18B20复位void DS18B20_WriteData(unsigned char); //写数据到DS18B20 unsigned char DS18B20_ReadData(); //读数据unsigned int DS18B20_Conert(); //转换温度/***********************************************************DS18B20初始化*函数名称:DS18B20_Init()*说明:本初始化程序可以不要,因为18B20在出厂时就被配置为12位精度了**********************************************************/void DS18B20_Init(){DS18B20_Reset();DS18B20_WriteData(0xCC); // 跳过ROMDS18B20_WriteData(0x4E); // 写暂存器DS18B20_WriteData(0x64); // 往暂存器的第三字节中写上限值100℃DS18B20_WriteData(0x00); // 往暂存器的第四字节中写下限值0℃DS18B20_WriteData(0x7F); // 将配置寄存器配置为12位精度DS18B20_Reset();}/***********************************************************复位DS18B20(通过存在脉冲可以判断DS1820是否损坏)*函数名称:DS18B20_Reset()**********************************************************/ unsigned char DS18B20_Reset(){unsigned char flag;DQ_OUT; //DQ为输出DS18B20_H;delay_us(8); //延时8微秒DS18B20_L; //拉低总线delay_us(500); //延时500微秒,产生复位脉冲,必须大于480微秒DS18B20_H;delay_us(80); //15~60us 后接收 60-240us的存在脉冲,必须大于60微秒DQ_IN;if(READ_DQ)flag=0; //等待从机 DS18B20 应答(低电平有效)else flag=1;DQ_OUT;delay_us(440);DS18B20_H;return(flag);}/***********************************************************写数据到DS18B20*函数名称:DS18B20_WriteData()**********************************************************/void DS18B20_WriteData(unsigned char wData){unsigned char i;DQ_OUT; //DQ为输出for (i=8;i>0;i--){DS18B20_L; //拉低总线,产生写信号delay_us(15); //延时在15us~30usif(wData&0x01) //发送1位{DS18B20_H;}else {DS18B20_L;}delay_us(45); //延时15~60usDS18B20_H; //释放总线,等待总线恢复wData>>=1; //准备下一位数据的传送}}/********************************************************** *从DS18B20中读出数据*函数名称:DS18B20_ReadData()**********************************************************/ unsigned char DS18B20_ReadData(){unsigned char i,TmepData;for(i=8;i>0;i--){TmepData>>=1; //数据右移DQ_OUT; //DQ为输出DS18B20_L; //拉低总线,产生读信号delay_us(6);DS18B20_H; //释放总线,准备读数据delay_us(4);DQ_IN; //DQ为输入if(READ_DQ){TmepData|=0x80;}delay_us(65);}return(TmepData); //返回读到的数据}/***********************************************************DS18B20转换温度*函数名称:DS18B20_Conert()**********************************************************/ unsigned int DS18B20_Conert(){unsigned char TempData1,TempData2;DS18B20_Reset();DS18B20_WriteData(0xCC); // 跳过ROMDS18B20_WriteData(0x44); // 开始转换delay_us(500); //延时一般在500us不能过小 DS18B20_Reset();DS18B20_WriteData(0xCC); // 跳过ROMDS18B20_WriteData(0xBE); //读取 RAMTempData1=DS18B20_ReadData(); //读低八位,LS Byte, RAM0TempData2=DS18B20_ReadData(); //读高八位,MS Byte, RAM1delay_ms(750); //延时750~900ms,保证工作周期DS18B20_Reset();//return (((TempData2<<8)|TempData1)*0.625); //0.0625=xx, 0.625=xx.x, 6.25=xx.xxreturn (((TempData2<<8)+TempData1)); //0.0625=xx, 0.625=xx.x, 6.25=xx.xx}。
温度传感器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_();}}}。
18B20温度传感器驱动程序
/*18B20测试功能:用数码管显示温度接线:用杜邦线将DATA接到P37,用跳线帽连接J8的*/#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit d=P3^7; // 定义18b20数据线uchar code wu[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位选数据uchar code du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x8 0,0x90 ,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x 00,0x10, //断选数据0xff,0xbf // 关显示和负号};uchar str[5];//存放待显示的数据/******************************************函数名称:delayms;函数功能:延时z毫秒;形参:z (延时时间参数)************************************* ******/void delayms(uchar z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/************************************* *****函数名称:display();函数功能:数码管显示子函数形参:d1 (选择第几位数码管)d2(数码管显示的数字)************************************* ******/void display(uchar d1,uchar d2){P1=wu[d1]; //位选P0=du[d2]; // 段选delayms(1);P0=0xff;P1=0xff; // 关显示}/********************* 延时函数***********/void delay(uint z){while(z--);}/********************* 初始化ds1820 ***********/void reset(){d=1; // d 复位delay(8); // 稍做延时d=0; // 单片机将DQ拉低delay(80); // 精确延时大于480usd=1; // 拉高总线delay(35);}/********************* 写一个字节***********/void write_b20(uchar dat){uchar i;for(i=0;i<8;i++){d=0; // 给脉冲信号d=dat&0x01; // 给数据信息delay(5);d=1;dat>>=1;}}/********************* 读一个字节***********/uchar read_b20(){uchar i,dat;for(i=0;i<8;i++){d=0; // 给脉冲信号dat>>=1;d=1; // 给脉冲信号if(d==1)dat|=0x80;delay(4);}return dat;}/********************* 启动温度转换***********/void write_com(){reset();write_b20(0xcc); // 跳过读序号列号的操作write_b20(0x44); // 启动温度转换}/********************* 读温度***********/int read_temper(){int temper;uchar a,b;reset();write_b20(0xcc); //跳过读序号列号的操作write_b20(0xbe); //读取温度寄存器EA=0;a=read_b20(); //读低8位b=read_b20(); //读高8位EA=1;temper=b;temper<<=8;temper|=a;temper*=0.625;return temper;}void main(){int temper;uchar i,j;while(1){write_com(); // 启动温度转换for(j=0;j<150;j++) //温度动态显示{for(i=0;i<5;i++)display(i,str[i]);}temper=read_temper(); //读温度if(temper<0){str[4]=21; //第五位数码管显示负号temper=~temper+1; //如果温度为负取反加1}else{str[4]=20; //第五位数码管不显示}str[3]=temper/1000;str[2]=temper/100%10;str[1]=temper/10%10+10;str[0]=temper%10;for(j=0;j<10;j++){for(i=0;i<5;i++)display(i,str[i]);}}}。
18B20温度传感器温度计程序
18B20温度传感器温度计程序2008-9-261.实验任务本实验实现的是通过18B20温度传感器读回温度并在6位数码管上显示。
精度为,范围为2.实验目的学会使用单片机控制18B20此类单总线器件。
原理及引脚介绍DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。
因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
DS18B20产品的特点(1)、只要求一个端口即可实现通信。
(2)、在DS18B20中的每个器件上都有独一无二的序列号。
(3)、实际应用中不需要外部任何元器件即可实现测温。
(4)、测量温度范围在-55。
C到+125。
C之间。
(5)、数字温度计的分辨率用户可以从9位到12位选择。
(6)、内部有温度上、下限告警设置。
TO-92封装的DS18B20的引脚排列见下图,其引脚功能描述见下:1.GND地信号2.DQ数据输入/输出引脚。
开漏单总线接口引脚。
当被用着在寄生电源下,也能够向器件提供电源。
3.VDD可选择的VDD引脚。
当工作于寄生电源时,此引脚必需接地。
18B20管脚图4.实验原理图实验原理图5. 18B20操纵命令字指令说明读ROM(33H) 读18B20的序列号匹配ROM(55H) 继续读完64位序列号的命令,用于多个18B20时定位跳过ROM(CCH) 此命令执行后的在存储器打操作针对在线所有18B20 搜ROM(F0H) 识别总线上各器件的编码,为操作各器件做准备报警搜索(ECH) 公温度越限的器件对此命令作出响应指令说明温度转换(44H) 启动在线18B20做温度AD转换读数据(BEH) 从高速暂存器读9位温度值和CRC值写数据(4EH) 将数据写入高速暂存的第3和第4字节中复制(48H) 将高速暂存器中第3和第4字节复制到EERAM读EERAM(B8H) 将EERAM内容写入高速暂存器中第3和第4字节读电源供电方式(B4H) 了解18B20的供电方式6. 实验源程序WENDU_L EQU 29H;用于保留读出温度的低字节WENDU_H EQU 28H;用于保留读出温度的高字节XIAOSHU EQU 27H;用于保留温度的小数部份ZHENGSHU EQU 26H;用于保留整数部份BIAOZHI BIT 50H;18B20检查位1为存在,0为不存在ORG 0000HAJMP MAINORG 0030HMAIN:MOV SCON,#00HACALL DUWENACALL ZHENGHEACALL BCDACALL DISPACALL TIME1AJMP MAIN;---------------------------------------------------------------------------------------------------------------------------------------- ;读温度子程序;---------------------------------------------------------------------------------------------------------------------------------------- DUWEN:SETBACALL FUWEI ;读温度之前必需先复位JB BIAOZHI,CUNZAI;查看标志位看18B20是不是存在,1为存在,0为不存在RET ;不存在那么返回CUNZAI: ;存在那么开始读温度MOV A,#0CCH ;跳过ROM匹配ACALL XIE ;调写子程序MOV A,#44H ;发出温度转换命令ACALL XIE ;调写子程序ACALL TIME1 ;调1秒延时,等等AD转换完成,此刻分辨率为12位,温度最大转换时刻为750MSACALL FUWEI ;读温前需要复位MOV A,#0CCH ;跳过ROM匹配ACALL XIEMOV A,#0BEH ;发读温度命令ACALL XIEACALL DUSHU ;将闱出数据读回CLRRET;------------------------------------------------------------------------------------------------------------------------------;复位子程序;18B20复位需要将数据位拉低500us;18B20收到信号后要等待16-60us,然后发出60-240us的低脉冲;------------------------------------------------------------------------------------------------------------------------------- FUWEI:SETBNOPCLRMOV R0,#3INTE:MOV R1,#107 ;设一个537us延时KK1: DJNZ R1,KK1DJNZ R0,INTESETB ;拉高数据线,等待回应NOPNOPNOPMOV R0,#25 ;INTE1:JNB ,INTE2 ;延时延时50us等待18B20回应,假设返回低脉冲那么说明18B20存在DJNZ R0 ,INTE1AJMP INTE3 ;通过反映时刻而没检测到18B20的存在,那么跳转去清零标志位INTE2:SETB BIAOZHI ;检测到18B20存在,置1标志位CLRAJMP INTE4INTE3:CLR BIAOZHI ;没检测到18B20,清零标志位AJMP INTE5INTE4:MOV R0,#120 ;延时240us,确定回应信号已发完KK: DJNZ R0,KKINTE5:SETBRET;---------------------------------------------------------------------------------------------------------------------------------------- ;写18B20子程序;----------------------------------------------------------------------------------------------------------------------------------------- XIE:MOV R2,#8 ;写计数寄放器,一共有8位数据CLR CLP:CLRMOV R3,#6 ;设一个延时LL1:DJNZ R3,LL1RRC A ;右循环,先输出低位MOV ,CMOV R3,#23 ;设延时LL: DJNZ R3,LL ;SETBNOPNOPDJNZ R2,LP ;判定是不是完成数据传送SETB ;完成传送拉高数据位RET;----------------------------------------------------------------------------------------------------------------------------------------- ;从18B20中读出温度数据子程序;-----------------------------------------------------------------------------------------------------------------------------------------DUSHU:MOV R4,#2 ;设读回数据个数指针MOV R1,#WENDU_L ;把温度数据低位存入29HRE: MOV R2,#8 ;设数据长度指针RE1: CLR CSETBNOPNOP CLRNOPNOPNOPSETBMOV R3,#9 DJNZ R3,$ MOV C, MOV R3,#23NN: DJNZ R3,NNRRC ADJNZ R2,RE1MOV @R1,A DEC R1 ;高位存入28H DJNZ R4,RERET;---------------------------------------------------------------------------------------------------------------------------------;数据整合子程序;温度源数据的整合,读出数据的高字节的低四位决定温度的整数部份;低字节的低四位决定小数部份;----------------------------------------------------------------------------------------------------------------------------- ZHENGHE:MOV A,#0FHANL A,WENDU_L ;低字节的低四位就是小数部分MOV XIAOSHU,A ;取得小数部份MOV A,WENDU_L ;将高字节的低四位移入低字节的高4位,MOV C,40H ;获得的新字节就是整数部分的数据RRC AMOV C,41HRRC AMOV C,42HRRC AMOV C,43HRRC AMOV ZHENGSHU,ARET;----------------------------------------------------------------------------------------------------------------------------------------- ;显示数据拆解程序、显示程序、延时程序;----------------------------------------------------------------------------------------------------------------------------------------;数据拆解程序BCD:MOV A,ZHENGSHU MOV B,#10DIV ABMOV 50H,AMOV 51H,BMOV A,XIAOSHUMOV R0,#52HMOV R2,#4D0:MOV B,#10MUL ABMOV B,#16DIV ABMOV @R0,AINC R0MOV A,BDJNZ R2,D0RET ;----------------------------------- ;显示程序;---------------------------------- DISP:ACALL TIMEMOV R7,#6MOV DPTR,#TABMOV R0,#55HLP1:MOV A ,@R0;MOVC A,@A+DPTRCJNE R7,#2,NE1ANL A,#07FHNE1:MOV SBUF,AJNB TI ,$CLR TIDEC R0DJNZ R7,LP1RET;---------------------------------------- ;延时程序;---------------------------------------- TIME1:MOV R6,#4LOOP2:MOV R5,#250LOOP1:ACALL D1MSDJNZ R5,LOOP1DJNZ R6,LOOP2RETTIME:MOV R6,#200LOOP3:ACALL D1MSDJNZ R6,LOOP3RETD1MS:MOV R7,#250LOOP0:NOPNOPNOPDJNZ R7,LOOP0RETTAB:DB 0C0H,0F9H,0A4H,0B0H DB 99H, 92H, 82H, 0F8HDB 80H, 90H, 88H, 83HDB 0C6H,0A1H,86H, 8EHDB 0FFHEND。
c语言18b20驱动程序
void check_pre_1(void) { while(DQ1); while(~DQ1); time_delay(30); } void read_ROM(void) { int n; ds_reset_1(); check_pre_1(); wr_ds18_1(0x33); for(n=0;n<8;n++){ROM[n]=rd_ds18_1();} }
/*****************************************************/ /* read a bety from ds18b20 字节读取 */ /*****************************************************/ unsigned char rd_ds18_1() { unsigned char idata i,j,dat=0; for(i=1;i<=8;i++) { j=tmrbit_1(); dat=(j<<(i-1))|dat; } return dat; }
#include <reg51.h> #include<intrins.h> #define sbit BUSY1 DQ1 (DQ1==0) = P0^4;
unsigned char idata TMP; unsigned char idata TMP_d; unsigned char f; void wr_ds18_1(char dat); unsigned char rd_ds18_1(); /***************延时程序,单位us,大于10us*************/ void time_delay(unsigned char time) { time=time-10; time=time/6; while(time!=0)time--; } /*****************************************************/ /* reset ds18b20 */ /*****************************************************/ void ds_reset_1(void) { unsigned char idata count=0; DQ1=0; time_delay(240); time_delay(240); DQ1=1; return; }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/****************************************************************************** *
* 标题: 试验数码管上显示温度*
*
*
******************************************************************************* **
* 1.通过本例程了解DLASS18b20的基本原理和使用,理解并掌握18B20驱动程序的编写*
* 2.了解掌握I2C总线接口的工作原理及一般编程方法。
*
* 插上18B20 观察数码管的实际温度显示
* 用排线将JP8(P1口) 与J12 连接在数码管上可以看温度显示
*
* * * * 请学员认真消化本例程,懂DLASS18b20在C语言中的操作*
******************************************************************************* */
#include <reg52.H>
extern GetTemp(); //声明引用外部函数
extern unsigned int idata Temperature; // 声明引用外部变量
void delay(unsigned int i);
//else IO
sbit LS138A=P2^2; //管脚定义
sbit LS138B=P2^3;
sbit LS138C=P2^4;
// 此表为LED 的字模// 0 1 2 3 4 5 6 7 8 9 A b c d E - L P U Hidden _ (20)
unsigned char code Disp_Tab[] = { 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0xbf,0xc7,0x8 c,0xc1, 0xff, 0xf7 };
unsigned long LedOut[5],LedNumVal;
void system_Ini()
{
TMOD|= 0x11;
TH1=0xDC; //11.0592M
TL1=0x00;
IE = 0x8A;
TR1 = 1;
}
main()
{ unsigned char i;
system_Ini();
while(1)
{
GetTemp();
/********以下将读18b20的数据送到LED数码管显示*************/
LedNumVal=Temperature;
LedOut[0]=Disp_Tab[LedNumVal%10000/1000];
LedOut[1]=Disp_Tab[LedNumVal%1000/100];
LedOut[2]=Disp_Tab[LedNumVal%100/10]; //十位
LedOut[3]=Disp_Tab[LedNumVal%10]; //个位
for(i=0; i<4; i++)
{
P1 = LedOut[i] ;
switch(i)
{ //138译码
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
//case 4:LS138A=0; LS138B=0; LS138C=1; break;
}
delay(150);
}
P1 = 0XFF;
}
}
//延时程序
void delay(unsigned int i) {
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--); }。