正文

51单片机使用18B20温度采集c51源程序2013-11-10 00:23:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/enc999/54342.html

分享到:

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

阅读(2105) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册