131 1300 0010
其他
当前位置: 首页>> 元件技术>>其他>>
  • 导航栏目
  • 二极管
  • 整流桥
  • MOS管
  • 其他
  • AT89C51单片机快热式热水器程序设计
    AT89C51单片机快热式热水器程序设计
  • AT89C51单片机快热式热水器程序设计
  •   发布日期: 2019-05-27  浏览次数: 954

    快热式热水器程序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;//完成可控硅导通信号

    }


  • ·上一篇:
    ·下一篇:
  • 其他关联资讯
    深圳市日月辰科技有限公司
    地址:深圳市宝安区松岗镇潭头第二工业城A区27栋3楼
    电话:0755-2955 6626
    传真:0755-2978 1585
    手机:131 1300 0010
    邮箱:hu@szryc.com

    深圳市日月辰科技有限公司 版权所有:Copyright©2010-2023 www.szryc.com 电话:13113000010 粤ICP备2021111333号