AT89C51单片机实现交通灯功能,交通灯使用点阵屏(文章末尾附带源码,注释+仿真图)

本文介绍了一个基于单片机的十字路口交通灯控制器的实现,使用LED二极管模拟交通灯,LED点阵屏显示剩余时间,并通过按键控制运行状态。系统在复位后自动按照预设时间进行红绿灯切换,同时提供了暂停、恢复和复位功能。通过定时器精确控制时间,确保交通灯的准确运行。
摘要由CSDN通过智能技术生成

实现的功能:

  1. 设计一个十字路口交通灯控制器,用LED发光二极管模拟东西南北方向交通灯,用LED点阵显示屏显示两个方向的剩余时间,用按键控制显示状态。时间用定时器准确控制。
  2. 单片机复位后,东西方向绿灯,从6秒倒计时;6秒过后,东西方向黄灯,从3秒倒计时;3秒过后,东西方向红灯,从9秒倒计时。单片机复位后,南北方向红灯,从9秒倒计时;9秒过后,南北方向绿灯,从6秒倒计时。此后按照以上方式循环显示。
  3. 单击K1键,恢复复位后的状态。单击K2键,停止,即LED发光二极管和LED点阵显示屏的状态保持不变。单片机停止后,再单击K3键,继续接着刚才的状态运行。

仿真图

效果图
效果图

效果图

效果图

完整代码(C语言)

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define f1(a) (65536-a)/256
#define f2(a) (65536-a)%256
uchar code table[]={
0xE7,0xEB,0xEF,0xEF,0xEF,0xEF,0xEF,0x83, /*                               */
0xC7,0xB7,0xBB,0xDF,0xEF,0xF7,0xFB,0x83, /*                               */
0xE3,0xDF,0xDF,0xE3,0xDF,0xDF,0xC3,0xFF, /*                               */
0xEF,0xE7,0xEB,0xED,0x81,0xEF,0xEF,0xEF, /*                               */
0xC3,0xFB,0xFB,0xFB,0xC3,0xDF,0xDF,0xC3, /*          红灯9秒              */
0xC3,0xFB,0xFB,0xFB,0xC3,0xDB,0xDB,0xC3, /*                               */
0xC3,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF, /*                               */
0xC1,0xDD,0xDD,0xC1,0xDD,0xDD,0xDD,0xC1, /*                               */
0xC1,0xDD,0xDD,0xC1,0xDF,0xDF,0xDD,0xC1, /*                               */
	
0xE7,0xEB,0xEF,0xEF,0xEF,0xEF,0xEF,0x83, /*                               */
0xC7,0xB7,0xBB,0xDF,0xEF,0xF7,0xFB,0x83, /*          黄灯3秒              */
0xE3,0xDF,0xDF,0xE3,0xDF,0xDF,0xC3,0xFF, /*                               */
	
0xE7,0xEB,0xEF,0xEF,0xEF,0xEF,0xEF,0x83, /*                               */
0xC7,0xB7,0xBB,0xDF,0xEF,0xF7,0xFB,0x83, /*                               */
0xE3,0xDF,0xDF,0xE3,0xDF,0xDF,0xC3,0xFF, /*                               */
0xEF,0xE7,0xEB,0xED,0x81,0xEF,0xEF,0xEF, /*          绿灯6秒              */
0xC3,0xFB,0xFB,0xFB,0xC3,0xDF,0xDF,0xC3, /*                               */
0xC3,0xFB,0xFB,0xFB,0xC3,0xDB,0xDB,0xC3, /*                               */
};
uchar sec=17;
sbit K1=P1^3;   //将P1.3定义为K1
sbit K2=P1^4;   //将P1.4定义为K2
sbit K3=P1^5;   //将P1.5定义为K3
void delay(uint t);
void Init();
void LatticDisplay(uchar num);
void Light(uchar num);
void keyscan();

void delay(uint t)  //延时函数
{
	uchar i;
	while(t--)
	{
		for(i=0;i<120;i++);
	}
}
void Init() //初始化函数
{
	TMOD=0x01; //只是用定时器T0,使用计数功能
	TH0=f1(1000); //高8位初始化
	TL0=f2(1000); //地8位初始化
	//1ms进入一次中断函数
	EA=1;   //中断总开关开启
	ET0=1;	//T0定时器中断开关开启
	TR0=1;  //允许T0定时器工作标志位打开
	
}
void LatticDisplay(uchar num)//点阵屏显示数字函数
{
		uchar i,j;
		for(i=0;i<8;i++)
		{
			P1=i|0xf8; //将P1口的高5位置1
			P0=table[8*num+i]; //显示P0接的点阵屏第i行的亮点情况
			
			if(8*(num-9)+i<0)//求出P2接口点阵屏亮的条件
				j=8*(num+9)+i;
			else             
				j=8*(num-9)+i;
			
			P2=table[j]; //显示P2接的点阵屏幕第i行的亮点情况
			delay(4); //延迟4ms,4*8=32ms<50ms 满足视觉余辉效应
			P0=0xff; //避免出现点阵有残影
			P2=0xff;
		}
}
void Light(uchar num)//交通灯亮的函数
{
	uchar state_E_W,state_S_N;
	if(num>=12&&num<=17)//
		state_E_W=0x04;   //
	if(num>=9&&num<=11) // 东西方向交通灯根据时间亮不同的颜色
		state_E_W=0x02;   //
	if(num>=0&&num<=8)  //
		state_E_W=0x01;   //
	
	if(num>=9&&num<=17) //
		state_S_N=0x08;   //
	if(num>=0&&num<=2)  // 南北方向交通灯根据时间亮不同的颜色
		state_S_N=0x10;   //
	if(num>=3&&num<=8)  //
		state_S_N=0x20;   //
	P3=state_E_W|state_S_N; //东西方向和南北方向交通灯情况互不干扰地写入P3,由P3输出
}
void keyscan()//键盘检测函数
{
	if(K2==0)//判断K2按键是否被按下
	{
		delay(20);//适当延迟,起到消抖作用
		if(K2==0)//再次判断K2是否被按下,这是如果检测到被按下那就是真的被按下了
		{
			TR0=0;//允许T0定时器工作标志位关闭
		}
	}
	
	if(K3==0&&TR0==0)//判断K3是否被按下且允许T0定时器工作标志位关闭
	{
		delay(20);
		if(K3==0&&TR0==0)
		{
		TR0=!TR0;//允许T0定时器工作标志位打开
		}
	}
	
	if(K1==0)//判断K1按键是否被按下
	{
		delay(20);
		if(K1==0)
		{
			Init();//单片机设置初始化
			sec=17;//单片机设置初始化
		}
	}
}
void main()
{
	Init();
	while(1)
	{
		LatticDisplay(sec);
		Light(sec);
		keyscan();
	}
}

void timer0(void) interrupt 1  //定时器T0的中断函数,接口是1
{
	uint k;
	TH0=f1(1000); //高8位初始化
	TL0=f2(1000); //低8位初始化
	//1ms进入一次中断函数
	k++;
	if(k==1000)  //判断是否进入中断函数1000次
	{            //进入中断函数1000次需要1s
		k=0;       //将记录进入中断函数的变量置0
		sec--;     //秒数-1
		if(sec==-1)//判断秒数是否为-1
		{
			sec=17;  //将秒数复位,即17~0为一个周期
		}
	}
	
}

通过网盘分享的文件:TrafficLight.7z
链接: https://pan.baidu.com/s/17Ny31dXfK0MWUPQNIDBPKg?pwd=zzzz
提取码: zzzz

拿走的记得自觉点赞就行, 谢谢大家

  • 6
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值