单片机显示时间跟温度_32单片机lcd如何显示温度传感器的温度 - CSDN
  • 单片机】时钟及温度显示

    千次阅读 2015-05-21 20:30:43
    在前面文章《我的2013–一起从心开始》一文中写道,我在大一暑假的时候开始了单片机的学习,在大二、大三期间做过些小东西。刚进入程序员的领域的时候,显然是单片机带我入了门。下面我将写写用单片机做过的一些东西...

    回头看我所写的文章,基本都是软件方面的,是个典型的“欺软怕硬”的人。然而,在最开始的时候,我学习的是硬件。在前面文章《我的2013–一起从心开始》一文中写道,我在大一暑假的时候开始了单片机的学习,在大二、大三期间做过些小东西。刚进入程序员的领域的时候,显然是单片机带我入了门。下面我将写写用单片机做过的一些东西,权当纪念。


    本文介绍我大一暑假学完单片机后,在大二上学期为参加学校星火杯而完成的作品(最终没有参加比赛)。这个电子制作是关于用单片机显示时间的作品,其功能就用单片机控制LCD、LED来显示时间和温度。


    功能描述

    • 显示精确度为0.1摄氏度的温度(低于0摄氏度和高于100摄氏度响铃)
    • 液晶时钟,断电后仍然继续走动,每月误差不到一分钟,无电源可工作10年左右,区分平年和闰年;
    • 指针式时钟(黄灯为时针,红色为分针,最小误差5分钟,整点报时)与考试计时器(计时2两小时)

    电子元器件

    • 2个单片机最小系统 (单片机型号为STC89C52)
    • 双色发光二级管
    • 液晶显示屏
    • 按键
    • DS12C887时钟芯片
    • DS18b20温度传感器
    • 蜂鸣器(整点报时)
    • LED数码管(显示温度)

    作品展示图

    • 由于所有电路都是由杜邦线连接,所以存在接触不良,导致有时不能正常显示,于是就没有参赛,下图为双色二极管的显示。
      这里写图片描述
      这里写图片描述
    • 下图为用1602液晶显示日期和时间
      这里写图片描述
      这里写图片描述
    • 下图为用数码管来显示温度
      这里写图片描述
    • 下图为作品的布线,简直是乱成一团,要是用PCB就好了。
      这里写图片描述

    原文:http://blog.csdn.net/tengweitw/article/details/45895989
    作者:nineheadedbird

    附录:代码实现

    对于硬件来说,给代码不给管脚图没啥意义,不过由于年代久远,我已经找不到当初设计的电路图了。但仍然给出代码图,希望能起到一点点的参考作用。

    //--------------------------------温度显示程序 第一个芯片------------------------------------------------------------------//
    
    #include<reg52.h>
    #include<intrins.h>
    #include<stdio.h>
    #define uchar unsigned char 
    #define uint unsigned int
    
    sbit ds=P2^2;
    
    unsigned int te;
    
    unsigned char code tabledu[]=
    { 
    0x3f0x060x5b0x4f
    0x660x6d0x7d0x07 
    0x7f0x6f0x770x7c
    0x390x5e0x790x71
    };
    unsigned char code tabledu1[]=
    { 
    0xbf0x860xdb0xcf
    0xe60xed0xfd0x87 
    0xff0xef0xf70xfc
    0x390x5e0x790x71
    };
    
    unsigned char code tablewe[]=
    {
    0xfe0xfd0xfb0xf70xef0xdf
    };
    
    
    void delayxms(unsigned int x)
    {
    unsigned int ij; 
    for(i=x;i>0;i--)
    for(j=110;j>0;j--);
    }
    
    
    
    void delayx2us(unsigned char t)
    { 
    while(--t);
    }
    
    
    void dsreset() // 复位
    {
    ds=1;
    _nop_();
    ds=0;
    delayx2us(200);//注意时间
    ds=1;
    delayx2us(20);
    
    }
    
    
    void writetemp(unsigned char dat)
    {
    unsigned char i=0;
    for (i=8; i>0; i--)
    {
    ds = 0;
    ds = dat&0x01;
    delayx2us(25);
    ds = 1;
    dat>>=1;
    }
    delayx2us(25);
    }
    
    
    unsigned char readtemp(void)
    {
    unsigned char i=0;
    unsigned char dat = 0;
    for (i=8;i>0;i--)
    {
    ds = 0; // 给脉冲信号
    dat>>=1;
    ds = 1; // 给脉冲信号
    if(ds)
    dat|=0x80;
    delayx2us(25);
    }
    return(dat);
    }
    
    uint temp()
    {
    uint ab;
    dsreset();
    delayxms(1);
    writetemp(0xcc);
    writetemp(0x44);
    delayxms(1);
    
    dsreset();
    delayxms(1);
    writetemp(0xcc);
    writetemp(0xbe);
    delayx2us(50);
    a=readtemp();
    b=readtemp();
    a=a*10;
    te=b*160+a/16;
    
    return te;
    }
    
    void disp(long int num)
    {
    uchar cde;
    c=num/100;
    d=num%100/10;
    e=num%10;
    
    P0=tabledu[c];
    P1=0xfe;
    delayxms(6);
    P0=tabledu1[d];
    P1=0xfd;
    delayxms(6);
    P0=tabledu[e];
    P1=0xfb;
    delayxms(6);
    P0=0xcc;
    P1=0xf7;
    delayxms(2);
    
    }
    
    
    void main()
    {
    
    while(1)
    {
    disp(temp());
    if((temp()>=1000)||(temp()<=0))
    beep=0;
    else
    beep=1;
    
    
    }
    
    
    
    
    
    //--------------------------------时钟显示程序 第二个芯片------------------------------------------------------------------//
    #include<reg52.h>
    
    #define uchar unsigned char 
    #define uint unsigned int
    
    
    
    //流水灯锁存器
    sbit wela1=P2^0;//1
    sbit wela2=P2^1;//2
    sbit wela3=P2^2;//1
    sbit wela4=P2^3;//2
    
    //蜂鸣器
    sbit beep=P2^4;
    
    //按键
    sbit key1=P2^5;//功能选择键
    sbit key2=P2^6;//+(时间、日期加)
    sbit key3=P2^7;//-(时间、日期减)
    sbit key4=P3^7;//模式键(平时或考试)
    
    
    
    //液晶接口
    sbit lcden=P3^4;
    sbit lcdrs=P3^5;
    sbit lcdwr=P3^6;
    
    //ds12c887接口
    sbit dscs=P1^6;
    sbit dsas=P1^7;
    sbit dsrw=P3^0;
    sbit dsds=P3^1;
    sbit dsirq=P3^3;
    
    
    //定义变量
    uchar hour minseccountriweekyuenianj;
    //uchar counthcountmcountycountkloop1;
    uchar code table1[]=" - - ";
    uchar code table2[]=" : : ";
    uchar code table3[]="SUNMONTUEWEDTHUFRISAT";
    
    
    
    //延迟函数
    void delayxms(unsigned int x) 
    {
    unsigned int ij; 
    for(i=x;i>0;i--)
    for(j=110;j>0;j--);
    }
    
    
    
    //--------------------1602液晶函数----------------------------------
    
    
    
    
    //液晶写命令
    void write_com(unsigned char com) 
    {
    lcdrs=0;
    P0=com;
    delayxms(5);
    lcden=1;
    delayxms(5); 
    lcden=0;
    }
    
    //液晶写数据
    void write_data(unsigned char date)
    {
    lcdrs=1;
    P0=date;
    delayxms(5); 
    lcden=1;
    delayxms(5);
    lcden=0;
    }
    
    //液晶初始化
    void lcdinit()
    {
    lcdwr=0;
    write_com(0x38);
    write_com(0x0c);
    write_com(0x06); 
    write_com(0x01);
    
    }
    
    // 液晶显示
    void disp() 
    {
    uchar i;
    
    write_com(0x80);
    for(i=0;i<15;i++)
    {
    write_data(table1[i]);
    delayxms(5);
    }
    write_com(0x80+0x40);
    for(i=0;i<12;i++)
    {
    write_data(table2[i]);
    delayxms(5);
    }
    }
    
    
    //写时间
    void write_sfm(uchar addressuchar shu) 
    {
    uchar shige;
    shi=shu/10;
    ge=shu%10;
    write_com(0x80+0x40+address);
    write_data(0x30+shi);
    write_data(0x30+ge);
    }
    
    
    //写日历
    void write_calendar(uchar addressuchar shu) 
    {
    uchar shige;
    shi=shu/10;
    ge=shu%10;
    write_com(0x80+address);
    write_data(0x30+shi);
    write_data(0x30+ge);
    }
    
    
    //-------------------------DS12C887程序----------------------------
    //写时钟
    void write_ds(uchar adduchar date)
    {
    dscs=0;
    dsas=1;
    dsds=1;
    dsrw=1;
    P0=add;
    dsas=0;
    dsrw=0;
    P0=date;
    dsrw=1;
    dsas=1;
    dscs=1;
    }
    
    
    //读时钟
    uchar read_ds(uchar add)
    {
    uchar ds_date;
    dsas=1;
    dsds=1;
    dsrw=1;
    dscs=0;
    P0=add;
    dsas=0;
    dsds=0;
    P0=0xff;
    ds_date=P0;
    dsds=1;
    dsas=1;
    dscs=1;
    return ds_date;
    }
    
    //写星期
    void write_week(uchar date)
    {
    
    write_com(0x80+12);
    write_data(table3[3*date]);
    write_data(table3[3*date+1]);
    write_data(table3[3*date+2]);
    }
    
    
    
    
    //键盘检测
    void keyscan() //键盘检测 key1 为功能键 key2为加 key3为减 :时间与日期的改变
    {
    
    if(key1==0)
    {
    delayxms(10);
    if(key1==0)
    {
    while(!key1);
    count++;
    
    if(count==1)
    {
    
    write_com(0x80+0x40+11);
    write_com(0x0f);
    
    }
    
    if(count==2)
    {
    
    write_com(0x80+0x40+8);
    write_com(0x0f);
    
    }
    
    if(count==3)
    {
    
    write_com(0x80+0x40+5);
    write_com(0x0f);
    
    }
    if(count==4)
    {
    write_com(0x80+13);
    write_com(0x0f);
    }
    if(count==7)
    {
    write_com(0x80+10);
    write_com(0x0f);
    }
    if(count==6)
    {
    write_com(0x80+7);
    write_com(0x0f);
    }
    if(count==5)
    {
    write_com(0x80+4);
    write_com(0x0f);
    }
    
    if(count==8)
    {
    
    count=0;
    write_com(0x0c);
    write_ds(0sec);
    write_ds(2min);
    write_ds(4hour);
    }
    }
    }
    
    
    if(key2==0)
    {
    delayxms(10);
    if(key2==0)
    {
    while(!key2);
    if(count==1)
    {
    sec++;
    if(sec==60)
    sec=0;
    write_ds(0sec);
    write_sfm(10sec);
    write_com(0x80+0x40+11);
    }
    
    if(count==2)
    {
    min++;
    if(min==60)
    min=0;
    write_ds(2min);
    write_sfm(7min);
    write_com(0x80+0x40+8);
    }
    
    
    if(count==3)
    {
    hour++;
    
    if(hour==24)
    hour=0;
    write_ds(4hour);
    write_sfm(4hour);
    write_com(0x80+0x40+5);
    }
    
    if(count==4)
    {
    week++;
    if(week==7)
    week=0;
    write_week(week);
    write_ds(6week);
    
    }
    
    
    if(count==5)
    {
    nian++;
    if(nian==100)
    nian=0;
    write_ds(9nian);
    write_calendar(3nian);
    write_com(0x80+4);
    }
    
    if(count==6)
    {
    yue++;
    if(yue==13)
    yue=1;
    write_ds(8yue);
    write_calendar(6yue);
    write_com(0x80+7);
    }
    
    if(count==7) // 判断闰年
    {
    ri++;
    week++;
    if(nian%4==0)
    {
    if((yue==4)||(yue==6)||(yue==9)||(yue==11))
    {
    if(ri==31)
    ri=1;
    }
    else if(yue==2)
    {
    if(ri==30)
    ri=1;
    }
    else
    {
    if(ri==32)
    ri=1;
    }
    }
    
    if(nian%4!=0)
    {
    if((yue==4)||(yue==6)||(yue==9)||(yue==11))
    {
    if(ri==31)
    ri=1;
    }
    else if(yue==2)
    {
    if(ri>=29)
    ri=1;
    }
    else
    {
    if(ri==32)
    ri=1;
    }
    }
    write_ds(7ri);
    write_calendar(9ri);
    write_com(0x80+10);
    delayxms(2);
    if(week==7) 
    week=0;
    write_week(week);
    write_ds(6week);
    
    
    }
    
    
    
    
    }
    }
    
    if(key3==0)
    {
    delayxms(10);
    if(key3==0)
    {
    while(!key3);
    if(count==1)
    {
    if(sec==0)
    sec=59;
    else
    sec--;
    write_ds(0sec);
    write_sfm(10sec);
    write_com(0x80+0x40+11);
    }
    
    if(count==2)
    {
    if(min==0)
    min=59;
    else
    min--;
    write_ds(2min);
    write_sfm(7min);
    write_com(0x80+0x40+8);
    }
    
    
    if(count==3)
    {
    if(hour==0)
    hour=23;
    else
    hour--;
    write_ds(4hour);
    write_sfm(4hour);
    write_com(0x80+0x40+5);
    }
    if(count==5)
    {
    
    if(nian==0)
    nian=99;
    else
    nian--;
    write_ds(9nian);
    write_calendar(3nian);
    write_com(0x80+4);
    
    }
    if(count==6)
    {
    
    if(yue==1)
    yue=12;
    else
    yue--;
    write_ds(8yue);
    write_calendar(6yue);
    write_com(0x80+7);
    }
    
    
    if(count==7) // 判断闰年
    {
    ri--;
    week--;
    if(nian%4==0)
    {
    if((yue==4)||(yue==6)||(yue==9)||(yue==11))
    {
    if(ri==0)
    ri=30;
    }
    else if(yue==2)
    {
    if(ri==0)
    ri=29;
    }
    else
    {
    if(ri==0)
    ri=31;
    }
    }
    
    if(nian%4!=0)
    {
    if((yue==4)||(yue==6)||(yue==9)||(yue==11))
    {
    if(ri==0)
    ri=30;
    }
    else if(yue==2)
    {
    if(ri==0)
    ri=28;
    }
    else
    {
    if(ri==0)
    ri=31;
    }
    }
    write_ds(7ri);
    write_calendar(9ri);
    write_com(0x80+10);
    delayxms(2);
    if(week==-1) 
    week=7;
    write_week(week);
    write_ds(6week);
    
    
    }
    
    
    }
    }
    }
    
    //----------------初始化---------------------------------//
    void init()
    {
    lcdinit();
    
    disp();
    week=0;
    nian=11;
    yue=9;
    ri=1;
    
    }
    
    
    //---------------------------流水灯-----------------------------------//
    void lampinit()
    {
    P1=0xff;
    wela1=1;
    wela2=1;
    wela3=1;
    wela3=1;
    wela1=0;
    wela2=0;
    wela3=0;
    wela4=0;
    
    }
    //----------------时钟用黄灯显示程序-------------------------------//
    void clock()
    {
    if((hour==1)&&(hour==13))
    {
    P1=0xfd;
    wela3=1;
    wela3=0;
    }
    
    if((hour==2)&&(hour==14))
    {
    P1=0xfb;
    wela3=1;
    wela3=0;
    }
    
    if((hour==3)&&(hour==15))
    {
    P1=0xf7;
    wela3=1;
    wela3=0;
    }
    
    if((hour==4)&&(hour==16))
    {
    P1=0xef;
    wela3=1;
    wela3=0;
    }
    if((hour==5)&&(hour==17))
    {
    P1=0xdf;
    wela3=1;
    wela3=0;
    }
    if((hour==6)&&(hour==18))
    {
    P1=0xfe;
    wela4=1;
    wela4=0;
    }
    if((hour==7)&&(hour==19))
    {
    P1=0xfd;
    wela4=1;
    wela4=0;
    }
    if((hour==8)&&(hour==20))
    {
    P1=0xfb;
    wela4=1;
    wela4=0;
    }
    if((hour==9)&&(hour=21))
    {
    P1=0xf7;
    wela4=1;
    wela4=0;
    }
    if((hour==10)&&(hour==22))
    {
    P1=0xef;
    wela4=1;
    wela4=0;
    }
    if((hour==11)&&(hour==23))
    {
    P1=0xdf;
    wela4=1;
    wela4=0;
    }
    if((hour==12)&&(hour==0))
    {
    P1=0xfe;
    wela3=1;
    wela3=0;
    }
    
    
    if(min<5)
    {
    if((hour!=12)&&(hour!=24))
    {
    P1=0xfe;
    wela1=1;
    wela1=0;
    }
    }
    //----------------分钟用红灯显示------------------------//
    
    if((min>=5)&&(min<10))
    {
    if((hour!=13)&&(hour!=1))
    {
    P1=0xfd;
    wela1=1;
    wela1=0;
    }
    }
    
    if((min>=10)&&(min<15))
    {
    if((hour!=14)&&(hour!=2))
    {
    P1=0xfb;
    wela1=1;
    wela1=0;
    }
    }
    
    if((min>=15)&&(min<20))
    {
    if((hour!=15)&&(hour!=3))
    {
    P1=0xf7;
    wela1=1;
    wela1=0;
    }
    }
    
    if((min>=20)&&(min<25))
    {
    if((hour!=16)&&(hour!=4))
    {
    P1=0xef;
    wela1=1;
    wela1=0;
    }
    }
    
    
    if((min>=25)&&(min<30))
    {
    if((hour!=17)&&(hour!=5))
    {
    P1=0xdf;
    wela1=1;
    wela1=0;
    }
    }
    
    if((min>=30)&&(min<35))
    {
    if((hour!=18)&&(hour!=6))
    {
    P1=0xfe;
    wela2=1;
    wela2=0;
    }
    }
    
    if((min>=35)&&(min<40))
    {
    if((hour!=19)&&(hour!=7))
    {
    P1=0xfd;
    wela2=1;
    wela2=0;
    }
    }
    
    
    if((min>=40)&&(min<45))
    {
    if((hour!=20)&&(hour!=8))
    {
    P1=0xfb;
    wela2=1;
    wela2=0;
    }
    }
    
    if((min>=45)&&(min<50))
    {
    if((hour!=21)&&(hour!=9))
    {
    P1=0xf7;
    wela2=1;
    wela2=0;
    }
    }
    
    if((min>=50)&&(min<55))
    {
    if((hour!=22)&&(hour!=10))
    {
    P1=0xef;
    wela2=1;
    wela2=0;
    }
    }
    if(min>=55)
    {
    if((hour!=23)&&(hour!=11))
    {
    P1=0xdf;
    wela2=1;
    wela2=0;
    }
    }
    
    }
    //---------------考试倒计时模式-----------------------//
    
    void test()
    {
    uchar hour1min1min2shi;
    hour1=hour+2;
    if(hour==24)
    hour1=0;
    if(hour==25)
    hour1=1;
    
    min1=min+20;
    if(min1>=60)
    {
    min1=min1-60;
    hour1=hour1+1;
    if(hour1==24)
    hour1=0;
    }
    
    shi=min1/10;
    min1=shi*10;
    
    
    
    if((min==min1)&&(sec==0))
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xfe;
    wela3=1;
    wela3=0;
    
    }
    
    
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xfc;
    wela1=1;
    wela1=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xf8;
    wela1=1;
    wela1=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xf0;
    wela1=1;
    wela1=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xe0;
    wela1=1;
    wela1=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xc0;
    wela1=1;
    wela1=0;
    
    }
    //-------------------------------------------------//
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xfe;
    wela2=1;
    wela2=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xfc;
    wela2=1;
    wela2=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xf8;
    wela2=1;
    wela2=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xf0;
    wela2=1;
    wela2=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xe0;
    wela2=1;
    wela2=0;
    
    }
    
    if(min==min2)
    {
    min2=min+5;
    if(min2==60)
    min2=0;
    P1=0xc0;
    wela2=1;
    wela2=0;
    
    }
    //----------------------时间到后开始响铃------------------------------------------//
    if(min==min2)
    {
    
    P1=0;
    wela1=1;
    wela1=0;
    beep=0;
    delayxms(1000);
    beep=1;
    delayxms(1000);
    beep=0;
    delayxms(1000);
    beep=1;
    beep=0;
    delayxms(1000);
    beep=1;
    delayxms(1000);
    beep=0;
    delayxms(6000);
    delayxms(6000);
    beep=1;
    
    lampinit();
    
    }
    }
    
    
    
    
    //-----------------主函数--------------------------------------//
    void main()
    {
    init();
    while(1)
    {
    
    keyscan();
    
    
    if(count==0)
    {
    sec=read_ds(0);
    min=read_ds(2);
    hour=read_ds(4);
    week=read_ds(6);
    nian=read_ds(9);
    yue=read_ds(8);
    ri=read_ds(7);
    write_sfm(10sec);
    write_sfm(7min);
    write_sfm(4hour);
    write_week(week);
    
    write_calendar(3nian);
    write_calendar(6yue);
    write_calendar(9ri);
    write_calendar(120);
    
    }
    
    }
    
    }
    展开全文
  • 基于51单片机LCD1602显示时钟(温度报警),程序,仿真图,元器件表
  • 51单片机LCD显示温度与串口接受温度

    千次阅读 2019-02-12 21:45:04
    外接晶振为12MHz时,51单片机相关周期的具体值为: 振荡周期=1/12us; 状态周期=1/6us; 机器周期=1us; 指令周期=1~4us; 51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于...

    外接晶振为12MHz时,51单片机相关周期的具体值为:

    振荡周期=1/12us;
    状态周期=1/6us;
    机器周期=1us;
    指令周期=1~4us;

    51单片机定时/计数器的工作由两个特殊功能寄存器控制。TMOD用于设置其工作方式;TCON用于控制其启动和中断申请。
    1、工作方式寄存器TMOD
    工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下:
    在这里插入图片描述
    GATE是门控位, GATE=0时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。
    C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。
    M1M0:工作方式设置位。定时/计数器有四种工作方式。
    在这里插入图片描述
    控制寄存器TCON
    TCON的高4位用于控
    制定时/计数器的启动和中断申请。其格式如下:
    在这里插入图片描述
    TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。T1工作时,CPU可随时查询TF1的状态。所以,TF1可用作查询测试的标志。TF1也可以用软件置1或清0,同硬件置1或清0的效果一样。
    TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
    TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。
    TR0(TCON.4):T0运行控制位,其功能与TR1类同。

    定时/计数器的工作方式

    1、方式1
    方式1的计数位数是16位,由TL0作为低8位,TH0
    作为高8位,组成了16位加1计数器 。计数个数与计数初值的关系为:X=2(16次方)-N

    2、方式2
    为自动重装初值的8位计数方式。 计数个数与计数初值的关系为:X=28-N
    工作方式2特别适合于用作较精确的脉冲信号发生器。所以串口通信处用此方式。

    计数器初值的计算
    机器周期也就是CPU完成一个基本操作所需要的时间。
    机器周期=1/单片机的时钟频率。
    51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用12MHZ的外部晶振的时候。机器周期=1/1M=1us。
    而我们定时1ms的初值是多少呢,1ms/1us=1000。也就是要计数1000个数,初值=65535-1000+1(因为实际上计数器计数到66636才溢出)=64536=FC18H

    串口通信
    比特率是每秒钟传输二进制代码的位数,单位是:位/秒(bps)。如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位、1个停止位、8个数据位),这时的比特率为:
    10位×240个/秒 = 2400 bps

    SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志:在这里插入图片描述
    SM0和SM1为工作方式选择位,可选择四种工作方式:
    在这里插入图片描述
    SM2,多机通信控制位,主要用于方式2和方式3。当接收机的SM2=1时可以利用收到的RB8来控制是否激活RI(RB8=0时不激活RI,收到的信息丢弃;RB8=1时收到的数据进入SBUF,并激活RI,进而在中断服务中将数据从SBUF读走)。当SM2=0时,不论收到的RB8为0和1,均可以使收到的数据进入SBUF,并激活RI(即此时RB8不具有控制RI激活的功能)。通过控制SM2,可以实现多机通信。
    在方式0时,SM2必须是0。在方式1时,如果SM2=1,则只有接收到有效停止位时,RI才置1。
    REN,允许串行接收位。由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收

    TI,发送中断标志位。在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI置1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。

    RI,接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请。

    PCON中只有一位SMOD与串行口工作有关 :SMOD(PCON.7) 波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0。

    80C51串行口的工作方式
    这里只介绍方式1:
    方式1是10位数据的异步通信口。TXD为数据发送引脚,RXD为数据接收引脚,传送一帧数据的格式如图所示。其中1位起始位,8位数据位,1位停止位。
    在这里插入图片描述
    在这里插入图片描述
    用软件置REN为1时,接收器以所选择波特率的16倍速率采样RXD引脚电平,检测到RXD引脚输入电平发生负跳变时,则说明起始位有效,将其移入输入移位寄存器,并开始接收这一帧信息的其余位。接收过程中,数据从输入移位寄存器右边移入,起始位移至输入移位寄存器最左边时,控制电路进行最后一次移位。当RI=0,且SM2=0(或接收到的停止位为1)时,将接收到的9位数据的前8位数据装入接收SBUF,第9位(停止位)进入RB8,并置RI=1,向CPU请求中断。

    方式1的波特率 =(2SMOD/32)·(T1溢出率)
    T1 溢出率 = fosc /{12×[256 -(TH1)]}

    在这里插入图片描述

    DS18B20温度传感器原理
    DS18B20温度转换规则
    DS18B20的核心功能是它可以直接读出数字的温度数值。温度传感器的精度为用户可编程的9,10,11或12位,分别以0.5℃,0.25℃,0.125℃和0.0625℃增量递增。在上电状态下默认的精度为12位。

    在这里插入图片描述
    这是12位转化后得到的12位数据,存储在DS18B20的两个8位的RAM中,高字节的前5位是符号位,如果测得的温度大于0,这5位为‘0’,只要将测到的数值乘以0.0625即可得到实际温度;如果温度小于0,这5位为‘1’,测到的数值需要先减1再取反再乘以0.0625即可得到实际温度。

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    (1).数据线拉到低电平“0”。
    (2).延时480微妙(该时间的时间范围可以从480到960微妙)。
    (3).数据线拉到高电平“1”。
    (4).延时等待80微妙。如果初始化成功则在15到60微妙时间内产生一个由DS18B20所返回的低电平“0”.根据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时判断。
    (5).若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(3)步的时间算起)最少要480微妙。

    读时序
    在这里插入图片描述
    (1).将数据线拉低“0”。
    (2).延时1微妙。
    (3).将数据线拉高“1”,释放总线准备读数据。
    (4).延时10微妙。
    (5).读数据线的状态得到1个状态位,并进行数据处理。
    (6).延时45微妙。
    (7).重复1~7步骤,直到读完一个字节。

    写时序
    在这里插入图片描述
    (1).数据线先置低电平“0”
    (2).延时15微妙。
    (3).按从低位到高位的顺序发送数据(一次只发送一位)。
    (4).延时60微妙。
    (5).将数据线拉到高电平。
    (6).重复1~5步骤,直到发送完整的字节。
    (7).最后将数据线拉高。

    #include<reg51.h>	
    #define LCD1602_DATAPINS P0
    
    typedef	 unsigned int	  uint;
    typedef unsigned char	 uchar;
    
    sbit LCD1602_E=P2^7;
    sbit LCD1602_RW=P2^5;
    sbit LCD1602_RS=P2^6;
    sbit DSPORT=P3^7;
    
    uchar CNCHAR[6] = "摄氏度";
    
    void LcdInit();
    void LcdWriteData(uchar dat);
    void LcdWriteCom(uchar com);
    void LcdDisplay(int);
    void UsartConfiguration();
    uchar init();
    void writebyte(uchar datas);
    void change_temper();
    void read_tempercom();
    uint read_temper();
    uchar readbyte();
    void DelayMs(unsigned int x);
    
    void main(void)	
    {
    	UsartConfiguration();
    	LcdInit();			 //初始化LCD1602
    	LcdWriteCom(0x88);	//写地址 80表示初始地址
    	LcdWriteData('C'); 
    	while(1)
    	{
    		LcdDisplay(read_temper());
    //		Delay1ms(1000);//1s钟刷一次
    	}				
    }
    
    void DelayMs(unsigned int x)   //0.14ms误差 0us
    {
     unsigned char i;
      while(x--)
     {
      for (i = 0; i<13; i++)
     {}
     }
    }
    
    void LcdDisplay(int temp) 	 //lcd显示
    {
        
      	unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
    	float tp;  
    	if(temp< 0)				//当温度值为负数
      	{
    	  	LcdWriteCom(0x80);		//写地址 80表示初始地址
    		SBUF='-';//将接收到的数据放入到发送寄存器
    		while(!TI);			         //等待发送数据完成
    		TI=0;						 //清除发送完成标志位
    	    LcdWriteData('-');  		//显示负
    		//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
    		temp=temp-1;
    		temp=~temp;
    		tp=temp;
    		temp=tp*0.0625*100+0.5;	
    		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    		//算由?.5,还是在小数点后面。
     
      	}
     	else
      	{			
    	  	LcdWriteCom(0x80);		//写地址 80表示初始地址
    	    LcdWriteData('+'); 		//显示正
    		SBUF='+';//将接收到的数据放入到发送寄存器
    		while(!TI);			         //等待发送数据完成
    		TI=0;						 //清除发送完成标志位
    		tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
    		//如果温度是正的那么,那么正数的原码就是补码它本身
    		temp=tp*0.0625*100+0.5;	
    		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    		//算加上0.5,还是在小数点后面。
    	}
    	datas[0] = temp / 10000;
    	datas[1] = temp % 10000 / 1000;
    	datas[2] = temp % 1000 / 100;
    	datas[3] = temp % 100 / 10;
    	datas[4] = temp % 10;
    
    	LcdWriteCom(0x82);		  //写地址 80表示初始地址
    	LcdWriteData('0'+datas[0]); //百位 
    	SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    	
    	LcdWriteCom(0x83);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[1]); //十位
    	SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x84);		//写地址 80表示初始地址
    	LcdWriteData('0'+datas[2]); //个位 
    	SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x85);		//写地址 80表示初始地址
    	LcdWriteData('.'); 		//显示 ‘.’
    	SBUF = '.';//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x86);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[3]); //显示小数点  
    	SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    
    	LcdWriteCom(0x87);		 //写地址 80表示初始地址
    	LcdWriteData('0'+datas[4]); //显示小数点 
    	SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
    	while (!TI);			         //等待发送数据完成
    	TI = 0;
    	for(i=0; i<6; i++)
    	{
    	 	SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
    		while (!TI);			         //等待发送数据完成
    		TI = 0;
    	}
    
    	 
    }
    
    
    void UsartConfiguration()
    {
    	SCON=0X50;			//设置为工作方式1
    	TMOD=0X20;			//设置计数器工作方式2
    	PCON=0X80;			//波特率加倍
    	TH1=0XF3;				//计数器初始值设置,注意波特率是4800的
    	TL1=0XF3;
    //	ES=1;						//打开接收中断
    //	EA=1;						//打开总中断
    	TR1=1;					//打开计数器
    }
    
    
    /****************
    温度传感器部分
    ****************/
    uchar init()
    {
    	uchar i=0;
    	DSPORT=0;
    	i = 70;				   //将总线拉低480us~960us
    	while(i--);//延时642us
    	DSPORT=1;				 //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
    	i=0;
    	while(DSPORT)		   //等待DS18B20拉低总线
    	{
    		 DelayMs(1);
    		 i++;		  
    		 if(i>5)
    		 {
    		 	return 0;			 //初始化失败
    		 }
    	}
    	return 1;
    }
    
    void writebyte(uchar datas)
    {
    	uchar i,j=1;
    	for(i=0;i<8;i++)
    	{
    		DSPORT=0;		   //每写入一位数据之前先把总线拉低1us
    		//j++;		  //此处延时1us,好像又影响不大
    		DSPORT=datas&0x01;
    		j=6;
    		while(j--); //延时68us,持续时间最少60us
    		DSPORT=1;		 //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
    		datas>>=1;
    	}
    }
    
    uchar readbyte()
    {
    	uchar dat=0,temp;
    	uint i ,j;
    	for(i=0;i<8;i++)
    	{
    		DSPORT=0;	 //先将总线拉低1us
    		j++;
    		DSPORT=1;	//然后释放总线
    		j++;	  //此处延时有变化,等待6us
    		j++;
    		temp=DSPORT;	 //读取数据,从最低位开始读取
    		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
    		dat=(dat>>1)|(temp<<7);
    		j = 4;		//读取完之后等待48us再接着读取下一个数
    		while(j--);;			 //好像没影响
    	}
    	return dat;		//不是temp
    }
    
    void change_temper()
    {
    	init();
    	DelayMs(1);			   //无影响
    	writebyte(0xcc);		  //跳过ROM操作命令	
    	writebyte(0x44);		   //温度转换命令
    }
    
    void read_tempercom()
    {
       	init();
    	//DelayMs(1);
    	writebyte(0xcc);
    	writebyte(0xbe);		 //发送读取温度命令
    }
    
    uint read_temper()
    {
    	uchar tml,tmh;
    	uint t=0;
    	change_temper();			//先写入转换命令
    	read_tempercom();			//然后等待转换完后发送读取温度命令
    	tml=readbyte();				//读取温度值共16位,先读低字节
    	tmh=readbyte();				//再读高字节
    	t=tmh;
    	t<<=8;			//移8位
    	t=tml|t;
    
    	return t;
    }
    /********************
     LCD液晶部分
    ********************/
    
    void LcdWriteCom(uchar com)	  //写入命令
    {
    	LCD1602_E = 0;     //使能
    	LCD1602_RS = 0;	   //选择发送命令
    	LCD1602_RW = 0;	   //选择写入
    	
    	LCD1602_DATAPINS = com;     //放入命令
    	DelayMs(1);		//等待数据稳定
    
    	LCD1602_E = 1;	          //写入时序
    	DelayMs(5);	  //保持时间
    	LCD1602_E = 0;
    }
    
    void LcdWriteData(uchar dat)			//写入数据
    {
    	LCD1602_E = 0;	//使能清零
    	LCD1602_RS = 1;	//选择输入数据
    	LCD1602_RW = 0;	//选择写入
    
    	LCD1602_DATAPINS = dat; //写入数据
    	DelayMs(1);
    
    	LCD1602_E = 1;   //写入时序
    	DelayMs(5);   //保持时间
    	LCD1602_E = 0;
    }
    
    void LcdInit()						  //LCD初始化子程序
    {
     	LcdWriteCom(0x38);  //开显示
    	LcdWriteCom(0x0c);  //开显示不显示光标
    	LcdWriteCom(0x06);  //写一个指针加1
    	LcdWriteCom(0x01);  //清屏
    	LcdWriteCom(0x80);  //设置数据指针起点
    }
    

    LCD显示部分可以参考我一篇文章
    51单片机DS1302时钟LCD1602显示

    以上是我在学习过程中的一点总结,用的是普中的51单片机·。

    展开全文
  • 关于温度传感器读写函数的编写:温度传感器的读写函数编写 在上面的函数的前提下,读取温度传感器响应的数据并在数码管上显示即可。 利用Ds18b20ReadTemp()函数返回温度值。 编写datapros()函数处理传输过来的数据。...

    关于温度传感器读写函数的编写:温度传感器的读写函数编写
    在上面的函数的前提下,读取温度传感器响应的数据并在数码管上显示即可。
    利用Ds18b20ReadTemp()函数返回温度值。
    编写datapros()函数处理传输过来的数据。(DisplayData数组是用于存储显示数据的全局变量,smgduan用来存储标准的数码管显示数组)
    代码部分:

    void datapros(int temp) 	 
    {
       	float tp;  
    		if(temp< 0)				//当温度值为负数
      	{
    		DisplayData[0] = 0x40; 	  //   显示‘-’符号
    		//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
    		temp=temp-1;
    		temp=~temp;
    		tp=temp;
    		temp=tp*0.0625*100+0.5;	
    		//保留两位小数*100,+0.5达成四舍五入
      	}
     	else
      	{			
    		DisplayData[0] = 0x00;	//首位不显示
    		tp=temp;//数据处理有小数点将温度赋给一个浮点型变量
    		temp=tp*0.0625*100+0.5;	
    	}
    	DisplayData[1] = smgduan[temp / 10000];
    	DisplayData[2] = smgduan[temp % 10000 / 1000];
    	DisplayData[3] = smgduan[temp % 1000 / 100] | 0x80;
    	DisplayData[4] = smgduan[temp % 100 / 10];
    	DisplayData[5] = smgduan[temp % 10];
    }
    
    最后编写数码管的显示函数。
    void DigDisplay()
    {
    	u8 i;
    	for(i=0;i<6;i++)
    	{
    		switch(i)	 //位选,选择点亮的数码管,
    		{
    			case(0):
    				LSA=0;LSB=0;LSC=0; break;//显示第0位
    			case(1):
    				LSA=1;LSB=0;LSC=0; break;//显示第1位
    			case(2):
    				LSA=0;LSB=1;LSC=0; break;//显示第2位
    			case(3):
    				LSA=1;LSB=1;LSC=0; break;//显示第3位
    			case(4):
    				LSA=0;LSB=0;LSC=1; break;//显示第4位
    			case(5):
    				LSA=1;LSB=0;LSC=1; break;//显示第5位	
    		}
    		P0=DisplayData[5-i];//发送数据
    		delay(40); //间隔一段时间扫描	
    		P0=0xff;//消影
    	}		
    }
    

    完成了上面的相关函数之后只需要在主函数中调用他们即可。

    void main()
    {	
    	datapros(Ds18b20ReadTemp());
    	DigDisplay();
    }
    
    

    效果图如下:
    在这里插入图片描述在这里插入图片描述

    展开全文
  • 基于51单片机时钟+温度,1602液晶屏显示,欢迎大家下载,本人亲测
  • 51单片机驱动LCD12864显示温度 时钟 DS1302 DS18B20 矩阵键盘
  • 本程序是通过51单片机汇编语言编写DS18b20、DS1302、红外遥控、LCD1602等驱动程序,实现用1602液晶屏显示时间、日期、室内温度。并通过红外遥控器按键实现时间的修改、闹钟的设置,到达设定闹钟时间时,控制蜂鸣器响...
  • 基于51单片机的电子温度计系统的设计与实现

    千次阅读 多人点赞 2018-10-24 09:01:55
    设计一个基于51单片机的电子温度计系统,其采用STC12C5A60S2芯片作为控制中心,DS18B20温度传感器为测温元件,LCD为显示器件。硬件设计部分包括温度传感电路设计、温度控制电路设计及显示电路设计;软件设计部分包括...

    设计一个基于51单片机的电子温度计系统,其采用STC12C5A60S2芯片作为控制中心,DS18B20温度传感器为测温元件,LCD为显示器件。硬件设计部分包括温度传感电路设计、温度控制电路设计及显示电路设计;软件设计部分包括主程序设计、读温度子程序设计、温度转换命令子程序和计算温度子程序设计。根据设计方案,设计出来的温度计能实现温度采集和显示功能,能测量0 ~100℃之间的温度,测量精度为0.5℃。能根据需要任意设定上下限,使用方便,操作简单,具有高精度、高准确率、体积小和功耗低等优点。

    ds18b20temp.h

    #ifndef __DS18B20_TEMP_H_
    #define __DS18B20_TEMP_H_
    
    #include<reg52.h>
    //---重定义关键词---//
    #ifndef uchar
    #define uchar unsigned char
    #endif
    
    #ifndef uint 
    #define uint unsigned int
    #endif
    
    //--定义使用的IO口--//
    sbit DSPORT=P3^7;
    
    //--声明全局函数--//
    void Delay1ms(uint );
    uchar Ds18b20Init();
    void Ds18b20WriteByte(uchar com);
    uchar Ds18b20ReadByte();
    void  Ds18b20ChangTemp();
    void  Ds18b20ReadTempCom();
    int Ds18b20ReadTemp();
    
    #endif
    

    lcd1602.h

    #ifndef __LCD1602_H_
    #define __LCD1602_H_
    /**********************************
    当使用的是4位数据传输的时候定义,
    使用8位取消这个定义
    **********************************/
    //#define LCD1602_4PINS
    
    /**********************************
    包含头文件
    **********************************/
    #include<reg52.h>
    
    //---重定义关键词---//
    #ifndef uchar
    #define uchar unsigned char
    #endif
    
    #ifndef uint 
    #define uint unsigned int
    #endif
    
    /**********************************
    PIN口定义
    **********************************/
    #define LCD1602_DATAPINS P0
    sbit LCD1602_E=P2^7;
    sbit LCD1602_RW=P2^5;
    sbit LCD1602_RS=P2^6;
    
    /**********************************
    函数声明
    **********************************/
    /*在51单片机12MHZ时钟下的延时函数*/
    void Lcd1602_Delay1ms(uint c);   //误差 0us
    /*LCD1602写入8位命令子函数*/
    void LcdWriteCom(uchar com);
    /*LCD1602写入8位数据子函数*/	
    void LcdWriteData(uchar dat)	;
    /*LCD1602初始化子程序*/		
    void LcdInit();						  
    
    #endif
    

    ds18b20temp.c

    #include"ds18b20temp.h"
    /*******************************************************************************
    * 函 数 名         : Delay1ms
    * 函数功能		   : 延时函数
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    
    void Delay1ms(uint y)
    {
    	uint x;
    	for( ; y>0; y--)
    	{
    		for(x=110; x>0; x--);
    	}
    }
    /*******************************************************************************
    * 函 数 名         : Ds18b20Init
    * 函数功能		   : 初始化
    * 输    入         : 无
    * 输    出         : 初始化成功返回1,失败返回0
    *******************************************************************************/
    
    uchar Ds18b20Init()
    {
    	uchar i;
    	DSPORT = 0;			 //将总线拉低480us~960us
    	i = 70;	
    	while(i--);//延时642us
    	DSPORT = 1;			//然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
    	i = 0;
    	while(DSPORT)	//等待DS18B20拉低总线
    	{
    		Delay1ms(1);
    		i++;
    		if(i>5)//等待>5MS
    		{
    			return 0;//初始化失败
    		}
    	
    	}
    	
    	return 1;//初始化成功
    }
    
    /*******************************************************************************
    * 函 数 名         : Ds18b20WriteByte
    * 函数功能		   : 向18B20写入一个字节
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    
    void Ds18b20WriteByte(uchar dat)
    {
    	uint i, j;
    
    	for(j=0; j<8; j++)
    	{
    		DSPORT = 0;	     	  //每写入一位数据之前先把总线拉低1us
    		i++;
    		DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始
    		i=6;
    		while(i--); //延时68us,持续时间最少60us
    		DSPORT = 1;	//然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
    		dat >>= 1;
    	}
    }
    /*******************************************************************************
    * 函 数 名         : Ds18b20ReadByte
    * 函数功能		   : 读取一个字节
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    
    
    uchar Ds18b20ReadByte()
    {
    	uchar byte, bi;
    	uint i, j;	
    	for(j=8; j>0; j--)
    	{
    		DSPORT = 0;//先将总线拉低1us
    		i++;
    		DSPORT = 1;//然后释放总线
    		i++;
    		i++;//延时6us等待数据稳定
    		bi = DSPORT;	 //读取数据,从最低位开始读取
    		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
    		byte = (byte >> 1) | (bi << 7);						  
    		i = 4;		//读取完之后等待48us再接着读取下一个数
    		while(i--);
    	}				
    	return byte;
    }
    /*******************************************************************************
    * 函 数 名         : Ds18b20ChangTemp
    * 函数功能		   : 让18b20开始转换温度
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    
    void  Ds18b20ChangTemp()
    {
    	Ds18b20Init();
    	Delay1ms(1);
    	Ds18b20WriteByte(0xcc);		//跳过ROM操作命令		 
    	Ds18b20WriteByte(0x44);	    //温度转换命令
    	//Delay1ms(100);	//等待转换成功,而如果你是一直刷着的话,就不用这个延时了
       
    }
    /*******************************************************************************
    * 函 数 名         : Ds18b20ReadTempCom
    * 函数功能		   : 发送读取温度命令
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    
    void  Ds18b20ReadTempCom()
    {	
    
    	Ds18b20Init();
    	Delay1ms(1);
    	Ds18b20WriteByte(0xcc);	 //跳过ROM操作命令
    	Ds18b20WriteByte(0xbe);	 //发送读取温度命令
    }
    /*******************************************************************************
    * 函 数 名         : Ds18b20ReadTemp
    * 函数功能		   : 读取温度
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    
    int Ds18b20ReadTemp()
    {
    	int temp = 0;
    	uchar tmh, tml;
    	Ds18b20ChangTemp();			 	// 先写入转换命令
    	Ds18b20ReadTempCom();			// 然后等待转换完后发送读取温度命令
    	tml = Ds18b20ReadByte();		// 读取温度值共16位,先读低字节
    	tmh = Ds18b20ReadByte();		// 再读高字节
    	temp = tmh;
    	temp <<= 8;
    	temp |= tml;
    	return temp;
    }
    
    
    

    lcd1602.h

    #include "lcd1602.h"
    
    /*******************************************************************************
    * 函 数 名         : Lcd1602_Delay1ms
    * 函数功能		   : 延时函数,延时1ms
    * 输    入         : c
    * 输    出         : 无
    * 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
    *******************************************************************************/
    
    void Lcd1602_Delay1ms(uint c)   //误差 0us
    {
        uchar a,b;
    	for (; c>0; c--)
    	{
    		 for (b=199;b>0;b--)
    		 {
    		  	for(a=1;a>0;a--);
    		 }      
    	}
        	
    }
    
    /*******************************************************************************
    * 函 数 名         : LcdWriteCom
    * 函数功能		   : 向LCD写入一个字节的命令
    * 输    入         : com
    * 输    出         : 无
    *******************************************************************************/
    #ifndef 	LCD1602_4PINS	  //当没有定义这个LCD1602_4PINS时
    void LcdWriteCom(uchar com)	  //写入命令
    {
    	LCD1602_E = 0;     		  // 使能
    	LCD1602_RS = 0;	          // 选择发送命令
    	LCD1602_RW = 0;	          // 选择写入
    	
    	LCD1602_DATAPINS = com;   //放入命令
    	Lcd1602_Delay1ms(1);	  //等待数据稳定
    
    	LCD1602_E = 1;	          //写入时序
    	Lcd1602_Delay1ms(5);	  //保持时间
    	LCD1602_E = 0;
    }
    #else 
    void LcdWriteCom(uchar com)	  //写入命令
    {
    	LCD1602_E = 0;	 //使能清零
    	LCD1602_RS = 0;	 //选择写入命令
    	LCD1602_RW = 0;	 //选择写入
    
    	LCD1602_DATAPINS = com;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;	 //写入时序
    	Lcd1602_Delay1ms(5);
    	LCD1602_E = 0;
    
    	LCD1602_DATAPINS = com << 4; //发送低四位
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;	 //写入时序
    	Lcd1602_Delay1ms(5);
    	LCD1602_E = 0;
    }
    #endif
    /*******************************************************************************
    * 函 数 名         : LcdWriteData
    * 函数功能		   : 向LCD写入一个字节的数据
    * 输    入         : dat
    * 输    出         : 无
    *******************************************************************************/		   
    #ifndef 	LCD1602_4PINS		   
    void LcdWriteData(uchar dat)			//写入数据
    {
    	LCD1602_E = 0;			// 使能清零
    	LCD1602_RS = 1;			// 选择输入数据
    	LCD1602_RW = 0;			// 选择写入
    
    	LCD1602_DATAPINS = dat; // 写入数据
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;   		// 写入时序
    	Lcd1602_Delay1ms(5);  	// 保持时间
    	LCD1602_E = 0;
    }
    #else
    void LcdWriteData(uchar dat)//写入数据
    {
    	LCD1602_E = 0;	  //使能清零
    	LCD1602_RS = 1;	  //选择写入数据
    	LCD1602_RW = 0;	  //选择写入
    
    	LCD1602_DATAPINS = dat;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;	  //写入时序
    	Lcd1602_Delay1ms(5);
    	LCD1602_E = 0;
    
    	LCD1602_DATAPINS = dat << 4; //写入低四位
    	Lcd1602_Delay1ms(1);
    
    	LCD1602_E = 1;	  //写入时序
    	Lcd1602_Delay1ms(5);
    	LCD1602_E = 0;
    }
    #endif
    /*******************************************************************************
    * 函 数 名       : LcdInit()
    * 函数功能		 : 初始化LCD屏
    * 输    入       : 无
    * 输    出       : 无
    *******************************************************************************/		   
    #ifndef		LCD1602_4PINS
    void LcdInit()						  //LCD初始化子程序
    {
     	LcdWriteCom(0x38);  //开显示,且显示两行
    	LcdWriteCom(0x0c);  //开显示不显示光标
    	LcdWriteCom(0x06);  //写一个指针加1
    	LcdWriteCom(0x01);  //清屏
    	LcdWriteCom(0x80);  //设置数据指针起点
    }
    #else
    void LcdInit()			 // LCD初始化子程序
    {
    	LcdWriteCom(0x32);	 // 将8位总线转为4位总线
    	LcdWriteCom(0x28);	 // 在四位线下的初始化
    	LcdWriteCom(0x0c);   // 开显示不显示光标
    	LcdWriteCom(0x06);   // 写一个指针加1
    	LcdWriteCom(0x01);   // 清屏
    	LcdWriteCom(0x80);   // 设置数据指针起点
    }
    #endif
    

     

    main.c

    #include "reg52.h"			 	// 此文件中定义了单片机的一些特殊功能寄存器
    #include "ds18b20temp.h"	
    #include "lcd1602.h"
    
    sbit BEEP= P1^7;
    
    typedef unsigned int u16;	  	// 对数据类型进行声明定义
    typedef unsigned char u8;
    //=============================================函数前向申明
    void SysInit(void);					// 系统初始化
    void Do(void);						// 系统执行
    void DoShow(void);	  				// 温度数据显示
    void DoSetting(void);				// 用户阈值设定
    void SaveSetting(void);				// 保存用户设设置
    int  KeyScan(void);					// 按键扫描
    void KeyListen(void);				// 按键监听
    void datapros(int temp); 			// 数据处理
    void DisInterface(uchar *disp); 	// 显示界面
    void DisTempData(void);				// 显示温度数据
    void DisTempThresholdData(void);	// 显示阈值数据
    void CursorPositionToChange(void);	// 在指定位置修改数据
    void Alarm(void);					// 温度超阈值警报
    
    //=============================================数据定义
    u8 DispInterface1[]="Temperature Is: ";		 // 显示温度检测界面
    u8 DispInterface2[]=" <--Setting-->  ";	 	 // 显示温度阀值设置界面 1
    
    
    u8 DispTempData[8]={0,0,0,'.',0,0,' ','C'};	 		// 显示温度值
    u8 DispUpData[7]={'U',':','5','0','.','0','0'};		// 显示温度上限值
    u8 DispDwData[7]={'D',':','2','0','.','0','0'};		// 显示温度下限值
    	 
    int TempData,TempDataUP=5000,TempDataDW=2000;		// 用于存储温度数据,温度上限,温度下限
    u8 	DoWhat= 0;										// 事件执行标记 :0为 温度数据显示,1 为温度阈值设置
    int veluTemp= 0;									// 用于存储数值增量
    u8 	isChange=0;
    u8  CursorPosition=0;								// 标识光标位置,共有八个位置
    
    //char num= 0;
    
    
    /*******************************************************************************
    * 函 数 名       : main
    * 函数功能		 : 主函数
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void main()
    {
    	SysInit();		// 系统初始化
    	Do(); 			// 显示界面			
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /*******************************************************************************
    * 函 数 名       : SysInit
    * 函数功能		 : 系统初始化
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void SysInit(void)
    {
    	LcdInit();
    	Ds18b20Init();
    	Ds18b20ReadTemp(); 		// 刷新,舍去无效数据
    	Ds18b20ReadTemp();
    	Ds18b20ReadTemp();
    }
    
    
    /*******************************************************************************
    * 函 数 名         : datapros()
    * 函数功能		   : 温度读取处理转换函数
    * 输    入         : temp
    * 输    出         : 无
    *******************************************************************************/
    void datapros(int temp) 	 
    {
       	float tp;  
    
    	if(temp< 0)						//	当温度值为负数
      	{
    		DispTempData[0] = '-'; 	 	//  负温度
    		//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
    		temp=temp-1;
    		temp=~temp;
    		tp=temp;
    		temp=tp*0.0625*100+0.5;	
    		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    		//算加上0.5,还是在小数点后面。
     
      	}
     	else
      	{			
    		DispTempData[0] = '+'; 	 		//  正温度
    		tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
    		//如果温度是正的那么,那么正数的原码就是补码它本身
    		temp=tp*0.0625*100+0.5;	
    		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    		//算加上0.5,还是在小数点后面。
    	}
    	TempData= temp % 10000;
    	//Disp[20] = (temp / 10000) + '0';
    	DispTempData[1] = (temp % 10000 / 1000) + '0';
    	DispTempData[2] = (temp % 1000 / 100) + '0';
    	DispTempData[4] = (temp % 100 / 10) + '0';
    	DispTempData[5] = (temp % 10) + '0';
    }
    
    /*******************************************************************************
    * 函 数 名       : DisInterface
    * 函数功能		 : 显示界面
    * 输    入       : uchar *disp
    * 输    出    	 : 无
    *******************************************************************************/
    void DisInterface(uchar *disp)
    {
    	u8 i;
    
    	LcdWriteCom(0x80);   			 	 // 设置数据指针起点	
    	for(i=0;i<16;i++)
    		LcdWriteData(disp[i]);			 // LCD12864显示数据
    }
    /*******************************************************************************
    * 函 数 名       : DisTempData
    * 函数功能		 : 显示温度数据
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void DisTempData(void)
    {
    	LcdWriteCom(0xc4);
    	LcdWriteData(DispTempData[0]);			 // LCD12864显示数据
    	LcdWriteData(DispTempData[1]);			 // LCD12864显示数据
    	LcdWriteData(DispTempData[2]);			 // LCD12864显示数据
    	LcdWriteData(DispTempData[3]);			 // LCD12864显示数据
    	
    	LcdWriteCom(0xc8);
    	LcdWriteData(DispTempData[4]);			 // LCD12864显示数据
    	LcdWriteData(DispTempData[5]);			 // LCD12864显示数据
    	LcdWriteData(DispTempData[6]);			 // LCD12864显示数据
    	LcdWriteData(DispTempData[7]);			 // LCD12864显示数据	
    }
    /*******************************************************************************
    * 函 数 名       : DisTempThresholdData
    * 函数功能		 : 显示温度阈值数据
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void DisTempThresholdData(void)
    { 
    	u8 i=0;
    
    	LcdWriteCom(0xc0);
    	for(i=0; i<7;i++)
    	{
    		LcdWriteData(DispUpData[i]);			 // LCD12864显示数据
    	}
    	  		  
    	LcdWriteCom(0xc9);
    	for(i=0; i<7;i++)
    	{
    		LcdWriteData(DispDwData[i]);			 // LCD12864显示数据
    	} 
    	LcdWriteCom(0x83);	
    }
    /*******************************************************************************
    * 函 数 名       : Do
    * 函数功能		 : 事件执行
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void Do(void)
    {
    	while(1)
    	{
    		Alarm();		// 温度超阈值时触发警报	
    		(DoWhat == 0)? DoShow():DoSetting();
    		KeyListen();	// 按键监听
    	}
    	
    }
    /*******************************************************************************
    * 函 数 名       : DoShow
    * 函数功能		 : 执行温度显示
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void DoShow(void)
    {
    	if(isChange != 0)
    	{
    		LcdWriteCom(0x01);   			// 清屏
    		isChange= 0;
    	}
    	
    	DisInterface(DispInterface1); 		// 温度显示界面
    	datapros(Ds18b20ReadTemp());	 	// 获取数据并处理 
    	DisTempData();					 	// 显示温度数据	
    	
    }
    /*******************************************************************************
    * 函 数 名       : DoSetting
    * 函数功能		 : 执行阈值设置
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void DoSetting(void)
    {  
    	if(isChange != 0)
    	{
    		LcdWriteCom(0x01);   			// 清屏
    		isChange= 0;
    	}
    	DisInterface(DispInterface2);  		// 温度设置界面
    	CursorPositionToChange();			// 指定位置显示光标,光标闪动,可以修改数据
    	DisTempThresholdData();				// 显示阈值数据
    }
    /*******************************************************************************
    * 函 数 名       : KeyListen
    * 函数功能		 : 按键监听
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void KeyListen(void)
    {
    	int KeyVelu= KeyScan();
    	if( KeyVelu != -1)			// 有按键按下
    	{
    		switch(KeyVelu)
    		{
    			case 1:					// 按键表示切换功能
    			{
    				DoWhat =  (DoWhat+1)%2;
    				isChange= 1;
    				break; 
    			}	
    			case 2:
    			{						//  +
    				if(DoWhat == 1)
    				{
    					switch(CursorPosition)
    					{
    						case 1:
    						{
    							veluTemp= (veluTemp+1)%10;
    							DispUpData[2]= '0'+veluTemp;		   
    							
    							break;
    						}
    						case 2:
    						{
    							veluTemp= (veluTemp+1)%10;
    							DispUpData[3]= '0'+veluTemp;
    							break;
    						}
    						case 3:
    						{
    							veluTemp= (veluTemp+1)%10;
    							DispUpData[5]= '0'+veluTemp;
    							break;
    						}
    						case 4:
    						{
    							veluTemp= (veluTemp+1)%10;
    							DispUpData[6]= '0'+veluTemp;
    							break;
    						}
    						case 5:
    						{
    							veluTemp= (veluTemp+1)%10;
    							DispDwData[2]= '0'+veluTemp;
    							break;
    						}
    						case 6:
    						{
    							veluTemp= (veluTemp+1)%10;
    							DispDwData[3]= '0'+veluTemp;
    							break;
    						}
    						case 7:
    						{
    							veluTemp= (veluTemp+1)%10;
    							DispDwData[5]= '0'+veluTemp;
    							break;
    						}
    						case 8:
    						{
    							veluTemp= (veluTemp+1)%10;
    							DispDwData[6]= '0'+veluTemp;
    							break;
    						}
    						default :
    						{
    							break;
    						}
    					}							
    				}
    				break; 
    			}
    			case 3:
    			{	  					// -
    				if(DoWhat == 1)
    				{
    					switch(CursorPosition)
    					{
    						case 1:
    						{
    							veluTemp--;
    							if(veluTemp < 0)
    								  veluTemp= 9;
    							DispUpData[2]= '0'+veluTemp;		   
    							
    							break;
    						}
    						case 2:
    						{
    							veluTemp--;
    							if(veluTemp < 0)
    								  veluTemp= 9;
    							DispUpData[3]= '0'+veluTemp;
    							break;
    						}
    						case 3:
    						{
    							veluTemp--;
    							if(veluTemp < 0)
    								  veluTemp= 9;
    							DispUpData[5]= '0'+veluTemp;
    							break;
    						}
    						case 4:
    						{
    							veluTemp--;
    							if(veluTemp < 0)
    								  veluTemp= 9;
    							DispUpData[6]= '0'+veluTemp;
    							break;
    						}
    						case 5:
    						{
    							veluTemp--;
    							if(veluTemp < 0)
    								  veluTemp= 9;
    							DispDwData[2]= '0'+veluTemp;
    							break;
    						}
    						case 6:
    						{
    							veluTemp--;
    							if(veluTemp < 0)
    								  veluTemp= 9;
    							DispDwData[3]= '0'+veluTemp;
    							break;
    						}
    						case 7:
    						{
    							veluTemp--;
    							if(veluTemp < 0)
    								  veluTemp= 9;
    							DispDwData[5]= '0'+veluTemp;
    							break;
    						}
    						case 8:
    						{
    							veluTemp--;
    							if(veluTemp < 0)
    								  veluTemp= 9;
    							DispDwData[6]= '0'+veluTemp;
    							break;
    						}
    						default :
    						{
    							break;
    						}
    					}	
    				}
    				break; 
    			}	
    			case 4:
    			{	 					// <---
    				if(DoWhat == 1)
    				{
    					CursorPosition--;
    					if(CursorPosition == 0)	
    						CursorPosition= 8;
    				}
    					
    				break; 
    			}
    			case 5:
    			{			 			// --->
    				if(DoWhat == 1)
    				{
    					CursorPosition++;
    					if(CursorPosition == 9)	
    						CursorPosition= 1;
    				}
    				break; 
    			}	
    			case 6:
    			{	 					// 确认
    				if(DoWhat == 1)
    				{	
    					SaveSetting(); 	// 保存设定的数据
    					DoWhat= 0;		// 事件重回温度显示
    					isChange= 1;
    				}
    				break; 
    			}
    			case 7:
    			{
    				if(DoWhat == 1)
    				{
    				}
    				break; 
    			}	
    			default:
    			{
    				if(DoWhat == 1)
    				{
    				}
    				break; 
    			}
    		}
    	}
    }
    /*******************************************************************************
    * 函 数 名       : KeyScan
    * 函数功能		 : 按键扫描
    * 输    入       : 无
    * 输    出    	 : u8类型的按键编号
    *******************************************************************************/
    int KeyScan(void)
    {	 // 返回1~7 表示K1(P1.0)~K7(P1.7) ,无按键按下时,返回-1
      
    	if((P1 & 0x7f) != 0x7f)	  		// 说明可能有按键按下
    	{
    		Delay1ms(10);				// 延时消抖
    		if((P1 & 0x7f) != 0x7f)	  	// 说明确实有按键按下
    		{
    			switch(P1 & 0x7f)
    			{
    				case 0x7e:	  		// 0111 1110
    					return 1;
    				case 0x7d:			// 0111 1101
    					return 2;	 	
    				case 0x7b:			// 0111 1011
    					return 3;
    				case 0x77: 			// 0111 0111
    					return 4;
    				case 0x6f:			// 0110 1111
    					return 5;
    				case 0x5f:			// 0101 1111
    					return 6;
    				case 0x3f:			// 0011 1111
    					return 7;
    				default:
    					return 0;
    			}	
    		}
    		return -1;
    	}
    	else
    		return -1;
    }
    
    /*******************************************************************************
    * 函 数 名       : CursorPositionToChange
    * 函数功能		 : 在指定位置显示光标并,执行数据修改
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void CursorPositionToChange(void)
    {
    	switch(CursorPosition)
    	{
    		case 1:
    		{
    			LcdWriteCom(0xc2);
    			LcdWriteData(' ');			 // LCD12864显示数据
    			Delay1ms(30);				 // 延时消抖
    			break;
    		}
    		case 2:
    		{
    			LcdWriteCom(0xc3);
    			LcdWriteData(' ');			 // LCD12864显示数据
    			Delay1ms(30);				 // 延时消抖
    			break;
    		}
    		case 3:
    		{
    			LcdWriteCom(0xc5);
    			LcdWriteData(' ');			 // LCD12864显示数据
    			Delay1ms(30);				 // 延时消抖
    			break;
    		}
    		case 4:
    		{
    			LcdWriteCom(0xc6);
    			LcdWriteData(' ');			 // LCD12864显示数据
    			Delay1ms(30);				 // 延时消抖
    			break;
    		}
    		case 5:
    		{
    			LcdWriteCom(0xcb);
    			LcdWriteData(' ');			 // LCD12864显示数据
    			Delay1ms(30);				 // 延时消抖
    			break;
    		}
    		case 6:
    		{
    			LcdWriteCom(0xcc);
    			LcdWriteData(' ');			 // LCD12864显示数据
    			Delay1ms(30);				 // 延时消抖
    			break;
    		}
    		case 7:
    		{
    			LcdWriteCom(0xce);
    			LcdWriteData(' ');			 // LCD12864显示数据
    			Delay1ms(30);				 // 延时消抖
    			break;
    		}
    		case 8:
    		{
    			LcdWriteCom(0xcf);
    			LcdWriteData(' ');			 // LCD12864显示数据
    			Delay1ms(30);				 // 延时消抖
    			break;
    		}
    		default :
    		{
    			break;
    		}
    	}
    	
    }
    
    /*******************************************************************************
    * 函 数 名       : SaveSetting
    * 函数功能		 : 保存用户设置
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void SaveSetting(void)
    {
    	TempDataUP=  (DispUpData[2]-'0')*1000+ (DispUpData[3]-'0')*100+	(DispUpData[5]-'0')*10+ (DispUpData[6]-'0');
    	TempDataDW=  (DispDwData[2]-'0')*1000+ (DispDwData[3]-'0')*100+	(DispDwData[5]-'0')*10+ (DispDwData[6]-'0');	
    }
    /*******************************************************************************
    * 函 数 名       : Alarm
    * 函数功能		 : 温度超阈值警报
    * 输    入       : 无
    * 输    出    	 : 无
    *******************************************************************************/
    void Alarm(void)
    {
    	if((TempData < TempDataDW) || (TempData > TempDataUP))
    	{
    		BEEP= 1;
    			Delay1ms(60);
    		BEEP= 0;
    			Delay1ms(30);				
    	}		
    }
    
    
    
    

     

    展开全文
  • 1602具有8根数据线和三根控制线(E使能线 R/W读写线 RS表示数据还是指令) 一般是先写地址再写数据即可
  • 51单片机控制的数字温度计 PROTEUS 和51单片机教程

    千次阅读 热门讨论 2020-02-15 15:48:05
    51单片机控制的数字温度计 总览部分 MCU部分 显示部分 开仿真以后实时显示温度 因为这个程序比较简单,我就直接上代码了,有不明白的请看我以前的文章,谢谢哦! 参考代码如下: #include “reg51.h” char disp...
  • 基于STC89S52单片机温度控制系统,可以通过按键设置最大最小温度值,DS18B20温度传感器采集回来温度通过1602液晶显示显示。内含电路图和程序源码
  • 基于51单片机及DS18B20温度传感器数码管显示程序

    万次阅读 多人点赞 2017-12-27 11:23:57
    //温度采集 sbit latch1=P2^2;//段锁存 sbit latch2=P2^3;//位锁存 unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示段码0~9 unsigned cha
  • 51单片机使用LCD1602显示DS18B20温度传感器温度

    千次阅读 多人点赞 2020-05-07 11:29:31
      使用LCD1602显示DS18B20温度传感器温度。关于DS18B20和LCD的原理,我就不再叙述了,大家自行查找,网上可以找到好多。   使用Proteus仿真。(需要仿真和Keil工程文件的可以留言,看到回复) 需要的元件:   ...
  • 51单片机+oled+ds18b20检测并显示温度~
  • 51单片机DS18B20温度读取

    千次阅读 2019-08-07 15:22:18
    本文是武汉市海联天下物联网有限公司技术团队内部学习笔记,将详细讲解DS18B20温度显示以及51单片机如何利用单总线与DS18B20通信,DS18B20重要时序掌握。——技术部 张傲 现象描述 使用DS18B20测量温度,并在数码管...
  • 实测好用。 047 DS18B20 温度读取 LCD1602 显示 51单片机 仿真 proteus
  • #基于单片机铂热电阻的温度控制系统,采用热敏PT100传感器,使用pid算法,可以对目标温度进行设置, 按键控制加减目标温度设置,放大电路,基于单片机铂热电阻的温度控制系统.精度0.1.实际温度和设定 温度比较,...
  • 温度测量系统以AT89C51单片机为核心控制器,配合DS18B20数字温度传感器、LCD1602、蜂鸣器、LED灯进行温度的测量、显示和预警。本系统可通过按键设置温度上限值,单片机将检测到的温度信号与输入温度的上限值进行...
  • 欢迎点击「算法与编程之美」↑关注我们!本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。51单片机开发板,功能模块独立性高,能够实现各种各样的功...
  • 51单片机+oled+ds18b20检测并显示温度~
1 2 3 4 5 ... 20
收藏数 3,102
精华内容 1,240
关键字:

单片机显示时间跟温度