基于51单片机的红绿灯控制电路设计详解

        单片机P1口控制数码管段选,P2口控制数码管位选,P0口控制两边的灯光。

void SMG_shift()
{
	P2=~(0x01<<shift);
	switch(shift)
	{
		case 0:bits=second1/10; break;
		case 1:bits=second1%10; break;
		case 2:bits=second2/10; break;
		case 3:bits=second2%10; break;
	}
	P1=smg[bits];
	shift=(shift+1)%4;
}

        首先是数码管控制函数,声明一个变量shift作为数码管位移量,首先进行位选,这里数码管使用的是共阴极数码管,所以位选脚为低时点亮,因为位移时除了置1的位保持1,其他的位都会变成0(例如0x01<<1是0x02,0xfe<<1是0x0xfc),为了避免位移时会点亮其他数码管,这里对0x01位移后进行取反,switch语句对变量bits赋值,结合数码管段码表达到第一位显示计时器一的十位,第二位显示计时器二并以此类推的效果。

void timer()
{

	if(second<=60 && second>33)								//左绿灯右红灯
	{		
		status1=1;
		status2=3;
		second1=second-33;									//左边倒计时为second-33
		second2=second-30;
	}
	if(second<=33 && second>30)								//左黄灯右红灯
	{
		status1=2;
		status2=3;											//此时左右倒计时相等
		second2=second-30;
		second1=second2;
	}
	if(second<=30 && second>3)								//左红灯右绿灯
	{
		status1=3;
		status2=1;
		second1=second;										//左倒计时等于second
		second2=second-3;									//右倒计时比左倒计时少3秒
	}
	if(second<=3 && second>=0)								//左红灯右黄灯
	{
		status1=3;
		status2=2;
		second1=second;
		second2=second;
	}
	second--;												
	if(second==0)
		second=60;
}

        倒计时的效果用变量second实现,将一个红绿灯周期设定为60秒,则在60秒中需要实现左绿右红,左黄右红,左红右绿,左红右黄的循环,黄灯占用3秒,绿灯27秒,红灯30秒,在倒计时函数中分别对计时器一二进行赋值,显示当前灯的剩余时间,对status赋值控制灯的变化。

void Light_Ctrl()											//红绿灯控制
{
	switch(status1)
	{
		case 1: P0 |= 0x07; P0 &= 0xfe; break;
		case 2: P0 |= 0x07; P0 &= 0xfd; break;
		case 3: P0 |= 0x07; P0 &= 0xfb; break;
	}
	switch(status2)
	{
		case 1: P0 |= 0x38; P0 &= 0xf7; break;
		case 2: P0 |= 0x38; P0 &= 0xef; break;
		case 3: P0 |= 0x38; P0 &= 0xdf; break;
	}
}

        灯光控制函数利用上一个函数对status的赋值控制P0口输出,在灯光变化之前先对之前的状态用|=置1,再用&=置0(这里的灯光是低电平点亮),否则在变灯的时候会出现三个灯同时亮的情况。

void main()
{
	Timer0Init();
	P1=0xff;
	P0=0xff;
	second1=27;
	second2=30;
	while(1);
}

        主函数包含了定时器0、P0P1口和计时器变量的初始化,while(1)死循环避免main函数循环运行。

void timer0ISP () interrupt 1   							//定时器0中断服务函数
{
    TH0=(65536-1000)/256;  									//1ms一次脉冲
	TL0=(65536-1000)%256;
	Light_Ctrl();
	i++;
	SMG_shift();
	if(i>=1000)
	{
		i=0;
		timer();
	}
}

        定时器0中断服务程序包含灯光控制及数码管刷新函数,1秒运行一次倒计时函数。

        全部代码

#include <REG51.H>
#define uint unsigned int
#define uchar unsigned char
	
uint second1,second2,i,bits,status1,status2,shift;
uint second=60;
uchar smg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

void Timer0Init()
{
	TMOD=0x01;												//工作模式1 ,需赋初值
	TH0=(65536-1000)/256; 									//定时1000,高八位
	TL0=(65536-1000)%256;
	EA=1;													//打开中断允许总开关
	ET0=1;													//定时器0中断允许
	TR0=1;													//定时器0启动控制
}

void SMG_shift()
{
	P2=~(0x01<<shift);
	switch(shift)
	{
		case 0:bits=second1/10; break;
		case 1:bits=second1%10; break;
		case 2:bits=second2/10; break;
		case 3:bits=second2%10; break;
	}
	P1=smg[bits];
	shift=(shift+1)%4;
}

void timer()
{

	if(second<=60 && second>33)								//左绿灯右红灯
	{		
		status1=1;
		status2=3;
		second1=second-33;									//左边倒计时为second-33
		second2=second-30;
	}
	if(second<=33 && second>30)								//左黄灯右红灯
	{
		status1=2;
		status2=3;											//此时左右倒计时相等
		second2=second-30;
		second1=second2;
	}
	if(second<=30 && second>3)								//左红灯右绿灯
	{
		status1=3;
		status2=1;
		second1=second;										//左倒计时等于second
		second2=second-3;									//右倒计时比左倒计时少3秒
	}
	if(second<=3 && second>=0)								//左红灯右黄灯
	{
		status1=3;
		status2=2;
		second1=second;
		second2=second;
	}
	second--;												//每运行一次该函数减一秒
	if(second==0)
		second=60;
}


void Light_Ctrl()											//红绿灯控制
{
	switch(status1)
	{
		case 1: P0 |= 0x07; P0 &= 0xfe; break;
		case 2: P0 |= 0x07; P0 &= 0xfd; break;
		case 3: P0 |= 0x07; P0 &= 0xfb; break;
	}
	switch(status2)
	{
		case 1: P0 |= 0x38; P0 &= 0xf7; break;
		case 2: P0 |= 0x38; P0 &= 0xef; break;
		case 3: P0 |= 0x38; P0 &= 0xdf; break;
	}
}

void main()
{
	
	Timer0Init();
	P1=0xff;
	P0=0xff;
	second1=27;
	second2=30;
	while(1);
}

void timer0ISP () interrupt 1   							//定时器0中断服务函数
{
    TH0=(65536-1000)/256;  									//1ms一次脉冲
	TL0=(65536-1000)%256;
	Light_Ctrl();
	i++;
	SMG_shift();
	if(i>=1000)
	{
		i=0;
		timer();
	}
}

        仿真电路图

 

物联沃分享整理
物联沃-IOTWORD物联网 » 基于51单片机的红绿灯控制电路设计详解

发表评论