weixin_43238148 2018-12-25 23:03 采纳率: 0%
浏览 2199

51单片机十字路口交通灯设计 求问

明天就要课设答辩了 影响着自己毕业。求大神帮我讲解一下这个程序 谢谢了

#include <reg51.h>
#include<absacc.h>  
#define COM XBYTE[0xCFE9] 
#define DAT XBYTE[0xCFE8]      
void Init_8279(void);   
void led_display(void);
void Key_Scan(void);    
void key_action(void);  
void led_init_status(void);            
void delay(void);          
unsigned char led_buf[8];      //数码管显示缓冲数组
unsigned char KeyVal = 0x00;    //当前按键的键值
unsigned char led_char[17] = {    //数码管数字真值表         
    0x3f,0x06,0x5b,0x4f,
    0x66,0x6d,0x7d,0x07,
    0x7f,0x6f,0x77,0x7c,
    0x39,0x5e,0x79,0x71,
                         }; 
sbit R_LED1 = P1^0;
sbit G_LED1 = P1^1;
sbit Y_LED1 = P1^2;
sbit Y_LED3 = P1^3;
sbit R_LED2 = P1^4;
sbit G_LED2 = P1^5;
sbit Y_LED2 = P1^6;
sbit Y_LED4 = P1^7;

int main(void)
{
    TMOD = 0x01;      //定时器模式设置
    TH0 = 0xfc;     
    TL0 = 0x18;      
    TR0 = 1;         
    EA = 1;           //总中断使能
    ET0 = 1;          //定时器中断0使能
    Init_8279();

    while(1)
    {
        Key_Scan();     //按键扫描函数        
    }
}

void Init_8279(void)
{
    COM = 0xd1;             //总清除命令
    do
    {
        ACC = COM;
    }                            //读取8279状态
    while(ACC^7 == 1);         //等待清除结束 
    COM = 0x00;         //8个字符显示,左入口;,双键锁定
    COM = 0x2a;        //时钟分频
}                     //数码管显示函数,实现数码管动态扫描
void led_display(void)
{
    static unsigned char j = 0;        //静态局部变量,只初始化一次,
    COM = 0x82 + j; //发送显示地址,0x80为左一,程序里0x80,0x81数码管未使用,j = 0时,显示0x82位置的数码管,j=1时83,。。。
    DAT = led_buf[j];       //依次把缓冲数组的内容显示
    j++;
    if(j >= 4)                   //四个数码管
       j = 0;
}                               //按键扫描函数, 主循环调用
void Key_Scan(void)
{
    unsigned char temp = 0;
while((temp & 0x0f) == 0)        //没有检测到按键程序停在这里,中断服务函数负责完成其他工作
    {
        temp = COM;
    }                           //能执行到此处说明检测到了按键
    COM = 0x40;         //读按键值命令
    KeyVal = DAT;         //取键值
    KeyVal &= 0x0f;       //取低4位
    KeyVal += 1;          //因为按下第一个按键时,得到的键值位0x00,加一为了后面方便操作
    key_action();         //检测到按键,并执行相应动作
}

unsigned long sec_1s = 0;          //全局时间,赋值多少当前秒是多少
unsigned char xingren = 0;
unsigned char sec_1s_bak = 0;
unsigned char bianhuan = 40;
void key_action(void)
{if(KeyVal == 0x01)    
    {xingren = 1;
        sec_1s_bak = sec_1s;
        sec_1s = 0;
    }
    if(KeyVal == 0x02)
    {bianhuan = 40;
        sec_1s = 0;
    }
    if(KeyVal == 0x03)
    {bianhuan = 20;
        sec_1s = 0;
    }
    if(KeyVal == 0x04)
    {bianhuan = 10;
        sec_1s = 0;
    }                   
}
unsigned long ms2 = 0;     //2ms计数
bit dir = 1;
void InterruptTimer0() interrupt 1
{   TH0 = 0xfc;    //重新装在定时器的值
    TL0 = 0x18; 
    ms2++;    //进来一次表示2ms
  if(ms2 >= 500)      //累计500次则表示1s
    {   ms2 = 0;      //归零
        sec_1s++;      //1s计数器 加一
        if(xingren == 1)
        {                R_LED1 = 0;
                         G_LED1 = 1;
                         Y_LED1 = 1;
                         Y_LED3 = 1;
                         R_LED2 = 0;
                         G_LED2 = 1;
                         Y_LED2 = 1;
                         Y_LED4 = 1;
            led_buf[2] = led_char[0];   
            led_buf[3] = led_char[10 - sec_1s]; 
                        if(sec_1s == 9)
            {  xingren = 0;
                P1 = 0XFF;
                sec_1s = sec_1s_bak;
            }


        }
        else if(sec_1s >= 0 && sec_1s <= bianhuan)
        {   if(dir)
            {           R_LED1 = 0;
                    G_LED2 = 0; 
            }
            else
            {
                R_LED2 = 0;
                G_LED1 = 0;         
}
            led_buf[2] = led_char[(bianhuan + 1 - sec_1s)/10];   
            led_buf[3] = led_char[(bianhuan + 1 - sec_1s)%10]; 
       }
        else if(sec_1s >= bianhuan && sec_1s <= bianhuan + 4)
        {        R_LED1 = 1;
                         G_LED1 = 1;
                         Y_LED1 = 0;
                         Y_LED3 = 0;
                         R_LED2 = 1;
                         G_LED2 = 1;
                         Y_LED2 = 0;
                         Y_LED4 = 0;                                
            led_buf[0] = led_char[0];   
            led_buf[1] = led_char[4 - sec_1s%10]; 
            if(sec_1s == bianhuan + 4)
            {
                sec_1s = 0;
                dir = ~dir;
                Y_LED1 = 1;
                Y_LED3 = 1;
              Y_LED2 = 1;
                Y_LED4 = 1;
            }
        }   
    }
    led_display();       //刷新数码管显示,放在中断中保证及时刷新显示
}

  • 写回答

1条回答

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-09-09 15:31
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 以帮助更多的人 ^-^
    评论

报告相同问题?

悬赏问题

  • ¥35 平滑拟合曲线该如何生成
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站