ds18b20,读写程序,
/*ds18b20,读写程序,这里以8M晶体为例,不同的晶体速度可能需要调整 延时的时间*/
#include "..ucos_iiincludes.h"
#if ds18b20 > 0
#define DQ PD7 //io口 #define CLR_DS PORTD&=~(1<<DQ) //数据线强制拉低 #define SET_DS PORTD|= (1<<DQ) //数据线强制拉高 #define HLD_DS DDRD |= (1<<DQ) //Mega控制总线,DQ为输出 #define RLS_DS DDRD &=~(1<<DQ) //释放总线,DQ为输入 #define STU_DS (PIND&(1<<DQ)) //数据线的状态
#define ds_read_rom 0x33 //读命令64bit #define ds_match_rom 0x55 //选择定位命令 #define ds_skip_rom 0xcc //跳过ROM序列号检测命令 #define ds_search_rom 0xf0 //查询命令 #define ds_alarm_search_rom 0xec //报警查询命令 #define ds_write_ram 0x4e //写入 2,3,4字节 #define ds_read_ram 0xbe //读出0-9 #define ds_copy_ram 0x48 //复制 #define ds_convert_tem 0x44 //开始转换 #define ds_eecall_eeprom 0xb8 //回调 #define ds_read_power_supply 0xb4 //读电源标志
const unsigned char ds[16]={0x00,0x06,0x13,0x19,0x25,0x31,0x38,0x44, 0x50,0x56,0x63,0x69,0x75,0x81,0x88,0x94}; /*********************************************************** * 函数名称:resetDS18B20() * 功 能:ds18b20初始化 * 入口参数:无 * 出口参数:0xff存在,0x00不存在或者错误 * 全程变量: 无,for(k=4;k!=0;k--);//4*4*0.125=2us ***********************************************************/ unsigned char resetDS18B20(void) { unsigned char i,k; i=0x00; asm("cli"); HLD_DS; //Maga控制总线,DIR:output CLR_DS; //强制拉低,并且等待480~960us--600us for(k=240;k!=0;k--);//120us for(k=240;k!=0;k--);//120us for(k=240;k!=0;k--);//120us for(k=240;k!=0;k--);//120us SET_DS; RLS_DS; //释放总线,总线自动上拉 //设置DIO=1,等待15~60us,如果DS18B20有应答,不会超过60us就将DIO拉低, //如果超过60us,DIO还是保持高电平,则表示有错误! for(k=120;k!=0;k--);//60us if(!(STU_DS)) //have a ACK { //等待DS18B20应答信号(低电平)过去,这个应答信号在60~240us //如果超时(大于240us),并且DIO还保持低电平,表示错误! asm("sei"); for(k=250;k!=0;k--);//125us for(k=250;k!=0;k--);//125us if(STU_DS) i=0xff; } asm("sei"); return i; } /*********************************************************** * 函数名称:readByteDS18B20() * 功 能:从ds18b20读一个字节 * 入口参数:无 * 出口参数:所读字节 * 全程变量: ***********************************************************/ unsigned char readByteDS18B20(void) { unsigned char i,k; unsigned char retVal=0; HLD_DS; //Maga控制总线 DIR:output for(i=8;i!=0;i--) { retVal>>=1; //生成读时间隙 //延迟时间必须要大于1us asm("cli"); HLD_DS; //Maga控制总线 DIR:output CLR_DS; //强制拉低 DATA:0 for(k=4;k!=0;k--);//2us //释放总线,让DS18B20确定总线状态 //DS18B20输出数据在生成读时间隙至15us内有效 SET_DS; //DATA=1,上拉电阻有效 RLS_DS; //释放总线,DS18B20会将总线强制拉低,DIR:input for(k=4;k!=0;k--);//2us if(STU_DS) retVal|=0x80; //读取一位数据必须至少要求大于60us asm("sei"); for(k=120;k!=0;k--);//60us } SET_DS; //DATA=1,上拉电阻有效 RLS_DS; //释放总线,DS18B20会将总线强制拉低,DIR:input return(retVal); } /*********************************************************** * 函数名称:writeByteDS18B20() * 功 能:向ds18b20写一个字节 * 入口参数:所写字节 * 出口参数:无 * 全程变量: ***********************************************************/ void writeByteDS18B20(unsigned char wb) { //从第0位到第7位,依次从总线发送出去 //如果将要发送的位是1,则先将总线拉低,持续时间大于1us,小于15us //然后再将总线拉高,维持时间大于60us,小于120us unsigned char i,k; for(i=8;i!=0;i--) { asm("cli"); HLD_DS; //DIR:output CLR_DS; //强制拉低,DATA=0 for(k=4;k!=0;k--);//2us if(wb & 0x01) SET_DS; //DATA=1 //输出一位之后,维持时间大于60us,小于120us for(k=120;k!=0;k--);//60us //输出下一位时候,先将总线拉高,维持时间大于1us,小于无穷大 SET_DS; //DATA=1 RLS_DS; //释放总线,DIR:input,上拉 asm("sei"); for(k=4;k!=0;k--);//2us wb>>=1; } SET_DS; //DATA=1,上拉 RLS_DS; //释放总线,DIR:input } /*********************************************************** * 函数名称:readTempDS18B20() * 功 能:读ds18b20的温度 * 入口参数:无 * 出口参数:温度值(两个字节),0xeeee表示无ds18b20 * 全程变量: ***********************************************************/ unsigned int readTempDS18B20(void) { unsigned int Temp; if(resetDS18B20()) { writeByteDS18B20(ds_skip_rom); //跳过ROM writeByteDS18B20(ds_convert_tem); //启动温度转换 750ms //延时750ms } else return(0xeeee); //无DS18B20 if(resetDS18B20()) { writeByteDS18B20(ds_skip_rom); //跳过ROM writeByteDS18B20(ds_read_ram); //读数据 //先低后高 Temp=readByteDS18B20()+(unsigned int)(readByteDS18B20()<<8); } else return(0xeeee); //无DS18B20 return(Temp); } #endif |
|