1、传感器DS18B20
2、输出:tempeature温度值、t_sign[]状态
*/
//---------------------------------------------
#define uchar unsigned char
#define uint unsigned int
#define sint signed int
#define schar signed char
//=============================================
//工作参数
#define TEMP_WAIT 10 //等待温度转换完成
#define TEMP_HIG 2000 //温度范围 125度 最大值 2000*0.0625=125
#define TEMP_LOW -880 //温度范围 -55度 最小值 -880*0.0625=-55
#define TEMP_K 0.625 //温度系数,从传感器读出的值×TEMP_K=实际温度值
#define ERR_MAX 5 //传感器连续错误次数检测
//==============================================
//字符定义
#define ERR 0 //错误标志
#define OLD 1 //数据准备好标志
#define END 2 //数据采集结束标志
#define OVERFLOW 3 //数据溢出标志
//传感器引脚
#define WRIT_DDR_0 DDRB &= ~(1 << DDB0)
#define WRIT_DDR_1 DDRB |= (1 << DDB0)
#define WRIT_POT_0 PORTB &= ~(1 << DDB0)
#define WRIT_POT_1 PORTB |= (1 << DDB0)
//===============================================
//全局变量
uchar temp_count,temp_wait; //温度采集相关寄存器
sint temp_reg;
uchar temp_err_c; //温度传感器错误读取错误寄存器
sint temp_buff[3];
uchar t_sign[4];
sint temperature;
//===============================================
//DS18B20驱动程序
void delay(unsigned int); //延时函数
void ds18b20_write(uchar); //写1个字节
uchar ds18b20_read(void); //读1个字节
uchar reset(void); //复位
//===============================================
/************************************************
函数名称:温度变换函数
函数参数:通道号
局部变量temp_count (温度采集数据组数 0-3),temp_wait(温度采集进程),
标志位: temp_err(传感器错误),temp_overflow(温度值溢出),temp_old(温度值准备就绪)
返 回 值:temperature(当前温度值×10)
备 注:传感器=18B20
*************************************************/
void call_temp(void)
{
uchar a,b;
//执行程序
switch(temp_wait)
{
case 0:temp_wait++;
a=reset();
if(a){temp_wait=0;temp_err_c++;t_sign[END]=1; } //无复位信号//未完成温度采集//传感器错误
break;
case 1:temp_wait++;
ds18b20_write(0XCC); //忽略ROM匹配
ds18b20_write(0X44); //发送温度转化命令
break;
case TEMP_WAIT:
temp_wait++;
a=reset(); //复位等待从机应答
if(a){temp_wait=0;temp_err_c++;t_sign[END]=1; } //无复位信号//未完成温度采集//传感器错误
break;
case (TEMP_WAIT+1):
temp_wait++;
ds18b20_write(0XCC); //忽略ROM匹配
ds18b20_write(0XBE); //发送读温度命令
break;
case (TEMP_WAIT+2):
temp_wait++;
temp_reg=ds18b20_read(); //读出温度低8
DDRB &=~(1<<DDB0); //释放总线
break;
case (TEMP_WAIT+3):
temp_wait++;
temp_reg=temp_reg|(ds18b20_read()<<8); //读出温度高8位
DDRB &=~(1<<DDB0);
break;
case (TEMP_WAIT+4):
temp_wait=0; //数据完成
temp_err_c=0; //传感器数据读取正常
t_sign[ERR]=0; //
//
if((TEMP_LOW<=temp_reg)&&(temp_reg<=TEMP_HIG)) //数据是否在允许范围内
{ //数据未溢出
temp_buff[temp_count]=temp_reg; //将数据保存在缓存中
if(temp_count>=2){temp_count=0;} //温度已采集3次以上
else temp_count++; //修改指针,以更新数据。
//在3组数据数值中,取出中间值。
for(b=0;b<2;b++)
{
for(a=0;a<2-b;a++)
if(temp_buff[a]>temp_buff[a+1])
{
temp_reg=temp_buff[a+1];
temp_buff[a+1]=temp_buff[a];
temp_buff[a]=temp_reg;
}
}
//计算实际温度值
temperature=(sint)(temp_buff[1]*TEMP_K); //传感器读出的数据×系数=实际温度值。
//连续采集3次以上数据后,数据准备就绪
if(temp_count>1)t_sign[OLD]=1; //数据准备完成
//温度采集正常
temp_err_c=0; //传感器数据读取正常
t_sign[ERR]=0; //
//
}
else temp_wait=0; //数据溢出
//
t_sign[END]=1; //温度采集完成
break;
default:
{
if(temp_wait>(TEMP_WAIT+4))temp_wait=0;
else temp_wait++;
}
}
//====================================
//传感器错误检测
if(temp_err_c>=ERR_MAX)
{
temp_err_c=ERR_MAX;
t_sign[ERR]=1;
temp_count=0;
t_sign[OLD]=0;
}//温度传感器错误
}
//======================================================
/***********************************
函数名称:DS18B20复位
函数参数:通道号
返 回 值:返回0成功,反1失败
备 注:无
**********************************/
unsigned char reset(void)
{
unsigned char presence=1;
WRIT_DDR_1;
WRIT_POT_0;
//主机拉至低电平
delay(250);
WRIT_POT_1;
WRIT_DDR_0; //延时503us
//释放总线等电阻拉高总线,并保持15~60us
delay(35); //延时70us
presence=PINB; //没有接收到应答信号,继续复位
presence=presence&0x01; //接收到应答信号
delay(200); //延时
return(presence);
}
//============================================
/***********************************
函数名称:DS18B20 读1个字节
函数参数:通道号
返 回 值:读出值
备 注:无
**********************************/
unsigned char ds18b20_read(void)
{
unsigned char i,byte,temp;
byte=0x00;
for(i=0;i<8;i++)
{
WRIT_DDR_1;
WRIT_POT_0;
delay(1); //拉低总线3us
asm("nop");
asm("nop");
WRIT_POT_1;
WRIT_DDR_0;
delay(5); //释放总线10us
temp=(PINB&0x01);
if(temp!=0x00)
byte|=0x80;
if(i<7)byte=byte>>1;
delay(50);
WRIT_DDR_1; //此段程序好像有问题
delay(2);
asm("nop");
asm("nop");
}
return byte;
}
//============================================
/***********************************
函数名称:DS18B20 写1个字节
函数参数:输入数据、通道号
返 回 值:无
备 注:无
**********************************/
void ds18b20_write(uchar cmd)
{
unsigned char i,j;
WRIT_DDR_1;
for(j=0;j<=7;j++)
{
i=cmd&0x01;
if(i==0x01)
{
WRIT_POT_0;
delay(5);
WRIT_POT_1;
delay(50);
}
else
{
WRIT_POT_0;
delay(50);
WRIT_POT_1;
delay(5);
}
cmd=cmd>>1;
}
}
//==========================================
//延时程序 (dt)us,晶振(4M);0.25us
void delay(unsigned int dt)
{
do
dt--;
while(dt>1);
}
//===============================================================
评论