51单片机学习之模拟路口红绿灯
1 所需设备
- 51单片机
其中P1口控制了8个led
灯的显示,高电平灯灭,低电平灯亮。 - LCD灯(引脚图)
LCD1602
显示屏
控制方式与8段数码管类似,使用了2个74HC573
芯片实现段、位选择的相关控制(此处使用了该博主的封装的控制程序)
2 效果展示
说明:
- 8 个
LED
,使用左边三个–模拟路口1的交通灯;使用右边三个–模拟路口2的交通灯 LCD1602
显示器第一行显示路口1的倒计时情况;第二行显示路口2的倒计时情况- 实现了以下功能:
- 两边红灯绿灯亮 10 秒,在第七秒时 实现闪烁
- 黄灯时间 3 秒
3 代码
主要分为以下几个模块:延时控制、LED控制、LCD1602控制
3.1 延时控制
// 延时程序 单位 ms
void Delay(unsigned int times) //@12.000MHz
{
unsigned char i, j;
while (times) {
i = 2;
j = 239;
do {
while (--j)
;
} while (--i);
times--;
}
}
3.2 LCD灯控制
#include <REGX52.H>
// 初始化led状态
void InitLight()
{
P1 = 0xff;
}
// 控制两个路口的红绿黄三色灯
void LightCtrRed()
{
P1 = 0x7e;
}
void LightCtrYellow()
{
P1 = 0xbd;
}
void LightCtrGreen()
{
P1 = 0xde;
}
3.3 main.c
lcd1602
的计时器显示,使用了封装好的控制方法,便捷实现需求。
#include <regx52.h>
#include "Delay.h"
#include "LCD1602.h"
#include "LightCrt.h"
typedef unsigned char uchar;
typedef unsigned int uint;
// 控制数码管的段位选择器
sbit DU = P2 ^ 6;
sbit WE = P2 ^ 7;
void main()
{
// 变量定义
uchar str1[] = {"Road1:"};
uchar str2[] = {"Road2:"};
uint i = 1;
uint flage = 1; // 转换标志 0-road1 1-road2
// 关闭段位选择器 停止数码管显示
DU = 0;
WE = 0;
// 初始化lcd1602
LCD_Init();
LCD_ShowString(1, 1, str1);
LCD_ShowString(2, 1, str2);
while (1) {
// 绿灯 倒计时
LightCtrGreen();
for (i = 0; i <= 10; i++) {
if (i > 7) {
LightCtrGreen();
Delay(500);
InitLight();
Delay(500);
LightCtrGreen();
LCD_ShowNum(1, 7, i, 2);
LCD_ShowNum(2, 7, i, 2);
} else {
Delay(1000);
LCD_ShowNum(1, 7, i, 2);
LCD_ShowNum(2, 7, i, 2);
}
}
InitLight();
// 黄灯 倒计时
LightCtrYellow();
for (i = 0; i <= 3; i++) {
Delay(1000);
LCD_ShowNum(1, 7, i, 2);
LCD_ShowNum(2, 7, i, 2);
}
InitLight();
// 红灯 倒计时
LightCtrRed();
for (i = 0; i <= 10; i++) {
if (i > 7) {
LightCtrRed();
Delay(500);
InitLight();
Delay(500);
LightCtrRed();
LCD_ShowNum(1, 7, i, 2);
LCD_ShowNum(2, 7, i, 2);
}else{
Delay(1000);
LCD_ShowNum(1, 7, i, 2);
LCD_ShowNum(2, 7, i, 2);
}
}
InitLight();
}
}