weixin_43238148
weixin_43238148
采纳率0%
2018-12-25 23:03 阅读 2.1k

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();       //刷新数码管显示,放在中断中保证及时刷新显示
}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

相关推荐