0x00 前言
学校实验室的阶段测试,是一个交通灯控制器,开始感觉貌似不太难,但是搞着搞着,发现情况不对,还是出现了些问题的(可能还是我菜),这周六中午放的题,下午,把大框搭好了,然后身体就开始不舒服(得好好锻炼身体了),等周日中午,感觉好一些了,继续完善了一下,开始调bug,,等晚上差不多了,就交了。有些可惜的是RCTF就在这两天,没参加上,等复现了。
笔者水平有限,但是还是分享一下。
0x01 题目
有一说一,第一眼看到题目时我是懵的,拓展里的1,2,3条我没看懂,没关系,还给了一个仿真图,我们来和仿真结合分析一下
仿真:
很清晰,不过,有些小错误,貌似没有绿灯,最后通过询问,我把D3,D6设为绿灯。
分析:
基础要求:
为了满足要求在循环播放时为:
A路:绿灯(10s)---> 黄灯 (闪烁4s)---> 红灯(10s)--->黄灯(闪烁4s)
B路:绿灯(10s)---> 黄灯 (闪烁4s)---> 红灯(10s)--->黄灯(闪烁4s)
紧急按键,是中断0。
当按下“紧急车辆”按钮,马上红灯(4s)。
(基础要求很好理解)
拓展要求:
1. 当按下A路检查,或B路检测,就代表A,B路来车了
2. 当在绿灯时,两路车都有车,就循环放行:首先A路绿灯,同时B路红灯;之后交换A路红灯,同时B路绿灯。
3.当只有一路车,且绿灯积累10s后,若另一路没有车,就继续放行,这里,的继续放行概念很模糊,这里我设置成:如果进入这种情况,数码管将 黑屏,且继续放绿灯,当另一路来车时,数码管退出黑屏。然和进入两路都有车的情况。
4. 修改没啥可说的,需要注意的,就是,所有的数字要用变量代替。
0x02 基础要求
先把 延时写上:
void Delay(u16 t)
{
while(t--);
}
数码管显示:
这个时候注意,因为在拓展要求时要进行修改还有需要的黑屏,所以数码管的显示一共有5种显示
1. 正常
2.放行时间修改模式
3.黄灯时间修改模式
4.紧急时间修改模式
5.黑屏
我们用一个变量 model来选择:
u8 code Duanxuan[]={ //????
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
u8 WE[]={0x00,0x00,0x00,0x00}; //位选
u16 numA=10, numB=10; //数码管的显示数字
u8 emergency_t = 4; //紧急时间
u8 Red_A_T = 10,Green_A_T = 10, Yellow_A_T =4;//A红绿灯
u8 Red_B_T = 10,Green_B_T = 10, Yellow_B_T =4;//B红绿灯
u8 model = 0; //用来判断修改哪个时间
void display(void)
{
static unsigned char i = 0;
P0 = 0xff;
P3 = (0x10 << i) | 0x04;
P0 = WE[i++];
i %= 4;
}
void SMC_show(void)
{
if(model == 0)//正常
{
WE[0] = ~Duanxuan[numA/10];
WE[1] = ~Duanxuan[numA%10];
WE[2] = ~Duanxuan[numB/10];
WE[3] = ~Duanxuan[numB%10];
}
else if(model == 1)//放行
{
WE[0] = ~Duanxuan[Green_A_T/10];
WE[1] = ~Duanxuan[Green_A_T%10];
WE[2] = ~Duanxuan[Green_B_T/10];
WE[3] = ~Duanxuan[Green_B_T%10];
}
else if (model == 2)//黄
{
WE[0] = ~Duanxuan[Yellow_A_T/10];
WE[1] = ~Duanxuan[Yellow_A_T%10];
WE[2] = ~Duanxuan[Yellow_B_T/10];
WE[3] = ~Duanxuan[Yellow_B_T%10];
}
else if (model == 3)//紧急
{
WE[0] = ~Duanxuan[emergency_t/1000];
WE[1] = ~Duanxuan[emergency_t/100%10];
WE[2] = ~Duanxuan[emergency_t/10%10];
WE[3] = ~Duanxuan[emergency_t%10];
}
else if (model == 4)//黑屏
{
WE[0] = ~Duanxuan[16];
WE[1] = ~Duanxuan[16];
WE[2] = ~Duanxuan[16];
WE[3] = ~Duanxuan[16];
}
}
用定时器进行倒计时 && 黄灯闪烁:
void Service_T0(void) interrupt 1
{
TH0 = (65535-50000) / 256;
TL0 = (65535-50000) % 256;
if(count++ >= 20)
{
if(emergency == 0 && signle == 0 && both == 0 && ((come_a == 1 && come_b == 0) || (come_a == 0 && come_b == 1)) && (LedA_Select%4 ==0 || LedB_Select%4 ==0))
count_change_t++;
if(model == 0)
{
numA--;
numB--;
}
count = 0;
}
//==利用定时 黄灯闪烁
if(LedA_Select%4 == 1 && emerg