当前位置:首页 > 单片机 > 单片机
[导读] /*--------------------------------------快热式热水器程序MCUAT89C51XAL12MHz--------------------------------------*///#pragmaSRC#include#include#includevoiddelay(unsignedint);//延时函数void

/*--------------------------------------
快热式热水器程序
MCUAT89C51XAL12MHz
--------------------------------------*/
//#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;//超温标志、测温开始标志、测温完成标志
/*----------------------------------------------
主函数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;//完成可控硅导通信号
}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭