单片机/MCU论坛
直播中

赵婧

11年用户 13经验值
擅长:基础元器件
私信 关注
[文章]

温度采集器

要求是51和DS18B20显示当下温度;精确到小数点后一位;有上下限后报警(灯);按键可加可不加的;帮着看下接线图和程序正确否?谢谢各位专业人士了;


#include

#define PORT_DATA   P0
#define PORT_SELECT P2
#define PORT_KEY    P1

#define KEY_UP      0x01    //按键+
#define KEY_DOWN    0x02    //按键-

***it DQ = P1^7;  //数据引脚定义
//***it SPEAKER = P2^4;
unsigned charSPEAKER = 0;

unsigned charTrg;              //按键触发
unsigned charCont;             //长按值
unsigned intT_max;
unsigned charcode SEG_CODE[] = {
    0xA0,/*0*/
    0xBB,/*1*/
    0x62,/*2*/
    0x2A,/*3*/
    0x39,/*4*/
    0x2C,/*5*/
    0x24,/*6*/
    0xBA,/*7*/
    0x20,/*8*/
    0x28,/*9*/
    0x64,/*E10*/
    0x77,/*r11*/
    0x7F,/*-12*/
    0xFF /*  13*/
};  //共阳表
unsigned charcode SEG_SEL[]={
    0xFB,
    0xF7,
    0xFD,
    0xFE
};
/*******微秒延时*********/
void Delayus(unsignedint dUT)
{
    while(dUT--);
}

/*******毫秒延时*********/
void Delayms(unsignedint dT)
{
    unsigned intdA,dB;
    for(dA=0;dA         for(dB=0; dB<113;dB++)
            ;
}

/******************************************************************************/
unsigned charInit_DS18B20(void)//初始化ds1820温度传感器
{
    unsigned charx=0,dsExt;
    DQ = 1;        //DQ复位
    Delayus(16);    //稍做延时
    DQ = 0;        //单片机DQ拉低
    Delayus(100);    //精确延时 大于 480us
    DQ = 1;        //拉高总线
    Delayus(4);
    x = DQ;           //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
    Delayus(60);
    return x;
}

/******************************************************************************/
unsigned charReadOneChar(void)//读一个字节(DS18B20驱动)
{
    unsigned chari=0;
    unsigned chardat=0;
    for (i=8;i>0; i--)
    {
        DQ = 0;    // 给脉冲信号
        dat>>=1;
        DQ = 1;    // 给脉冲信号
        if(DQ)
            dat |= 0x80;
        Delayus(4);
    }
    return(dat);
}
/******************************************************************************/
void WriteOneChar(unsignedchar dat)//写一个字节(DS18B20驱动)
{
    unsigned chari=0;
    DQ = 0;
    Delayus(5);
    for (i=8;i>0; i--)
    {
        DQ = 0;
        DQ = dat & 0x01;
        Delayus(4);
        DQ = 1;
        dat>>=1;
    }
}
/******************************************************************************/
unsigned intReadTemperature(void)//读取温度(DS18B20驱动)
{
    unsigned charTL,TH;
    unsigned intt=0;
    float tt=0;
    bit flag=0;
    if ( Init_DS18B20() == 1 )
        return 2345;        //不存在标志
    WriteOneChar(0xCC);    // 跳过读序号列号的操作
    WriteOneChar(0x44);    // 启动温度转换
    if ( Init_DS18B20() == 1 )
        return 2345;
    WriteOneChar(0xCC);    //跳过读序号列号的操作
    WriteOneChar(0xBE);    //读取温度寄存器
    TL = ReadOneChar();        //读低8
    TH = ReadOneChar();        //读高8
    t = TH;
    t <<= 8;
    t = t|TL;
    if( t>0x8000) {
        t = ~t+1;
        tt = t*0.0625;
        t = tt*10+0.5;     //放大10倍输出并四舍五入
        t = t | 0x8000;    //存入负温度标志
    } else {
        tt=t*0.0625;
        t= tt*10+0.5;      //放大10倍输出并四舍五入
    }
    return(t);
}

void DispTem(unsignedint tC)
{
    unsigned chari,sT[4];

    if (tC == 2345) {           //DS18B20不存在
        sT[0]= 13;            //
        sT[1]= 10;            //E
        sT[2]= 11;            //r
        sT[3]= 11;            //r
        for (i=0; i<4; i++)
        {
            PORT_DATA = SEG_CODE[ sT];
            PORT_SELECT =SEG_SEL&(~(SPEAKER<<4));
            Delayms(2);          //
延时,显示一段时间
            PORT_SELECT = 0xff&(~(SPEAKER<<4));    //
关闭显示,防止重影
        }
    } else {
        if ( tC& 0x8000)
        {
            tC &= 0x7FFF;       //
去掉最高位的负温度标志
            sT[0]= 12;         //-
        }
        else
            sT[0]= 13;         //

        
        if (tC> T_max*10)      //
超温报警
        {
            SPEAKER = 1;
        } else {
            SPEAKER = 0;
        }
        
        sT[0]= tC / 1000;      //
百位
        sT[1]= tC % 1000 / 100;//
十位
        sT[2]= tC % 100 / 10;  //
个位
        sT[3]= tC % 10;       //
小数位

        if (sT[0] == 0){       //
去左边的0
            sT[0]= 13;
            if(sT[1] == 0){
                sT[1] = 13;
            }
        }
        for (i=0; i<4; i++)
        {
            if(i == 2)
                PORT_DATA =SEG_CODE[ sT] & 0xDF;    //
点亮小数点
            else
                PORT_DATA =SEG_CODE[ sT];

            PORT_SELECT = SEG_SEL&(~(SPEAKER<<4));
            Delayms(2);         //
延时,显示一段时间
            PORT_SELECT = 0xff&(~(SPEAKER<<4));   //
关闭显示,防止重影
        }
    }
}

//
读按键值
void KeyRead( void)
{
    unsigned charReadData = P1^0xff;   //
读端口值,并取反
    ReadData &= (KEY_UP | KEY_DOWN);                  //
只取有效按键值
    Trg = ReadData & (ReadData ^ Cont); //
只在第一次按下时为按键值,以后为0
    Cont = ReadData;                   //
长按、短按都为按键值
}

//
报警上限温度显示函数
void DispMaxTem(void)
{
    PORT_DATA = SEG_CODE[T_max/10];    //
显示报警上限温度
    PORT_SELECT = SEG_SEL[2];
    Delayms(2);
    PORT_SELECT = 0xFF;
    PORT_DATA = SEG_CODE[T_max%10];
    PORT_SELECT = SEG_SEL[3];
    Delayms(2);
    PORT_SELECT = 0xFF;
}

//
最高温度修改函数
void MaxTem(void)
{
    unsigned intcount=0;
    while(1){                  //
如果处于修改状态
        PORT_KEY = 0xFF;
        KeyRead();             //
读按键
        if ((Cont == 0x00) && (count > 0) )   //“+”
处理
        {
            T_max++;
            if(T_max>99)
            {
                T_max = 99;     //
上限为99
            }
            count = 0;
        }
        if (Cont& KEY_UP)
        {
            count++;
            if(count > 200)
            {
                count = 0;
                break;          //
长按,跳出该程序,进入主程序显示温度
            }
        }
        if (Trg& KEY_DOWN)     //“-”
处理
        {
            if(T_max < 1)
            {
                T_max = 0;      //
下限为0
            } else{
                T_max--;
            }
        }
        DispMaxTem();          //
显示上限温度
        ReadTemperature();     //
增加刷新间隔时间,降低亮度
    }
}

void main(void)
{
    unsigned inttem,count;

    T_max = 50;                       //
初始报警上限温度
    SPEAKER = 0;                      //
关蜂鸣器

    while(1)
    {
        tem = ReadTemperature();       //
读温度
        DispTem(tem);                  //
显示温度
        PORT_KEY = 0xFF;
        KeyRead();                     //
读按键状态
        if(Cont&KEY_UP)             //“+”
键按下
        {
            count++;
            if(count > 150)           //
长按+,松开后进入修改模式
            {
                count = 0;
                while(Cont != 0)       //
等待按键松开
                {
                   PORT_KEY = 0xFF;
                   KeyRead();
                   DispMaxTem();       //
显示最高温度
                   ReadTemperature();  //
增加刷新间隔时间,降低亮度
                }
               MaxTem();               //
到报警上限修改模式
            }
        }
        if ((Cont== 0x00) && (count>0))//
短按,重新计数
        {
            count = 0;
        }
    }
}















































  • 接线图

回帖(1)

齐磊

2016-4-17 18:15:36
好好学习天天向上
举报

更多回帖

发帖
×
20
完善资料,
赚取积分