#include "./src/AT89X52.h" #include "intrins.h"
#include "./src/Memory.h" #include "./src/Msg.h" #include "./src/Uart.h" #include "./src/UartPrintf.h"
#include "DS18B20.h" #include "Delay.h"
struct Ds18b20Buf{ uchar ConvertTepTrigger; //两次转换时间间隔时间 };
struct Ds18b20Buf sInDs18b20Buf; struct Temperature sTemperatureBuf;
bit DetectOK; //复位成功标志 bit Refurbish; //显示刷新标志
//----------------------------------------------------------- //函数功能: DS18b20复位 //入口参数: 无 //出口参数: 无 //----------------------------------------------------------- bit DS18B20_Reset(void){
DataIO=1;
Delay20us(); //20us
DataIO=0; Delay400us(); Delay100us(); //延时500us(>480usd)复位DS18b20 DataIO=1; //CPU释放总线,数据线被拉高 Delay50us(); //DS18b20检测到高电平后等待15-60us Delay10us(); //在等待60us时候采样
if(DataIO==0){ Delay100us(); Delay50us(); //低电平维持60-240us DetectOK = 1; }else{ DetectOK = 0; } DataIO=1; //释放总线 return DetectOK; }
//----------------------------------------------------------- //函数功能: DS18b20读取一位数据 //入口参数: 无 //出口参数: 从DS18b20内部读出的一位数据 //----------------------------------------------------------- bit DS18B20_Read_Bit(void){ //读一位
bit Val;
DataIO=0; DelayMin(); //MCU拉低总线初始化读时隙 DataIO=1; //释放总线,DS18B20开始传送数据 DelayMin(); Val=DataIO; //读取数据,15us内有效 Delay50us(); //读时隙最少60us Delay20us();
return(Val); //返回数据 }
//----------------------------------------------------------- //函数功能: 向DS18b20写入1 //入口参数: 无 //出口参数: 无 //----------------------------------------------------------- void DS18B20_Write_Bit_1(void){ DataIO=1; DelayMin(); DataIO=0; //MCU拉低总线初始化写时隙
Delay10us(); DataIO=1; //15us内释放总线 Delay50us(); }
//----------------------------------------------------------- //函数功能: 向DS18b20写入0 //入口参数: 无 //出口参数: 无 //----------------------------------------------------------- void DS18B20_Write_Bit_0(void){
DataIO=1; DelayMin(); DataIO=0; //MCU拉低总线初始化写时隙
Delay10us(); Delay50us(); //60us后释放总线
DataIO=1; } //----------------------------------------------------------- //函数功能: DS18b20读取一字节数据 //入口参数: 无 //出口参数: 从DS18b20内部读出的一字节数据 //----------------------------------------------------------- uchar DS18B20_Read_Byte(void ){ //读一字节 uchar i; uchar readval; uchar bitshiftval;
bitshiftval = 0x01; readval=0; //初值
for(i=0;i<8;i++){ if( DS18B20_Read_Bit() ){ readval |= bitshiftval; } bitshiftval <<= 1; } return(readval); //返回一个字节的数据 }
//----------------------------------------------------------- //函数功能: 向DS18b20写一位数据 //入口参数: 需要写入的一个字节的数据 //出口参数: 无 //----------------------------------------------------------- void DS18B20_Write_Byte(uchar dat){ //写一个字节
uchar i; bit ShiftOutbit; for(i=1; i<=8; i++){ ShiftOutbit = dat&0x01; dat = dat>>1; if(ShiftOutbit){ //写 1 DS18B20_Write_Bit_1(); }else{ //写 0 DS18B20_Write_Bit_0(); } } }
//----------------------------------------------------------- //函数功能: 启动DS18b20温度转换 //入口参数: 无 //出口参数: 无 //-----------------------------------------------------------
void TemperatureConversion(void) { DS18B20_Reset();
DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0x44); }
//----------------------------------------------------------- //函数功能: 读出DS18b20转换后的温度 //入口参数: 无 //出口参数: 无 //----------------------------------------------------------- void GetTemperature(void) { uchar temhighbyte,temlowbyte,currenttemperature; DS18B20_Reset();
DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0xbe); temlowbyte = DS18B20_Read_Byte(); temhighbyte = DS18B20_Read_Byte(); currenttemperature = (temlowbyte>>4) + (temhighbyte<<4); //如果此次温度与上次相同,则刷新标志Refurbish清零,在LCD等显示时可以不刷新 if( sTemperatureBuf.TemperatureHbyte == currenttemperature ){ Refurbish = 0; }else{//温度变化,显示刷新 sTemperatureBuf.TemperatureHbyte = currenttemperature; Refurbish = 1; } }
//----------------------------------------------------------- //函数功能: DS18B20初始化 //入口参数: 无 //出口参数: 无 //----------------------------------------------------------- void DS18B20Init(void){
//检测DS18B20 EnableMcuINT;
if ( DS18B20_Reset() ){ UartPrintf("Detect DS18B20 Successful!
"); }else{ UartPrintf("Detect DS18B20 failed!
"); } while( Send_OK );
DisableMEcuINT;
Memory_InitSet((uchar *)&sTemperatureBuf, 0, sizeof( struct Temperature )); //进入循环后触发温度转换 sInDs18b20Buf.ConvertTepTrigger = 1; DataIO = 1; }
//----------------------------------------------------------- //函数功能: 调度温度转换、读取已转换的温度值 //入口参数: 无 //出口参数: 无 //----------------------------------------------------------- void DS18B20Drv(void){
sInDs18b20Buf.ConvertTepTrigger--;
if( sInDs18b20Buf.ConvertTepTrigger == 0 ){ DisableMEcuINT; //禁止中断,保证DS18B20时序正确 GetTemperature(); //读取温度 TemperatureConversion(); //进行下次转换 EnableMcuINT; //开放中断 //压入一次温度转换读取完毕消息及是否刷新显示,显示函数接收处理该消息 PushMsgWithPar( TmpConvertOver, Refurbish ); //一次转换MAX时间750ms,因此800ms后再读取数据进行下次转换 sInDs18b20Buf.ConvertTepTrigger = ConvertTemperatureTimer; } } |