找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1645|回复: 0
打印 上一主题 下一主题
收起左侧

经典交通灯程序 只为学习 无任何意图

[复制链接]
跳转到指定楼层
楼主
ID:141089 发表于 2016-12-16 15:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include <reg52.h>
sbit  ADDR3 = P1^3;
sbit  ENLED = P1^4;
unsigned char code LedChar[] = {  //数码管显示字符转换表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[7] = {  //数码管+独立LED显示缓冲区
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
bit flag1s = 1;          //1秒定时标志
unsigned char T0RH = 0;  //T0重载值的高字节
unsigned char T0RL = 0;  //T0重载值的低字节
void ConfigTimer0(unsigned int ms);
void TrafficLight();
void main()
{
    EA = 1;      //开总中断
    ENLED = 0;   //使能数码管和LED
    ADDR3 = 1;
        ConfigTimer0(1);  //配置T0定时1ms

    while (1)
    {
        if (flag1s)  //每秒执行一次交通灯刷新
        {
            flag1s = 0;
            TrafficLight();
        }
    }
}
/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0(unsigned int ms)
{
    unsigned long tmp;  //临时变量

    tmp = 11059200 / 12;      //定时器计数频率
    tmp = (tmp * ms) / 1000;  //计算所需的计数值
    tmp = 65536 - tmp;        //计算定时器重载值
    tmp = tmp + 13;           //补偿中断响应延时造成的误差
    T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
    T0RL = (unsigned char)tmp;
    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0为模式1
    TH0 = T0RH;     //加载T0重载值
    TL0 = T0RL;
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
}
/* 交通灯显示刷新函数 */
void TrafficLight()
{
    static unsigned char color = 2;  //颜色索引:0-绿色/1-黄色/2-红色
    static unsigned char timer = 0;  //倒计时定时器

    if (timer == 0) //倒计时到0时,切换交通灯
    {
        switch (color)  //LED8/9代表绿灯,LED5/6代表黄灯,LED2/3代表红灯
        {
            case 0:     //切换到黄色,亮3秒
                color = 1;
                timer = 2;
                LedBuff[6] = 0xE7;
                break;
            case 1:     //切换到红色,亮30秒
                color = 2;
                timer = 29;
                LedBuff[6] = 0xFC;
                break;
            case 2:     //切换到绿色,亮40秒
                color = 0;
                timer = 39;
                LedBuff[6] = 0x3F;
                break;
            default:
                break;
        }
    }
    else  //倒计时未到0时,递减其计数值
    {
        timer--;
    }
    LedBuff[0] = LedChar[timer%10];  //倒计时数值个位显示
    LedBuff[1] = LedChar[timer/10];  //倒计时数值十位显示
}
/* LED动态扫描刷新函数,需在定时中断中调用 */
void LedScan()
{
    static unsigned char i = 0;  

    P0 = 0xFF;            
    P1 = (P1 & 0xF8) | i;  
    P0 = LedBuff[i];     
    if (i < 6)            
        i++;
    else
        i = 0;
}
/* T0中断服务函数,完成LED扫描和秒定时 */
void InterruptTimer0() interrupt 1
{
    static unsigned int tmr1s = 0;  

    TH0 = T0RH;  
    TL0 = T0RL;
    LedScan();   
    tmr1s++;     
    if (tmr1s >= 1000)
    {
        tmr1s = 0;
        flag1s = 1;  
    }
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表