明天就要课设答辩了 影响着自己毕业。求大神帮我讲解一下这个程序 谢谢了
#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(); //刷新数码管显示,放在中断中保证及时刷新显示
}