您的位置 首页 观点

AT89C51单片机快热式热水器程序设计

AT89C51单片机快热式热水器程序设计-voiddelay(unsignedint);//延时函数

voiddisplay(void);//显示函数

unsignedcharkeysCAN(void);//按键扫描处理函数

voidheatCTRl(void);//加热控制函数

voidtemptest(void);//测温函数

sbitswkey=P1^0;//开关键

sbitupkey=P1^1;//加热档位“+”键

sbitdownkey=P1^2;//加热档位“-”键

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

//#pragmaSRC

#include

#include

#include

voiddelay(unsignedint);//延时函数

voiddisplay(void);//显现函数

unsignedcharkeysCAN(void);//按键扫描处理函数

voidheatCTRl(void);//加热操控函数

voidtemptest(void);//测温函数

sbitswkey=P1^0;//开关

sbitupkey=P1^1;//加热档位“+”键

sbitdownkey=P1^2;//加热档位“-”键

sbitbuzz=P1^05;//蜂鸣器输出端

sbittriac=P1^6;//可控硅触发信号输出端

sbitrelay=P1^7;//继电器操控信号输出端

sbitLED1=P2^5;//加热档位指示灯1

sbitled2=P2^6;//加热档位指示灯2

sbitled3=P2^7;//加热档位指示灯3

signedchardatactemp;//当时测得水温寄存器

unsignedchardatadispram[2]={0x10,0x10};//显现区缓存

unsignedchardataheatpower,px0count;//加热档位寄存器、外中止0计数器

bittempov,t0tst,testok;//超温标志、测温开端标志、测温完结标志

AT89C51单片机快热式热水器程序设计

/*———————————————-

主函数voidmain(void)

无参数,无回来值

循环调用显现、键扫描、温度检测、加热操控函数

———————————————-*/

voidmain(void)

{

unsignedchari,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();//调用加热操控函数

}//endfor(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;//送显现(带灭零)

}//endwhile(1)

}

/*————————————–

延时函数voiddelay(unsignedintdt)

参数:dt,无回来值

延时时刻=dt*500机器周期

————————————–*/

voiddelay(unsignedintdt)

{

registerunsignedcharbt;//界说寄存器变量

for(;dt;dt–)

for(bt=250;–bt;);//此句编译时以“DJNZ”完结,250*2=500机器周期

}

/*————————————–

显现函数voiddisplay(void)

无参数,无回来值

两位共阳数码管扫描显现

————————————–*/

voiddisplay(void)

{

unsignedcharcodetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,

0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff};

unsignedchari,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;//消影

}

}

/*———————————————————-

按键扫描处理函数unsignedcharkeyscan(void)

无参数,回来值:无符号字符型,无键按下为0,有键按下为其它

影响全局变量:heatpower

———————————————————-*/

unsignedcharkeyscan(void)

{

unsignedchari,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);//回来有键按下

}

elseif(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);//回来有键按下

}

elseif(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);//回来无键按下

}

elsereturn(0);//无任何键按下时由此回来

}

/*————————————–

加热操控函数voidheatctrl(void)

无参数,无回来值

判别是否加热、加热功率及档位指示灯处理

————————————–*/

voidheatctrl(void)

{

if(!tempov)//当没有超温标志时

{

relay=0;//接通继电器

buzz=1;//封闭蜂鸣器

switch(heatpower)//判别加热档位

{

case0:{EX1=0;ET1=0;triac=1;led1=1;led2=1;led3=1;break;}//0档不加热,指示灯不亮

case1:

case2:

case3:

case4:{led1=0;led2=1;led3=1;EX1=1;break;}//1~4档1号指示等亮

case5:

case6:

case7:

case8:{led1=0;led2=0;led3=1;EX1=1;break;}//5~8档1号、2号指示灯亮

case9:{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;//蜂鸣报警

}

}

/*————————————–

测温函数voidtemptest(void)

无参数,无回来值,

影响全局变量:ctemp,tempov

丈量并查表核算温度,判别是否超温

————————————–*/

voidtemptest(void)

{

signedchartemp,tempmin,tempmax;

unsignedintt0rig;

unsignedintcodetemptab[]={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=(unsignedint)TH0《《8|TL0;//字节组成

tempmin=0;//以下是二分查表法核算温度值

tempmax=100;//tempmin和tempmax为温度表的规模

while(1)

{

temp=(tempmax+tempmin)/2;//假定当时温度为最大值与最小值之中点值

if(t0rig==temptab[temp])break;//若实践值等于假定值完毕查找

elseif(t0rig》temptab[temp])tempmax=temp;//若实践值大于假定值,减小查找规模的最大值

elsetempmin=temp;//若实践值小于假定值,增大查找规模的最小值

if(tempmax-tempmin《=1)//若查找规模已缩小到1度之间,

{//判别实践值更挨近哪个端点

if(temptab[tempmax]+temptab[tempmin]》2*t0rig)temp=tempmax;//挨近最大值取最大值

elsetemp=tempmin;//挨近最小值取最小值

break;//完毕查找

}

}

ctemp=temp;//改写当时温度寄存器

if(temp》65)tempov=1;//假如温度超越65度置位超温标志

elseif(temp《45)tempov=0;//当温度回落到45度以下时铲除超温标志

}

/*——————————————

测温频率测验函数voidtempFrequency(void)

运用外部X0中止,寄存器组1

测出温度——频率转化电路的频率

——————————————*/

voidtempfrequency(void)interrupt0using1

{

if(–px0count)return;//找齐起点或计数

if(t0tst)//假如是起点

{

t0tst=0;//铲除测频开端标志

px0count=100;//取100个方波为一次测频

TH0=0;

TL0=0;//铲除计时器T0

TR0=1;//开端计时

}

else//假如是结尾

{

TR0=0;//中止计时

EX0=0;//中止测频外中止

testok=1;//置位测频完结标志

}

}

/*————————————–

加热操控过〇检测函数voidpass0(void)

运用外部X1中止,寄存器组2

检测过〇点,给定时器T1赋初值

————————————–*/

voidpass0(void)interrupt2using2

{

unsignedcharcodepowertab[]={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

}

/*——————————————

可控硅触发信号操控函数voidtriaCCtrl(void)

运用定时器T1中止,寄存器组3

向可控硅送出触发信号

——————————————*/

voidtriacctrl(void)interrupt3using3

{

registerunsignedchari;

triac=0;//输出可控硅导通信号

ET1=0;//封闭定时器T1中止

TR1=0;//停止定时器运转

for(i=0;i《2;i++);//延时,确保导通信号有满足的宽度

triac=1;//完结可控硅导通信号

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/guandian/345116.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部