如需要源文件可以添加qq群聊获取:662177587
文章目录
概要
实际设计图
设计内容
本课题对基于单片机的交通灯控制系统进行设计。以单片机为控制核心,设计并制作交通灯控制系统,用于十字路口的车辆及行人的交通管理。东西南北四个路口通行指示灯,并分别用计时器显示路口通行转换剩余时间, 在特种车辆如110、120通过路口时,系统可自动转为特种车辆放行,其他车辆禁止通行状态。模拟交通信号灯的交替变换;最大限度的提高交通的顺畅交替运行;系统硬件设计与实现;节省能源消耗。
(1) 设计交通灯状态的管理方案;
(2) 设计单片机的最小系统和周边电路;
(3) 设计整个系统的电路分布和接线;
(4) 使用C语言编写整个系统运行的程序。
研究目标
设计一个基于单片机的十字路口交通灯控制电路,要求南北方向和东西方向两个交叉路口的车辆交替运行,车流量大,通行时间长,车流量小,通行时间短。每次绿灯变红灯时,要求黄灯先亮5S,才能变换运行车辆。东西方向、南北方向车道除了有红、黄、绿灯指示外,每一种灯亮的时间都用数码管显示器进行显示(采用倒计时的方法)。考虑到特殊车辆情况,设置紧急转换开关。
整体架构流程
首先我们应知道实际的十字路口灯的运转情况,在十字路口观察可以发现,主要由红黄绿三种颜色构成,在绿灯向红灯切换时会有一小部分的黄灯警告阶段,而红灯向绿灯转换时并没有。
由此我们可以使用一个状态机,分别表示红绿灯在一个循环内的所有情况。
如图上图所示,设初始状态为0态,此时南北为绿灯,东西为红灯;1态为绿灯向红灯过渡的黄灯态;2态时东西为绿灯,南北为红灯;3态时东西为黄灯,南北依然是红灯,接着进入下一循环。
因此只要设定红灯的时间time和黄灯过渡的时间yellow即可,count是一个1秒自动加一的变量。通过该变量则可以判断出当前处于哪一状态,当count=time*2时,进入下一循环。
倒计时和状态的计算如下所示:
0-判断:count<time-yellow,
南倒计时=time-yellow-count,
东倒计时=time-count
1-判断:time-yellow<count<time,
南倒计时=yellow-(count-(time-yellow)),
东倒计时=time-count
2-判断:time<count<time*2-yellow,
南倒计时=time-(count-time)
东倒计时=(time-yellow)-(count-time)
3-判断:time*2-yellow<count<time*2
南倒计时=time-(count-time)
东倒计时=yellow-(count-time-(time-yellow))
Count=2*time则清零
技术细节
具体的细节可以参照下面的代码:
- main函数
#include <STC89C5xRC.H>
#include "Timer0.h"
#include "Nexie.h"
unsigned char short_time = 20; //³µÁ÷Á¿Ð¡Ê±¼ä
unsigned char long_time = 35; //³µÁ÷Á¿´óʱ¼ä
unsigned char yellow = 3; //»ÆµÆʱ¼äӦСÓÚÕý³£Ê±¼ä
unsigned char run_flag = 0;
unsigned char h_time,v_time;//ˮƽºÍ´¹Ö±·½Ïòµ¹¼ÆʱÏÔʾ±äÁ¿
bit spec_flag=0;//ÓÐÎÞÌØÖÖ³µ±ê־λÓÐΪ1£¬ÎÞΪ0
bit liul_flag=0;//³µÁ÷Á¿±ê־λСΪ0£¬´óΪ1
unsigned int count=0; //¶¨Ê±Æ÷×ܼÆʱʱ¼ä
unsigned char time; //´æ´¢ÕæʵʹÓõÄÊÇlong»¹ÊÇshortʱ¼ä
/**
* @brief ÑÕÉ«Åжϼ°ÏÔʾ
* @param ÎÞ
* @retval ÎÞ
*/
void led_color(void)
{
if(spec_flag==0)//ÏÈÈ·¶¨²»ÊÇÔÚÌØÖÖ³µÇé¿öÏÂ,·Ö0-3ÖÖÇé¿öÌÖÂÛ
{
switch(run_flag)
{
case 0:
P10=0;P11=0;P12=1;
P13=1;P14=0;P15=0;break;
case 1:
P10=0;P11=1;P12=0;
P13=1;P14=0;P15=0;break;
case 2:
P10=1;P11=0;P12=0;
P13=0;P14=0;P15=1;break;
case 3:
P10=1;P11=0;P12=0;
P13=0;P14=1;P15=0;break;
}
}
else //ÌØÖÖ³µÇé¿öÈ«²¿ÁÁºìµÆ
{
P10=1;P11=0;P12=0;
P15=0;P14=0;P13=1;
}
}
/**
* @brief °´¼üɨÃè
* @param ÎÞ
* @retval ÎÞ
*/
void Key_Loop()
{
if(P30==0) //ÌØÖÖ³µ°´¼ü°´ÏÂÖñê־λspec_flag
{
spec_flag=1;
}
else
{
spec_flag=0;//·ñÔòspec_flagÇåÁã
}
if(P31==0)
{
liul_flag=1;//³µÁ÷Á¿´ó°´¼ü°´ÏÂÖñê־λliul_flag
time=long_time;
}
else
{
liul_flag=0;//·ñÔòliul_flagÇåÁã
time=short_time;
}
}
/**
* @brief ÊýÂë¹ÜÊý×ÖÏÔʾ
* @param ÎÞ
* @retval ÎÞ
*/
void num_show()
{
if(spec_flag==0) //ÏÈÈ·¶¨²»ÊÇÔÚÌØÖÖ³µÇé¿öÏÂÏÔʾµ¹¼Æʱ
{
Nixie_SetBuf(1,v_time/10%10);
Nixie_SetBuf(2,v_time%10);
Nixie_SetBuf(3,h_time/10%10);
Nixie_SetBuf(4,h_time%10);
}
else //ÊÇÔÚÌØÖÖ³µÇé¿öÏ£¬µ¹¼ÆʱÏÔʾ¡°--¡±
{
Nixie_SetBuf(1,10);
Nixie_SetBuf(2,10);
Nixie_SetBuf(3,10);
Nixie_SetBuf(4,10);
}
}
void main()
{
Timer0_Init(); //¶¨Ê±Æ÷0³õʼ»¯
while(1)
{
num_show(); //Ñ»·É¨Ãè
led_color();
}
}
/**
* @brief ¶¨Ê±Æ÷0µÄÏà¹Ø²Ù×÷
* @brief ¶¨Ê±Æ÷0Ϊģʽ1,16Ϊ²»×Ô¶¯ÖØÔØ,1msÖжÏ
* @param ÎÞ
* @retval ÎÞ
*/
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count0,T0Count1,T0Count2;//¶¨Ê±Æ÷Ïà¹Ø±äÁ¿
TL0 = 0x18; //ÉèÖö¨Ê±³õʼֵ
TH0 = 0xFC; //ÉèÖö¨Ê±³õʼֵ
T0Count0++;T0Count1++;T0Count2++;//ÿ1ms½øÐÐÒ»´Î++£»
if(T0Count0>=10)//10msµ÷ÓÃÒ»´ÎKey_Loop()º¯Êý
{
T0Count0=0;
Key_Loop();
}
if(T0Count1>=2)//2msµ÷ÓÃÒ»´ÎNixie_Loop()º¯Êý
{
T0Count1=0;
Nixie_Loop();
}
if(T0Count2>=1000)//1Ãë½øÈëÒ»´Î
{
T0Count2=0;
if(spec_flag==0)//Èç¹û²»ÊÇÌØÊâÇé¿öÔò¿ªÆô¼ÆÊý
{
count++;
if(count==2*time)
{count=0;run_flag=0;}
if(count<=time-yellow)
{
run_flag=0;//ÅжÏΪ״̬0
v_time=time-yellow-count;
h_time=time-count;
}
else if(time-yellow<count && count<=time)
{
run_flag=1;//ÅжÏΪ״̬1
v_time=yellow-(count-(time-yellow));
h_time=time-count;
}
else if(time<count && count<=time*2-yellow)
{
run_flag=2;//ÅжÏΪ״̬2
v_time=time-(count-time);
h_time=(time-yellow)-(count-time);
}
else if(time*2-yellow<count && count<time*2)
{
run_flag=3;//ÅжÏΪ״̬3
v_time=time-(count-time);
h_time=yellow-(count-time-(time-yellow));
}
}
}
}
- 定时器初始化.c
#include <STC89C5xRC.H>
/**
* @brief ¶¨Ê±Æ÷³õʼ»¯
* @param ÎÞ
* @retval ÎÞ
*/
void Timer0_Init(void) //100us@12.000MHz
{
TMOD &= 0xF0; //¶¨Ê±Æ÷ʱÖÓ12Tģʽ
TMOD |= 0x01; //ÉèÖö¨Ê±Æ÷ģʽ
TL0 = 0x18; //ÉèÖö¨Ê±³õʼֵ
TH0 = 0xFC; //ÉèÖö¨Ê±³õʼֵ
TF0 = 0; //Çå³ýTF0±êÖ¾
TR0 = 1; //¶¨Ê±Æ÷0¿ªÊ¼¼Æʱ
ET0=1;
EA=1;
PT0=0;
}
- 定时器初始化.h
#ifndef __TIMER0_H__
#define __TIMER0_H__
void Timer0_Init(void);
#endif
- 数码管.c
#include <STC89C5xRC.H>
#include "Delay.h"
unsigned char Nixie_Buf[11]={0,10,10,10,10};//0ÊÇΪÁËÕÕÓ¦loopÖÐi=1
unsigned char NixieNumb[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};
/**
* @brief Íⲿµ÷ÓöÔÊý×éNixie_Buf[4]¸³Öµ
* @brief ʹµÃloopº¯ÊýÑ»·¶Ôscanº¯Êý¸³ÖµÊ±¶Áµ½ÏàÓ¦Êý¾Ý
* @brief δ¸³ÖµµÄÊý×éλ¼´Îª10£»¶ÔÓ¦NixieNumb[]ÖеÄ0£»
* @param Table,NumberÔÚNixie_BufÊý×éµÄÏÂ±ê ¸³µÄÖµ£¨¸ÃÖµ¼´¶ÔÓ¦NixieNumb[]ÖеÄÖµ£©
* @retval ÎÞ
*/
void Nixie_SetBuf(unsigned char Table,Number)
{
Nixie_Buf[Table]=Number;
}
/**
* @brief ÊýÂë¹ÜÏÔʾ
* @param Table,NumberÏÔʾµÄλÖà ÏÔʾµÄÊý×Ö
* @param Á½²ÎÊýÓɶ¨Ê±Æ÷°´ÖÜÆÚɨÃèʱ¸ø¶¨
* @retval ÎÞ
*/
void Nixie_Scan(unsigned char Table,Number)
{
P0=0x00;//ÏûÒþ
switch(Table)
{// P2_4=C-4,P2_3=B-2;P2_2=A-1
case 1:P24=1;P23=1;P22=1;break;
case 2:P24=1;P23=1;P22=0;break;
case 3:P24=1;P23=0;P22=1;break;
case 4:P24=1;P23=0;P22=0;break;
}
P0=NixieNumb[Number];//²»ÓÃdelayÔÙÏûÒþ£¬ÒòΪ¶¨Ê±Æ÷½øÀ´ÓÐʱ¼ä¼ä¸ô
}
/**
* @brief ¶¨Ê±Æ÷µ÷Óõĺ¯Êý
* @param ÎÞ
* @retval ÎÞ
*/
void Nixie_Loop(void)//¶¨Ê±Æ÷ÿ½øÒ»´Î¾Íµ÷ÓÃÒ»´Îscanº¯Êý
{ //ʹµÃ3¸öÊýÂë¹ÜÒÀ´Î¿ìËÙÏÔʾ
static unsigned char i=1;
Nixie_Scan(i,Nixie_Buf[i]);
i++;
if(i>=5)i=1;
}
- 数码管.h
#ifndef __NEXIE_H__
#define __NEXIE_H__
void Nixie_Scan(unsigned char Table,Number);
void Nixie_Loop(void);
void Nixie_SetBuf(unsigned char Table,Number);
#endif
小结
本课题对基于单片机的交通灯控制系统进行设计。以单片机为控制核心,设计并制作交通灯控制系统,用于十字路口的车辆及行人的交通管理。
如需要源文件可以添加qq群聊获取:662177587
希望对你有所帮助!
标签:10,小课,void,51,unsigned,Nixie,单片机,flag,time From: https://blog.csdn.net/qq_61688416/article/details/136813837