#include
#define uchar unsigned char
#define uint unsigned int
//定义共阴数码管段码0-9
uchar code segment[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x6F};
sbit A_R = P2 ^ 0; // 定义A路的红灯
sbit A_Y = P2 ^ 1; // 定义A路的黄灯
sbit A_G = P2 ^ 2; // 定义A路的绿灯
sbit B_R = P2 ^ 3; // 定义B路的红灯
sbit B_Y = P2 ^ 4; // 定义B路的黄灯
sbit B_G = P2 ^ 5; // 定义B路的绿灯
sbit A_SEG_EN_1 = P0 ^0; // 定义A路的数码管的第一个位的使能
sbit A_SEG_EN_2 = P0 ^1; // 定义A路的数码管的第二个位的使能
sbit B_SEG_EN_1 = P0 ^2; // 定义B路的数码管的第一个位的使能
sbit B_SEG_EN_2 = P0 ^3; // 定义B路的数码管的第二个位的使能
sbit key = P0 ^ 7; // 紧急按键
bit flag = 0; // 标志是否处于紧急状态,紧急状态flag=1
//作用:延时 z ms
//参数:z
//返回值:
void delay(uint z) // 利用不停的运行空代码来消耗时间
{
uint x, y;
for (x = z; x>0; x--)
for (y = 110; y>0; y--);
}
void check_buttn()
{
//检测按键key
if (key == 0) // 如果按键被按下
{
delay(10); // 消抖
if (key == 0) // 确认按键被按下
{
flag = !flag; // 紧急标志位取反
while (!key); // 等待按键释放
}
}
}
void seg_display(int numA, int numB)
{
P0 |= 0x7F; // 关闭所有数码管的片选
P3 = segment[numA/10]; // 显示A路计时的十位
A_SEG_EN_1 = 0; // 打开A路的十位的使能
P1 = segment[numB/10]; // 显示B路计时的十位
B_SEG_EN_1 = 0; // 打开B路的十位的使能
delay(5); // 延时,是数据在数码管上停留一段时间
P0 |= 0x7F; // 关闭所有数码管的片选
P3 = segment[numA%10]; // 显示A路计时的个位
A_SEG_EN_2 = 0; // 打开A路的个位的使能
P1 = segment[numB%10]; // 显示B路计时的个位
B_SEG_EN_2 = 0; // 打开B路的个位的使能
delay(5); // 延时,是数据在数码管上停留一段时间
}
void display(int numA, int numB)
{
int i = 0;
int temp = P2; // 保存红绿灯的状态
for(i=0; i<50; i++)
{
check_buttn(); // 按键检测
if(flag) // 如果处于紧急状态
{
while(flag) // 紧急状态中
{
P2 = 0x09; // 将AB路都变成红灯
seg_display(numA, numB); // 显示计时
check_buttn(); // 按键检测
}
P2 = temp; // 还原进入紧急之前的状态
}
seg_display(numA, numB); // 显示计时
}
}
void main()
{
int j=0;
P2 = 0; //先关闭所有的红绿灯,为了防止刚打开仿真的时候有闪烁
while(1)
{
A_G = 1;
B_R = 1;
for (j=10; j>=0; j--)
display(j/2, j/2);
P2 = 0;
for (j=5; j>=0; j--)
{
A_Y = 1;
B_R = 1;
display(j, j+25);
A_Y = 0;
B_R = 1;
display(j, j+25);
}
P2 = 0;
A_R = 1;
B_G = 1;
for (j=25; j>=0; j--)
display(j+5, j);
P2 = 0;
A_R = 1;
B_Y = 1;
for (j=5; j>=0; j--)
display(j, j);
P2 = 0;
}
}