AT89C51快热式热水器程序

发布者:创意狂想最新更新时间:2018-01-07 来源: eefocus关键字:AT89C51  快热式热水器 手机看文章 扫描二维码
随时随地手机看文章

快热式热水器程序MCU AT89C51  XAL 12MHz

//#pragma  SRC 
#include  
#include  
#include  
void delay(unsigned int);       //延时函数

void display(void);             //显示函数 
unsigned char keysCAN(void);    //按键扫描处理函数 
void heatCTRl(void);            //加热控制函数 
void temptest(void);            //测温函数 
sbit swkey=P1^0;                //开关键 
sbit upkey=P1^1;                //加热档位“+”键 
sbit downkey=P1^2;              //加热档位“-”键 
sbit buzz=P1^05;                //蜂鸣器输出端 
sbit triac=P1^6;                //可控硅触发信号输出端 
sbit relay=P1^7;                //继电器控制信号输出端 
sbit LED1=P2^5;                 //加热档位指示灯1 
sbit led2=P2^6;                 //加热档位指示灯2 
sbit led3=P2^7;                 //加热档位指示灯3 
signed char data ctemp;         //当前测得水温寄存器 
unsigned char data dispram[2]={0x10,0x10};  //显示区缓存 
unsigned char data heatpower,px0count;      //加热档位寄存器、外中断0计数器 
bit tempov,t0tst,testok;        //超温标志、测温开始标志、测温完成标志 
/*---------------------------------------------- 
  主函数 void main(void) 
  无参数,无返回值 
  循环调用显示、键扫描、温度检测、加热控制函数 
----------------------------------------------*/ 
void main(void) 
{  
unsigned char i,j; 
ctemp=15;                       //初始化水温寄存器 
heatpower=5;                    //初始化加热档位为5当 
tempov=0;                       //清除超温标志 
swkey=0;                        //默认开关键被按下,进入待机状态 
TMOD=0x11;                      //设定T0和T1工作方式为16位定时器 
TCON=0x05;                      //设置外中断0和1为下降沿触发 
IP=0x01;                        //设置外中断0优先 
IE=0x80;                        //打开总中断 
while (1) 
  { 
  i=1; 
  do{ 
    for (j=0;j<100;j++)         //循环100次约0.5s 
      { 
      if (keyscan()) i=6;       //如果有键按下,显示当前档位3s 
      display();                //调用显示函数一次约4ms 
      heatctrl();               //调用加热控制函数 
      }//end for (b=0;b<100;b++) 
    temptest();                 //每0.5s进行一次测温 
    } while (--i);              //通过改变循环次数i的大小决定是否刷新显示 
  j=abs(ctemp);                 //取温度绝对值 
  dispram[1]=j%10;              //取个位数送显示 
  j/=10;                        //取十位数 
  dispram[0]=j?j:0x11;          //送显示(带灭零) 
  }//end while (1) 
}  

/*-------------------------------------- 
  延时函数 void delay(unsigned int dt) 
  参数:dt,无返回值 
  延时时间=dt*500机器周期 
--------------------------------------*/ 
void delay(unsigned int dt) 

register unsigned char bt;      //定义寄存器变量 
for (; dt; dt--) 
  for (bt=250; --bt; );         //此句编译时以“DJNZ”实现,250*2=500机器周期 


/*-------------------------------------- 
  显示函数 void display(void) 
  无参数,无返回值 
  两位共阳数码管扫描显示 
--------------------------------------*/ 
void display(void) 

unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\ 
                            0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff}; 
unsigned char i,a; 
a=0xfe;                         //位选赋初值 
for (i=0; i<2; i++)             //循环扫描两位数码管 
  { 
  P2|=0x1f;                     //清除位选 
  P0=table[dispram[i]];         //送显示段码 
  P2&=a;                        //选通一位 
  delay(4);                     //延时2ms 
  a=_crol_(a,1);                //改变位选字 
  P0=0xff;                      //消影 
  } 


/*---------------------------------------------------------- 
  按键扫描处理函数 unsigned char keyscan(void) 
  无参数,返回值:无符号字符型,无键按下为0,有键按下为其它 
  影响全局变量:heatpower 
----------------------------------------------------------*/ 
unsigned char keyscan(void) 

unsigned char i,ch; 
if (upkey==0)                   //“+”键 
  { 
  buzz=0;                       //打开蜂鸣器(发出按键音) 
  for (i=0;i<5;i++) display();  //延时消抖 
  buzz=1;                       //关闭蜂鸣器 
  if (heatpower<9) heatpower++; //档位加一 
  dispram[0]=0; 
  dispram[1]=heatpower;         //显示当前档位 
  while (upkey==0) display();   //等待键释放 
  return (1);                   //返回有键按下 
  } 
  else if (downkey==0)          //“-”键 
  { 
  buzz=0;                       //打开蜂鸣器(发出按键音) 
  for (i=0;i<5;i++) display();  //延时消抖 
  buzz=1;                       //关闭蜂鸣器 
  if (heatpower>0) heatpower--; //档位减一 
  dispram[0]=0; 
  dispram[1]=heatpower;         //显示当前档位 
  while (downkey==0) display(); //等待键释放 
  return (2);                   //返回有键按下 
  } 
  else if (swkey==0)            //开关键 
  { 
  buzz=0;                       //打开蜂鸣器(发出按键音) 
  for (i=0;i<30;i++) display(); //延时消抖 
  buzz=1;                       //关闭蜂鸣器 
  swkey=1;                      //置位开关键 
  while (swkey==0) display();   //等待键释放 
  ch=IE;                        //暂存中断控制字IE 
  IE=0x00;                      //禁止中断 
  P0=0xff; 
  P1=0xff; 
  P2=0xff;                      //清除端口输出 
  dispram[0]=0x10; 
  dispram[1]=0x10;              //显示“--” 
  display(); 
  while (1) 
    { 
    while (swkey) display();     //等待开关键按下 
    buzz=0;                      //打开蜂鸣器(发出按键音) 
    for (i=0;i<10;i++) display();//延时消抖 
    buzz=1;                      //关闭蜂鸣器 
    if (swkey==0) break;         //确认开关键被按下 
    } 
  while (swkey==0) display();    //等待键释放 
  IE=ch;                         //还原中断控制字IE 
  return (0);                    //返回无键按下 
  } 
  else return (0);               //无任何键按下时由此返回 


/*-------------------------------------- 
  加热控制函数 void heatctrl(void) 
  无参数,无返回值 
  判断是否加热、加热功率及档位指示灯处理 
--------------------------------------*/ 
void heatctrl(void) 

if (!tempov)                     //当没有超温标志时 
  { 
  relay=0;                       //接通继电器 
  buzz=1;                        //关闭蜂鸣器 
  switch (heatpower)             //判断加热档位 
    { 
    case 0: {EX1=0;ET1=0;triac=1;led1=1;led2=1;led3=1;break;}//0档不加热,指示灯不亮 
    case 1: 
    case 2: 
    case 3: 
    case 4: {led1=0;led2=1;led3=1;EX1=1;break;} //1~4档1号指示等亮 
    case 5: 
    case 6: 
    case 7: 
    case 8: {led1=0;led2=0;led3=1;EX1=1;break;} //5~8档1号、2号指示灯亮 
    case 9: {EX1=0;ET1=0;led1=0;led2=0;led3=0;triac=0;break;} //9档全功率,指示灯全亮 
    } 
  } 
  else                           //当有超温标志时 
  { 
  relay=1;                       //断开继电器 
  EX1=0; ET1=0; triac=1;         //关闭可控硅 
  buzz=0;                        //蜂鸣报警 
  } 


/*-------------------------------------- 
  测温函数 void temptest(void) 
  无参数,无返回值, 
  影响全局变量:ctemp,tempov 
  测量并查表计算温度,判断是否超温 
--------------------------------------*/ 
void temptest(void) 

signed char temp,tempmin,tempmax; 
unsigned int t0rig; 
unsigned int code temptab[]={0x6262,0x61eb,0x6171,0x60f7,0x6047,0x5ff7,0x5f6e,0x5eef,0x5e53,0x5dbe,0x5d4b,0x5ca5,0x5c17,\ 
                             0x5b6b,0x5ada,0x5a5c,0x599b,0x58ff,0x5869,0x57b0,0x570d,0x5663,0x55c6,0x550e,0x5444,0x5396,\ 
                             0x52dd,0x5240,0x5189,0x50b0,0x5005,0x4f20,0x4e69,0x4db1,0x4cef,0x4c42,0x4b64,0x4aaa,0x49e1,\ 
                             0x48fc,0x4847,0x476c,0x46b1,0x4604,0x4503,0x4449,0x4356,0x4299,0x41c0,0x40ce,0x3ff0,0x3f2b,\ 
                             0x3e33,0x3d86,0x3ca6,0x3bd2,0x3b26,0x3a39,0x3973,0x38a6,0x37ef,0x373f,0x3687,0x35c3,0x3507,\ 
                             0x3487,0x33bc,0x32ed,0x324f,0x319e,0x3106,0x3053,0x2fa6,0x2f2a,0x2e88,0x2e00,0x2d63,0x2cd6,\ 
                             0x2c65,0x2bae,0x2b28,0x2a97,0x2a07,0x298e,0x2914,0x287a,0x280d,0x278a,0x2703,0x2687,0x2626,\ 
                             0x25e5,0x256d,0x24ee,0x2489,0x2414,0x23bc,0x2356,0x22d9,0x2278,0x2203}; //温度频率表 
px0count=2;                      //测频中断函数参数 
t0tst=1;                         //置测频程序开始标志 
EX0=1;                           //打开测频外中断 
testok=0;                        //清除测频程序完成标志 
while (!testok) display();       //等待测试完成 
t0rig=(unsigned int)TH0<<8|TL0;  //字节合成字 
tempmin=0;                       //以下是二分查表法计算温度值 
tempmax=100;                     //tempmin和tempmax为温度表的范围 
while (1) 
  { 
  temp=(tempmax+tempmin)/2;        //假定当前温度为最大值与最小值之中点值 
  if (t0rig==temptab[temp]) break; //若实际值等于假定值结束查找 
    else if (t0rig>temptab[temp]) tempmax=temp;//若实际值大于假定值,减小查找范围的最大值 
    else tempmin=temp;             //若实际值小于假定值,增大查找范围的最小值 
  if (tempmax-tempmin<=1)          //若查找范围已缩小到1度之间, 
    {                              //判断实际值更接近哪个端点 
    if (temptab[tempmax]+temptab[tempmin]>2*t0rig) temp=tempmax;//接近最大值取最大值 
      else temp=tempmin;           //接近最小值取最小值 
    break;                         //结束查找 
    } 
  } 
ctemp=temp;                        //刷新当前温度寄存器 
if (temp>65) tempov=1;             //如果温度超过65度置位超温标志 
  else if (temp<45) tempov=0;      //当温度回落到45度以下时清除超温标志 


/*------------------------------------------ 
  测温频率测试函数 void tempFrequency(void) 
  使用外部X0中断,寄存器组1 
  测出温度——频率转换电路的频率 
------------------------------------------*/ 
void tempfrequency(void) interrupt 0 using 1 

if (--px0count) return;         //找齐起点或计数 
if (t0tst)                      //如果是起点 
  { 
  t0tst=0;                      //清除测频开始标志 
  px0count=100;                 //取100个方波为一次测频 
  TH0=0; 
  TL0=0;                        //清除计时器T0 
  TR0=1;                        //开始计时 
  } 
  else                          //如果是终点 
  { 
  TR0=0;                        //停止计时 
  EX0=0;                        //停止测频外中断 
  testok=1;                     //置位测频完成标志 
  } 


/*-------------------------------------- 
  加热控制过〇检测函数 void pass0(void) 
  使用外部X1中断,寄存器组2 
  检测过〇点,给定时器T1赋初值 
--------------------------------------*/ 
void pass0(void) interrupt 2 using 2 

unsigned char code powertab[]={0xd8,0xf0,0xe2,0x63,0xe5,0x25,0xe8,0x3e,0xeb,0x16,0xed,0xda,0xf0,0xb2,0xf3,0xcb,0xf7,0x8d,0xf7,0x8d};//10个功率档位的可控硅导通角延时参数表 
TH1=powertab[2*heatpower]-1; 
TL1=powertab[2*heatpower+1];    //市电过零后,根据当前设置的档位给定时器T1赋延时参数 
ET1=1;                          //允许定时器T1中断 
TR1=1;                          //打开定时器T1 


/*------------------------------------------ 
  可控硅触发信号控制函数 void triaCCtrl(void) 
  使用定时器T1中断,寄存器组3 
  向可控硅送出触发信号 
------------------------------------------*/ 
void triacctrl(void) interrupt 3 using 3 

register unsigned char i; 
triac=0;                        //输出可控硅导通信号 
ET1=0;                          //关闭定时器T1中断 
TR1=0;                          //终止定时器运行 
for (i=0;i<2;i++);              //延时,保证导通信号有足够的宽度 
triac=1;                        //完成可控硅导通信号 


关键字:AT89C51  快热式热水器 引用地址:AT89C51快热式热水器程序

上一篇:AT89C52单片机控制BH1415F调频台C程序
下一篇:AT89C2051简易正弦波\三角波\方波发生器

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

采用AT89C51单片机实现动态车辆检测器系统的设计
引言 随着经济的发展,不停车收费系统(ETC)已在我国悄然兴起。不停车收费系统主要是由通讯、监控、收费三大系统组成。整个系统可靠运行的一个重要环节就是车辆检测器。在不停车收费系统中它是检测驶向通讯区域的车辆并命令天线进行通信的传感器,具有进入检测、车速检测、车型判别等功能;它是检测出离开通信区域的车辆、根据ETC车道控制器的判断控制栏杆、路侧显示器的传感器,具有进入检测功能;它具有检测车辆通过,控制清除针对该车辆的路侧显示器的显示内容以及控制针对后续车辆的显示的功能,并命令栏杆关闭的功能。 考虑到性能、价格、技术复杂性、可靠性、维护要求、适用范围等因素,我们这种车辆检测器是基于地感线圈原理研制的。 1、动态车辆检测器设计
[单片机]
采用<font color='red'>AT89C51</font>单片机实现动态车辆检测器系统的设计
基于单片机的温湿度分析遥控开关门窗系统
单片机控制系统在生产生活领域应用广泛,无论是从简单的有线控制还是到无线远程控制,都能体现单片机在电子控制领域非常重要。现代化的办公大楼里面各种控制开关系统更是离不开单片机系统,现在的办公设备和精密仪器需要严格的温度和湿度环境,基于单片机的温、湿、时遥控开关系统是采集当时的温度、湿度传感器传回的信息及内部时钟信息,经分析是否符合办公仪器设备和常规下人体舒适程度进行有效的门窗开关遥控。 系统的工作原理 温湿度遥控控制系统主要是由SHT11传感器进行温湿度采集的,将采集到的温湿度输入到单片机的AT89C51的P1.0接口,SCK信号输入到单片机的P1.1接口,由单片机的P1.2口将接收到的数据转发送到MICR102的STBY
[单片机]
基于AT89C51单片机的温度测控系统设计
0 引言 温度的测量和控制在日常生活和工业领域中具有广泛的应用,随着人们生活水平的大幅提高,对温度测量控制的精度和范围也有着更高的要求。在工业企业中,如何提高温度控制对象的运行性能一直以来都是控制人员和现场技术人员努力解决的问题,这类控制对象惯性大,滞后现象严重,存在很多不确定的因素,难以建立精确的数学模型,从而导致控制系统性能不佳,甚至出现控制不稳定、失控等现象。PID控制方式控制稳定且精度高,但是控制对象的模型难以建立,并且当扰动因素不明确时,参数调整较复杂。本文采用DS18B20数字温度传感器,该传感器具有微型化、封装简单、低功耗、高性能抗干扰能力、测量范围广、强易配处理器等优点,可使系统测量更加精确,电路更加简单。实验测
[单片机]
基于<font color='red'>AT89C51</font>单片机的温度测控系统设计
基于AT89C51的智能稳压电源设计
本文介绍了一种基于AT89C51的智能稳压电源的设计方案,其核心技术是通过AT89C51控制数模转换来改变其后稳压模块的输出。该系统由整流滤波初步稳压电路部分、AT89C51控制部分、DAC和显示部分组成,该稳压电源能连续步进可调,并可实时显示,弥补了传统稳压电源的不足。   本系统研究的直流稳压电源主要是符合智能化、数字化及模块化的特点:智能化指系统有可编程模块能对系统进行智能控制;数字化指系统输出电压通过7段数码管显示,并可通过按键对输出电压进行连续步进数字化调节;模块化指系统由各个相关模块组成,提高了系统的可靠性。   AT89C51智能型稳压电源设计原理   1、设计系统框图   系统由各模块组成,其模块构成
[模拟电子]
基于<font color='red'>AT89C51</font>的智能稳压电源设计
采用AT89C51多气体检测系统电路设计
  气体传感器是一种能将气体种类及其与浓度有关的信息转换成电气信号的装置。根据这些电气信号的强弱就可以获得与待测气体在环境中存在情况有关的信息,从而可以进行检测、监控、报警。因此由气体传感器与模式识别系统构成的智能化气味识别仪器有着广泛的应用领域,如食品工业、化学工业、环境监测、医学诊断、安全检查等,越来越受到广泛关注。   数据采集和数据处理系统   由气体传感器阵列输出的微弱电信号,经各自信号放大电路对信号进行预处理,使其转换为O ~5V 范围内变化的直流信号,送到A/D 转换电路变换为数字信号,对其进行数据采集处理。为了方便与89C51 单片机的连接,本系统选用ADC0809芯片对采集到的气体信息进行模数转换。其分辨率为8
[单片机]
采用<font color='red'>AT89C51</font>多气体检测系统电路设计
基于智能传感器的弹药库温/湿度监控系统设计
1 引言 弹药从出厂到部队作战或训练使用以前主要存放在仓库中。在长期的储存过程中,弹药虽然处于宏观静止状态。但其质量不断发生变化。这是因为弹药主要由金属和装药组成.在长期储存过程中,由于温,湿度的影响。金属会锈蚀.从而使金属部件的强度降低。表面机械性能变坏,严重影响弹药的使用.甚至会造成重大事故。温,湿度还会使弹药装药的物理和化学性质发生变化.从而使其失去应有的战技要求。因此,温,湿度是弹药质量发生变化的主要矛盾。根据我军的仓库条件、我国的气候条件和目前仓库的管理水平.通常规定最高温度不超过30℃.最大湿度不超过。70%.即通常所说的“三七”线。 传统弹药仓库的监控系统采用的是干,湿球湿度计、毛发湿度计、湿敏电阻器或由普通的温,
[单片机]
基于智能传感器的弹药库温/湿度监控系统设计
采用AT89C51单片机控制的量程自切换频率计
量程自切换频率计采用AT89C51单片机控制,主要由信号放大整形电路,单片机控制电路,分频电路,信号显示电路以及电源电路五个模块组成。本文阐述了系统的硬件组成及工作原理,论证了设计方案的可行性。系统程序采用C语言编写,经Keil软件进行调试后在Prote us软件中进行仿真,并且经过实物的测试,可以实现对不同波形的频率进行测量。具有自动切换并指示量程,精度较高,测量范围较大等特点。 近年来,随着科学技术的快速发展,特别是类似单片机等相关集成电路生产技术的快速堀起,推动了仪器仪表及家电产业的快速发展,用程序代码来简化硬件电路的复杂程度,使其不断向着体积小,价格低廉,功能更加多样化、智能化的方向发展。功能齐全,价格低廉的产
[单片机]
采用<font color='red'>AT89C51</font>单片机控制的量程自切换频率计
AT89C51单片机系统简介
AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51 ? 指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。 1.主要特性: ·与MCS-51 兼容 ·4K字节可编程闪烁存储器 寿命:1000写/擦循环 数据保留时间:10年 ·全静态工作:0Hz-24Hz ·三
[工业控制]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved