栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

使用51单片机以及数码管来显示十字路口红绿灯

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用51单片机以及数码管来显示十字路口红绿灯

最近老师让我们使用51单片机做一个十字路口红绿灯实验,正好发表一篇文章,希望能给有需要的同学们带来一些帮助,如果有不合理的地方,还请大家帮忙指正。

一. 首先要利用51做一个红绿灯我们需要知道这个红绿灯有哪些要求,下面是题目要求:

1.实验硬件:红绿黄三种颜色的LED灯每种两个,杜邦线若干,面包板一个,51单片机开发板一个。

2.实验要求:做一个十字路口红绿灯,每一向各一个,红绿灯要求能够按照通行的要求来亮灯。南北向红绿灯,红灯亮60秒,东西向的红绿灯亮,红灯亮30秒。

3.要求用LED灯和定时器中断来完成。

二.下面说一下我所用的单片机以及其图片:

我所用的是STC89C52系列的51单片机,这个是学习版的,在淘宝和京东上都能搜到,大部分初学者都是学的这个型号的51单片机。

我本来是想直接用这个板子上的数码管和它右边mo的LED模块来做这个实验,但是数码管控制的引脚和这个LED模块是冲突的,两个共用一个引脚,所以不能同时使用。

        数码管需要用到P0和P2的引脚,而这个LED模块就是用的P2的8个引脚控制。

三.程序部分

1.头文件以及子程序的说明

/

void time0_init(void)
{
	TMOD|=0x01;//选择为定时器0模式,工作方式1
	TH0=0xFC;	//给定时器赋初值,定时1ms
	TL0=0x18;	
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	TR0=1;//打开定时器		
}


extern int ss=90;

void time0() interrupt 1 //定时器0中断函数
{
	static u16 i;//定义静态变量i
	TH0=0xFC;	//给定时器赋初值,定时1ms
	TL0=0x18;
	i++;
	if(i==1000)
	{
		i=0;
		ss--;
	}						
}

这个定时器中断配置的是每一毫秒溢出一次,也就是说每一毫秒进入一次中断,而中断服务函数里面的SS--就会每一秒钟进行一次,也就是说SS每一秒钟会减一,这样也是为了符合红绿灯的读数显示,我们都知道红绿灯是倒计时显示的。

2.主程序的代码以及相关说明

//对红绿灯的引脚定义
sbit NBred=P1^0;//南北方向红绿黄灯引脚定义
sbit NBgreen=P1^1;
sbit NByellow=P1^2;

sbit DXred=P1^5;//东西方向红绿黄灯引脚定义
sbit DXgreen=P1^6;
sbit DXyellow=P1^7;
//**********************************************
//*************************************************数码管段码表
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

void Nixie(unsigned char Location,Number)//数码管显示子函数
{
	switch(Location)		//位码输出
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];	//段码输出
	Delay(1);				//显示一段时间
	P0=0x00;				//段码清0,消影
}
//**************************************
//**************************主函数变量定义
extern int ss;
int a=0,b=0,sign=0,cc=0;
//**************************
//********************主函数部分,使用定时器0中断计时,中断函数在interrupt文件中
void main()
{
   time0_init();
	while(1)
	{
		
		if(ss==0)
		{
			sign=0;
			ss=90;//如果等于ss=0,让ss=90,重置ss的时间周期
		}
		
		//这些标志位的处理,主要是为了倒计时的正常显示
		if(ss==90) {sign=1;}
		if(sign==1){cc=ss-30;}
		if(cc==0)  {sign=2;}
		if(sign==2) {cc=ss;}
		
		if(ss==90)//开始让南北的红灯亮,东西的绿灯亮
		{
			NBred=0;//南北的红绿灯亮灭控制
			NBgreen=1;
			NByellow=1;
			
			DXred=1;//东西的红绿黄灯亮灭控制
			DXgreen=0;				
		}
		if(ss==30)//让南北的绿灯亮,东西的红灯亮
		{
			NBred=1;
			NBgreen=0;
				
			DXred=0;
			DXgreen=1;
			DXyellow=1;	
		}
		if(ss==33)//控制东北黄灯的亮,绿灯灭
		{
			DXyellow=0;	
			 DXgreen=1;
		}
		
		if(ss<=3&ss>=0)//控制南北黄灯的灭,绿灯灭
		{
			NByellow=0;	
			NBgreen=1;
		}
		
		
		a=cc%10;//个位
		b=cc/10;//十位
		Nixie(1,b);		//在数码管的第1位置显示十位b
		Nixie(2,a);		//在数码管的第2位置显示个位a
		
	}
}

主程序大体的思路:

        这里我是直接把SS的初值给90,因为南北和东西两向的灯的红绿灯时间不一样,一个是红灯60秒,一个是红灯30秒,所以说两个红绿灯的总周期是90秒,把SS设为90,来做总周期的计时。但是红绿灯的倒计时不能显示总周期,而是分成两段的。所以我设了一个CC来进行外部实际的倒计时显示。可能有同学不理解为什么要这样设,我在这里简单说明一下,拿南北方向红绿灯来说,我设计的是南北方向先进入红灯,那么南北方向红绿灯就会有一个60秒的红灯倒计时。倒计时结束后,南北方向是红绿灯就会进入30秒的绿灯,而东西方向的红绿灯正好相反。至于黄灯单独拿出来处理即可。

        而数码管显示的时候要注意把倒计时数字,拆成个位和十位然后进行动态显示即可。

        这里还要说的一点是,如果是用仿真的话,根据电路的不同,程序也是不一样的,但是设计的思路是类似的,大家要灵活变通

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/846891.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号