51单片机智能温控器C语言源程序

发布者:星光曲折最新更新时间:2017-09-02 来源: elecfans关键字:51单片机  智能温控器  C语言 手机看文章 扫描二维码
随时随地手机看文章

这是一款51单片机智能温控器C语言源程序,程序功能:速成有时钟显示,使用DS18B20进行温度检测,控制温度可通过按键进行设置,输出通过继电器械驱动加热器进行加热。是一款功能较为完善的温度控制板,适合单片机爱好者进行温度控制的电子制作实作项目。电路简单,容易制作,调试容易。

51单片机智能温控器C语言源程序

#include 'reg51.h'

#include 'intrins.h'

#include  'absacc.h'

#define uchar unsigned char

#define uint   unsigned int

#define BUSY  0x80                               //lcd忙检测标志

#define DATAPORT P0                              //定义P0口为LCD通讯端口

#define PLAYE_ADDR XBYTE[0XBFFF]                 //语音报警地址

sbit RED_ALARM=P1^0;                                                    //红色指示灯

sbit WRITE_ALARM=P1^1;                                          //白色指示灯

sbit GREEN_ALARM=P1^2;                                          //绿色指示灯

sbit P1_4=P1^4;                                                    //时钟调整

sbit P1_5=P1^5;                                                 //时钟加

sbit P1_6=P1^6;                                                 //时钟减

sbit DQ = P1^7;                                                 //定义ds18b20通信端口 

sbit LCM_RS=P2^0;                                                                //数据/命令端

sbit LCM_RW=P2^1;                                                                //读/写选择端

sbit LCM_EN=P2^2;                                               //LCD使能信号

sbit ad_busy=P3^2;                                              //adc中断方式接口

sbit RECLED_EOC=P3^5;                                           //ISD1420放音结束查询标志

sbit OUT=P3^7;

uchar ad_data;                                                  //ad采样值存储                                                

uchar seconde=0;                                                //定义并初始化时钟变量

uchar minite=0;

uchar hour=12;

uchar mstcnt=0;

uchar temp1,temp2,temp;                                     //温度显示变量

uchar t,set;

uchar T;

bit ON_OFF;

bit outflag;

uchar code str0[]={"---  :  :  ---OF"};

uchar code str1[]={"SET:  C SA:  . C"};

void delay_LCM(uint);                                                                                                     //LCD延时子程序

void initLCM( void);                                                                                                       //LCD初始化子程序

void lcd_wait(void);                                                                                                      //LCD检测忙子程序

void WriteCommandLCM(uchar WCLCM,uchar BusyC);                              //写指令到ICM子函数

void WriteDataLCM(uchar WDLCM);                                             //写数据到LCM子函数

void DisplayOneChar(uchar X,uchar Y,uchar DData);                           //显示指定坐标的一个字符子函数

void DisplayListChar(uchar X,uchar Y,uchar code *DData);                    //显示指定坐标的一串字符子函数

void init_timer0(void);                                                                                               //定时器初始化

void displayfun1(void);

void displayfun2(void);

void displayfun3(void);

void displayfun4(void);

void keyscan(void );                                                                                            //键盘扫描子程序

void set_adj(void);

void inc_key(void);

void dec_key(void);

void delay_18B20(unsigned int i);

void Init_DS18B20(void) ;

uchar ReadOneChar(void);

void WriteOneChar(unsigned char dat);

void ReadTemperature(void);

void ad0809(void);

void playalarm(void); 

void delay_LCM(uint k)

{

    uint i,j;

    for(i=0;i

    {

        for(j=0;j<60;j++)

                {;}

    }

}   

void WriteCommandLCM(uchar WCLCM,uchar BusyC)

{

    if(BusyC)lcd_wait();

        DATAPORT=WCLCM;

    LCM_RS=0;                   // 选中指令寄存器

    LCM_RW=0;                       // 写模式        

    LCM_EN=1;    

        _nop_();   

        _nop_();

        _nop_(); 

    LCM_EN=0;  

}

void WriteDataLCM(uchar WDLCM)

    lcd_wait( );            //检测忙信号    

        DATAPORT=WDLCM;

    LCM_RS=1;               // 选中数据寄存器

    LCM_RW=0;                   // 写模式

    LCM_EN=1;

    _nop_();

        _nop_();

        _nop_();

    LCM_EN=0;

}

void lcd_wait(void)

{

    DATAPORT=0xff;             

        LCM_EN=1;

    LCM_RS=0;                           

    LCM_RW=1;                           

    _nop_();

    while(DATAPORT&BUSY)

        {  LCM_EN=0;

           _nop_();

           _nop_();

           LCM_EN=1;

           _nop_();

           _nop_();

           }

           LCM_EN=0;

        

}

void initLCM( )

{   

        DATAPORT=0;        

        delay_LCM(15);

        WriteCommandLCM(0x38,0);    //三次显示模式设置,不检测忙信号

    delay_LCM(5); 

    WriteCommandLCM(0x38,0);

    delay_LCM(5); 

    WriteCommandLCM(0x38,0);

    delay_LCM(5); 

    WriteCommandLCM(0x38,1);    //8bit数据传送,2行显示,5*7字型,检测忙信号

    WriteCommandLCM(0x08,1);    //关闭显示,检测忙信号

    WriteCommandLCM(0x01,1);    //清屏,检测忙信号

    WriteCommandLCM(0x06,1);    //显示光标右移设置,检测忙信号

    WriteCommandLCM(0x0c,1);    //显示屏打开,光标不显示,不闪烁,检测忙信号

}

void DisplayOneChar(uchar X,uchar Y,uchar DData)

{

    Y&=1;

    X&=15;

    if(Y)X|=0x40;               //若y为1(显示第二行),地址码+0X40

    X|=0x80;                    //指令码为地址码+0X80

    WriteCommandLCM(X,0);

    WriteDataLCM(DData);

}

void DisplayListChar(uchar X,uchar Y,uchar code *DData)

{

    uchar ListLength=0;

    Y&=0x01;

    X&=0x0f;

    while(X<16)

    {

        DisplayOneChar(X,Y,DData[ListLength]);

        ListLength++;

        X++;

    }

}

 

void delay_18B20(unsigned int i)

{

        while(i--);

}

void Init_DS18B20(void) 

{

         unsigned char x=0;

         DQ = 1;          //DQ复位

         delay_18B20(8);  //稍做延时

         DQ = 0;          //单片机将DQ拉低

         delay_18B20(80); //精确延时 大于 480us

         DQ = 1;          //拉高总线

         delay_18B20(14);

         x=DQ;            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败

         delay_18B20(20);

}

 

unsigned char ReadOneChar(void)

{

        uchar i=0;

        uchar dat = 0;

        for (i=8;i>0;i--)

         {

                  DQ = 0; // 给脉冲信号

                  dat>>=1;

                  DQ = 1; // 给脉冲信号

                  if(DQ)

                  dat|=0x80;

                  delay_18B20(4);

         }

        return(dat);

}

 

void WriteOneChar(uchar dat)

{

        unsigned char i=0;

        for (i=8; i>0; i--)

        {

                  DQ = 0;

                DQ = dat&0x01;

            delay_18B20(5);

                DQ = 1;

            dat>>=1;

}

}

void ReadTemperature(void)

{

        unsigned char a=0;

        unsigned char b=0;

        unsigned char t=0;

        Init_DS18B20();

        WriteOneChar(0xCC);            // 跳过读序号列号的操作

        WriteOneChar(0x44);         // 启动温度转换

        delay_18B20(100);       // this message is wery important

        Init_DS18B20();

        WriteOneChar(0xCC);         //跳过读序号列号的操作

        WriteOneChar(0xBE);         //读取温度寄存器等(共可读9个寄存器) 前两个就是温度

        delay_18B20(100);

        a=ReadOneChar();            //读取温度值低位

        b=ReadOneChar();                   //读取温度值高位

        temp1=b<<4;

        temp1+=(a&0xf0)>>4;

        temp2=a&0x0f;

    temp=((b*256+a)>>4);    //当前采集温度值除16得实际温度值

}

void displayfun1(void)

{        

        WriteCommandLCM(0x0c,1);                                            //显示屏打开,光标不显示,不闪烁,检测忙信号        

        DisplayListChar(0,0,str0);        

        DisplayListChar(0,1,str1);        

                                                                                                      

        DisplayOneChar(3,0,hour/10+0x30);                    //液晶上显示小时

        DisplayOneChar(4,0,hour+0x30);

        DisplayOneChar(6,0,minite/10+0x30);                        //液晶上显示分

        DisplayOneChar(7,0,minite+0x30);

        

        DisplayOneChar(9,0,seconde/10+0x30);            //液晶上显示秒

        DisplayOneChar(10,0,seconde+0x30);

        DisplayOneChar(4,1,T/10+0x30);                            //液晶上显示设定的温度

        DisplayOneChar(5,1,T+0x30);

           DisplayOneChar(11,1,temp1/10+0x30);         //液晶上显示测得的温度  

        DisplayOneChar(12,1,temp1+0x30);

        DisplayOneChar(14,1,temp2/10+0x30);

        if(ON_OFF==0)                                                      //若温控标志为0

        {

                DisplayOneChar(14,0,0x4f);                           // 液晶上显示不控温的标志

                DisplayOneChar(15,0,0x46);

        }

        else

        {

                DisplayOneChar(14,0,0x4f);                           // 液晶上显示控温的标志

                DisplayOneChar(15,0,0x4e);

                if(outflag==1)

                    DisplayOneChar(0,0,0x7c);                           

            else

                        DisplayOneChar(0,0,0xef);

        }

        

}

void displayfun2(void)

{

        WriteCommandLCM(0x0c,1);                     //显示屏打开,光标不显示,不闪烁,检测忙信号        

        DisplayListChar(0,0,str0);        

        DisplayListChar(0,1,str1);        

                

        DisplayOneChar(6,0,minite/10+0x30);

        DisplayOneChar(7,0,minite+0x30);

        

        DisplayOneChar(9,0,seconde/10+0x30);

        DisplayOneChar(10,0,seconde+0x30);

        DisplayOneChar(4,1,T/10+0x30);                           

        DisplayOneChar(5,1,T+0x30);

           DisplayOneChar(11,1,temp1/10+0x30);         

        DisplayOneChar(12,1,temp1+0x30);

        DisplayOneChar(14,1,temp2/10+0x30);

           WriteCommandLCM(0x0f,1);                                            //显示屏打开,光标显示,闪烁,检测忙信号        

    DisplayOneChar(3,0,hour/10+0x30);

        DisplayOneChar(4,0,hour+0x30);

}

void displayfun3(void)

{

        WriteCommandLCM(0x0c,1);                                    //显示屏打开,光标不显示,不闪烁,检测忙信号       

        DisplayListChar(0,0,str0);        

        DisplayListChar(0,1,str1);        

        

        DisplayOneChar(3,0,hour/10+0x30);

        DisplayOneChar(4,0,hour+0x30); 

        DisplayOneChar(9,0,seconde/10+0x30);

        DisplayOneChar(10,0,seconde+0x30);

        DisplayOneChar(4,1,T/10+0x30);                           

        DisplayOneChar(5,1,T+0x30);

           DisplayOneChar(11,1,temp1/10+0x30);         

        DisplayOneChar(12,1,temp1+0x30);

        DisplayOneChar(14,1,temp2/10+0x30);

   

        WriteCommandLCM(0x0f,1);                                            //显示屏打开,光标显示,闪烁,检测忙信号

        DisplayOneChar(6,0,minite/10+0x30);

        DisplayOneChar(7,0,minite+0x30);

}

void displayfun4(void)

{

        WriteCommandLCM(0x0c,1);                                    //显示屏打开,光标不显示,不闪烁,检测忙信号       

        DisplayListChar(0,0,str0);        

        DisplayListChar(0,1,str1);        

        

        DisplayOneChar(3,0,hour/10+0x30);

        DisplayOneChar(4,0,hour+0x30); 

        DisplayOneChar(6,0,minite/10+0x30);

        DisplayOneChar(7,0,minite+0x30);

        DisplayOneChar(9,0,seconde/10+0x30);

        DisplayOneChar(10,0,seconde+0x30);

        

           DisplayOneChar(11,1,temp1/10+0x30);         

        DisplayOneChar(12,1,temp1+0x30);

        DisplayOneChar(14,1,temp2/10+0x30);

   

        WriteCommandLCM(0x0f,1);                                            //显示屏打开,光标显示,闪烁,检测忙信号

        DisplayOneChar(4,1,T/10+0x30);                           

        DisplayOneChar(5,1,T+0x30);

}

void keyscan(void)

{

        uchar xx;                                           //局部变量

        P1=0xff;

        if(P1!=0xff)

          {

            delay_LCM(30);

                if(P1!=0xff)

                  {        

                        xx=P1;

                        switch(xx)                                                       // 根据按键状态,调用不同的子函数

                        {

                                case 0xfe:set_adj();       break;               

                                case 0xfd:inc_key();       break;               

                                case 0xfb:dec_key();       break;               

                                case 0xf7:ON_OFF=!ON_OFF;  break;

                                default:break;

                        }

                  }

                

          }

  

}

void set_adj(void)

{

        delay_LCM(100);

        set++;

    if(set>=4)set=0;

                

}

void inc_key(void)

{

        delay_LCM(100);

                

        switch(set)

        {

                case 0:if(P2==0xf7)ON_OFF=!ON_OFF;       break;

                case 1:hour++;   if(hour>=23)hour=23;    break;

                case 2:minite++; if(minite>=59)minite=59;break;

                case 3:T++;if(T>=99)T=99;                                 break; 

                default:break;

        }

                

}

void dec_key(void)

{

        delay_LCM(100);

        

        switch(set)

        {

                   case 0:if(P2==0xf7)ON_OFF=!ON_OFF;    break;

                case 1:hour--;  if(hour<=0)hour=0;    break;

                case 2:minite--;if(minite<=0)minite=0;break;

                case 3:T--;if(T<=1)T=1;                                  break; 

                default:break;

        }

                

}

void init_timer0(void)

{

         TMOD=0x01;                                  //time0为定时器,方式1

     TH0=0x3c;                                   //预置计数初值

     TL0=0xb0;

     EA=1;                                                                   

     ET0=1;                                                                                                  

     TR0=1;                          

}

void timer0(void) interrupt 1 using 0          //定时器0方式1,50ms中断一次

{

     TH0=0x3c;

     TL0=0xb0;

     mstcnt++;

     if(mstcnt>=20 )  {seconde++; mstcnt=0; }

         if(seconde>=60)  {minite++;  seconde=0;}

         if(minite>=60 )  {hour++;    minite=0; }

         if(hour>=24   )  {hour=0;}

         keyscan( );                               //按键扫描

}

void playalarm(void)                        //语音提示温度上升过快

{

        

    if(temp>25&&temp<30)              

        {   

       delay_LCM(10);

       if(temp>20&&temp<22) 

        {

                        RED_ALARM=0;

                        PLAYE_ADDR=0x11;

                        _nop_();

                         _nop_();

                        PLAYE_ADDR=0x10;

                        while(RECLED_EOC==1);            //等待放音结束

                        RED_ALARM=1;

                }

        }

        

        if(temp>30&&temp<35)                    //语音提示温度上升过慢

        {

                delay_LCM(10);

        if(temp>22&&temp<25)

                {

                        GREEN_ALARM=0;

                        PLAYE_ADDR=0x21;

                         _nop_();

                        _nop_();

                        PLAYE_ADDR=0x20;

                       while(RECLED_EOC==1);

                        GREEN_ALARM=1;

                }

        }

        

        if(temp>35&&temp<40)                   //语音提示恒温控制

        {

                delay_LCM(10);

                if(temp>25&&temp<30) 

                {

                        WRITE_ALARM=0;

                        PLAYE_ADDR=0x31;

                        _nop_();

                        _nop_();

                        PLAYE_ADDR=0x30;

                        while(RECLED_EOC==1);

                        WRITE_ALARM=1;

                }

        }   

}

    

void main(void)

        ad_data=0;                                                                          //采样值存储单元初始化为0

    P1=0xff;                                                                   //初始化p1口,全设为1       

        delay_LCM(500);                                                //延时500ms启动

        initLCM( );                                                               //LCD初始化

        init_timer0( );                                                                   //时钟定时器0初始化        

    Init_DS18B20( ) ;                                                          //DS18B20初始化

        DisplayListChar(0,0,str0);        

        DisplayListChar(0,1,str1);  

                             

    while (1)

    {   

               keyscan();                                            //按键扫描

            ReadTemperature();                                    //温度采集

                playalarm();

        switch(set)                                           //LCD根据工作模式显示

                {

                        case 0:displayfun1();delay_LCM(1000);break;       //正常工作显示

                        case 1:displayfun2();delay_LCM(1000);break;       //调整时显示

                        case 2:displayfun3();delay_LCM(1000);break;       //调整分显示

                        case 3:displayfun4();delay_LCM(1000);break; 

                        default:break;

                }         

                keyscan( );                                              //相当于延时

                if(ON_OFF==1)                                                                          //若温控标志位1, 控制LAMP动作

                {

                        if(temp1>=T+1){outflag=1;OUT=0;}

                        if(temp1

                        { 

                                delay_LCM(1000);

                                if(temp1

                        }

                }

                else{outflag=0;OUT=1;}

    }

        

}


关键字:51单片机  智能温控器  C语言 引用地址:51单片机智能温控器C语言源程序

上一篇:Ds3231+12864液晶显示AT89C51带温度功能的时钟程序
下一篇:DS18B20制作的温度测量模块

推荐阅读最新更新时间:2024-03-16 15:35

51单片机蜂鸣器程序
#include reg52.h typedef unsigned char u8; typedef unsigned int u16; sbit beep=P1^5; void delay(u16 i) { while(i--); } void main() { while(1) { beep=~beep; delay(1000);//控制音调频率 beep=~beep;/控制声音大小 delay(10); } }
[单片机]
基于C语言在8×8点阵实现9到0倒计时牌显示
基于C语言在8×8点阵实现9到0倒计时牌显示。 每个数之间为1秒间隔,采用定时器实现。 #include reg52.h sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4; code unsigned char image ={ {0xFF,0xC3,0xDB,0xDB,0xC3,0xDF,0xDF,0xC3}, //要显示数字9时,对于的P0值 {0xFF,0xC3,0xDB,0xDB,0xC3,0xDB,0xDB,0xC3}, {0xFF,0xC3,0xDF,0xDF,0x
[单片机]
51单片机入门——LCD1602
1.初识 LCD1602 LCD ( Liquid Crystal Display 的简称)液晶显示器。 LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置TFT(薄膜晶体管),上基板玻璃上设置彩色滤光片,通过TFT上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。 1.1.1602 液晶的硬件接口 1602 液晶,从它的名字我们就可以看出它的显示容量,就是可以显示 2 行,每行 16 个字符的液晶。它的工作电压为 4.5V~5.5V ,对于这点我们在设计电路的时候,直接按照 5V 系统设计即可,但是要保证我们的 5V 系统不能低于 4.5V 。在 5V 工作
[单片机]
<font color='red'>51单片机</font>入门——LCD1602
51单片机外部中断点亮LED
外部中断软件设计原理 中断发生的三个条件 ①中断源有中断请求; ②此中断源的中断允许位为 1; ③CPU 开中断(即 EA=1)。 比如我们配置外部中断 0,对应的配置程序如下: EA=1;//打开总中断开关 EX0=1;//开外部中断 0 IT0=0/1;//设置外部中断的触发方式(下降沿触发) 如果要配置的是外部中断 1,只需将 EX0 改为 EX1,IT0 改为 IT1 在编写程序时通常我们会将外部中断的配置放到一个自定义函数内便于管 理维护。如下伪代码所示: void Int0Init() { //设置 INT0 IT0=1;//边沿触发方式(下降沿) EX0=1;//打开 INT0 的中断允许。 EA=1;//打开总
[单片机]
51单片机完全不工作,该怎么入手去检查
首先应该确认电源电压是否正常。用电压表测量接地引脚跟电源引脚之间的电压,看是否是电源电压,例如常用的5V。接下来就是检查复位引脚电压是否正常。分别测量按下复位按钮和放开复位按钮的电压值,看是否正确。然后再检查晶振是否起振了,一般用示波器来看晶振引脚的波形,注意应该使用示波器探头的“X10”档。另一个办法是测量复位状态下的IO口电平,按住复位键不放,然后测量IO口(没接外部上拉的P0口除外)的电压,看是否是高电平,如果不是高电平,则多半是因为晶振没有起振。另外还要注意的地方是,如果使用片内ROM的话(大部分情况下如此,现在已经很少有用外部扩ROM的了),一定要将EA引脚拉高,否则会出现程序乱跑的情况。有时用仿真器可以,而烧入片子不行
[单片机]
51单片机向PC电脑发送汉字的方法
简介:最近看到有朋友在网上问单片机怎么向电脑发送一串汉字这个问题,其实这个问题也不难.呵呵.只要把相关的参数设置好一些,然后把汉字定义成一组字符向电脑发送就可以. 为了让大家更明确的了解,我就写了下面的一个程序来演示一下. 操作条件: 1.XP操作系统. 2.XP的超级终端显示. 3.WJ-V4.0开发板. 4.单片机STC89C52. 5.晶振11.0592M 操作步骤: 1.设置TMOD设置波特率和定时器1的工作方式. 2.设置定时器的初始值. 3.设置串行口工作方式. 4.设置波特率不加倍. 5.打开TR1允许发送. 6.启动定时器. 7.串行中断打开. 8.打开E
[单片机]
<font color='red'>51单片机</font>向PC电脑发送汉字的方法
基于51单片机12864简易计算器
终于写计算器了,其实计算器老早就写好了的,只是那会一直在忙考试还有实验室项目,所以没能空出时间来写博客。现在寒假在家,终于可以静心的学点东西了。 下面就先写点自己写这个程序的过程。其实这是个单片机课的期末课题,但是没有几个能写的好的。计算器其实要考虑周全也是很复杂的,。但我们只要求做简易计算器,所以我的计算器只有整数加减乘除,带负数功能。经过检验,实用性还是可以的。 这个程序的整体思路很简单,主要是一些细节的处理。 思路是,先矩阵键盘扫描,监测运算符号按下,存储两个运算数,计算结果,整个过程的实时显示。 先是矩阵键盘扫描,我以前一直用的郭天祥教的方法,这种方法很好理解,但是缺点是代码太长了,于是我上网去找一种简单的矩阵键
[单片机]
基于C语言51单片机电子密码锁的设计与仿真
  0、引言   电子密码锁是现代生活中常用的加密工具。它克服了机械式密码锁密码量少、安全性能差的缺点,尤其是的智能电子密码锁;不仅具有电子密码锁的功能”还可引人智能化管理功能,从而使密码锁具有更离的安全性和可靠性。   电子密码锁通常使用ARM和单片机控制,单片机相对ARM实现较为简单,功能较为完善,因此使用单片机控制较多。用单片机控制的窖码锁常使用汇编语言编写程序,显示器多数用。而本文所介绍的电子密犸锁使用移植性及可读性强的高级语言C语言编写,便于修改和增减功能蚤同时采用显示清楚数码管,功率消耗小而且寿命长的 液晶显示器,显示更加直观,使用更加方便。从经济实用的角度出发,采用STC89C52单片机设计出一种具有密码设置、报
[单片机]
基于<font color='red'>C语言</font><font color='red'>51单片机</font>电子密码锁的设计与仿真
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
更多每日新闻
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved