/*温度采集程序 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); } //===============================================================

评论