资讯详情

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

实现功能:

  1. 十字路口交通灯控制器的设计LED发光二极管模拟东、西、方向的交通灯LED点阵显示屏显示两个方向的剩余时间,用按钮控制显示状态。时间由定时器准确控制。
  2. 单片机复位后,东西方向的绿灯从6秒倒计时;6秒后,东西方向的黄灯从3秒倒计时;3秒后,东西方向的红灯从9秒倒计时。单片机复位后,南北方向的红灯从9秒倒计时;9秒后,南北方向的绿灯从6秒倒计时。然后以上述方式循环显示。
  3. 单击K1键,恢复位置后的状态。K二键,停止,即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为一个周期
		}
	}
	
}

标签: 二极管n052at23

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台