Proteus仿真:STM32单片机交通灯控制系统设计详解

文章目录

  • 一、功能简介
  • 二、软件设计
  • 三、实验现象
  • 联系作者

  • 一、功能简介

    本项目使用Proteus8仿真STM32单片机控制器,使用数码管、按键、交通信号灯模块等。

    系统运行后,交通灯系统开始运行,数码管显示初始时间,默认南北绿灯5S,东西红灯8S,绿灯过后南北黄灯3秒;然后切换东西绿灯5S,南北红灯8S,绿灯过后南北黄灯3秒;如此循环。
    可使用K1键进入红绿灯时间设置,K2和K3进行加减调节,设定好后,K4键确定并继续运行。在运行过程中,可通过K2键禁止通行,此时东南西北方向红灯亮,K3键允许南北通行,此时南北绿灯亮,东西红灯亮。
    K4键允许东西通行,此时南北红灯亮,东西绿灯亮。此时可按下K1键返回
    交通灯自动控制模式运行。
    主要功能如下:
    1、东西南北红黄绿灯控制
    2、交通灯时间设置
    3、数码管显示
    4、突发状况交通灯控制


    二、软件设计

    /*
    作者:嗨小易(QQ:3443792007)
    */
    
    
    
    /*******************************************************************************
    * 函 数 名         : TIM2_IRQHandler
    * 函数功能		   : TIM2中断函数
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    void TIM2_IRQHandler(void)
    {
    	static u8 i=0;
    	
    	if(TIM_GetITStatus(TIM2,TIM_IT_Update))
    	{
    		i++;
    		if(i>=100)//间隔1S
    		{
    			i=0;
    			sys_ctrl.sec++;
    			if(sys_ctrl.led_sta==0)//南北绿灯,东西红灯时间
    			{
    				sys_ctrl.nbled_time=sys_ctrl.gled_time-sys_ctrl.sec;
    				sys_ctrl.dxled_time=sys_ctrl.rled_time-sys_ctrl.sec;
    				//LED灯
    				NB_GLED=1;NB_YLED=0;NB_RLED=0;
    				DX_GLED=0;DX_YLED=0;DX_RLED=1;
    				if(sys_ctrl.sec>=sys_ctrl.gled_time)
    				{
    					sys_ctrl.sec=0;
    					sys_ctrl.led_sta=1;
    					sys_ctrl.nbled_time=YLED_TIME-sys_ctrl.sec;
    					sys_ctrl.dxled_time=YLED_TIME-sys_ctrl.sec;
    					//LED灯
    					NB_GLED=0;NB_YLED=1;NB_RLED=0;
    					DX_GLED=0;DX_YLED=0;DX_RLED=1;
    				}	
    			}
    			else if(sys_ctrl.led_sta==1)//南北黄灯,东西红灯时间
    			{
    				sys_ctrl.nbled_time=YLED_TIME-sys_ctrl.sec;
    				sys_ctrl.dxled_time=YLED_TIME-sys_ctrl.sec;	
    				if(sys_ctrl.sec>=YLED_TIME)
    				{
    					sys_ctrl.sec=0;
    					sys_ctrl.led_sta=2;
    					sys_ctrl.nbled_time=sys_ctrl.rled_time-sys_ctrl.sec;
    					sys_ctrl.dxled_time=sys_ctrl.gled_time-sys_ctrl.sec;
    					//LED灯
    					NB_GLED=0;NB_YLED=0;NB_RLED=1;
    					DX_GLED=1;DX_YLED=0;DX_RLED=0;
    				}	
    			}
    			else if(sys_ctrl.led_sta==2)//南北红灯,东西绿灯时间
    			{
    				sys_ctrl.nbled_time=sys_ctrl.rled_time-sys_ctrl.sec;
    				sys_ctrl.dxled_time=sys_ctrl.gled_time-sys_ctrl.sec;
    				if(sys_ctrl.sec>=sys_ctrl.gled_time)
    				{
    					sys_ctrl.sec=0;
    					sys_ctrl.led_sta=3;
    					sys_ctrl.nbled_time=YLED_TIME-sys_ctrl.sec;
    					sys_ctrl.dxled_time=YLED_TIME-sys_ctrl.sec;
    					//LED灯
    					NB_GLED=0;NB_YLED=0;NB_RLED=1;
    					DX_GLED=0;DX_YLED=1;DX_RLED=0;
    				}	
    			}
    			else if(sys_ctrl.led_sta==3)//南北红灯,东西黄灯时间
    			{
    				sys_ctrl.nbled_time=YLED_TIME-sys_ctrl.sec;
    				sys_ctrl.dxled_time=YLED_TIME-sys_ctrl.sec;
    				if(sys_ctrl.sec>=YLED_TIME)
    				{
    					sys_ctrl.sec=0;
    					sys_ctrl.led_sta=0;
    					sys_ctrl.nbled_time=sys_ctrl.gled_time-sys_ctrl.sec;
    					sys_ctrl.dxled_time=sys_ctrl.rled_time-sys_ctrl.sec;
    					//LED灯
    					NB_GLED=1;NB_YLED=0;NB_RLED=0;
    					DX_GLED=0;DX_YLED=0;DX_RLED=1;
    				}	
    			}
    		}
    	}
    	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);	
    }
    
    
    //系统数据显示
    void sys_data_show(void)
    {
    	u8 buf[8];
    
    	//正常显示
    	while(sys_ctrl.mode==0)
    	{
    		buf[0]=gsmg_code[sys_ctrl.nbled_time/10];
    		buf[1]=gsmg_code[sys_ctrl.nbled_time%10];
    		buf[2]=gsmg_code[sys_ctrl.nbled_time/10];
    		buf[3]=gsmg_code[sys_ctrl.nbled_time%10];
    		buf[4]=gsmg_code[sys_ctrl.dxled_time/10];
    		buf[5]=gsmg_code[sys_ctrl.dxled_time%10];
    		buf[6]=gsmg_code[sys_ctrl.dxled_time/10];
    		buf[7]=gsmg_code[sys_ctrl.dxled_time%10];
    		smg_display(buf,1);
    		break;	
    	}
    	//时间设置模式显示
    	while(sys_ctrl.mode==1)
    	{
    		buf[0]=gsmg_code[sys_ctrl.gled_time/10];
    		buf[1]=gsmg_code[sys_ctrl.gled_time%10];
    		buf[2]=gsmg_code[sys_ctrl.gled_time/10];
    		buf[3]=gsmg_code[sys_ctrl.gled_time%10];
    		buf[4]=gsmg_code[sys_ctrl.rled_time/10];
    		buf[5]=gsmg_code[sys_ctrl.rled_time%10];
    		buf[6]=gsmg_code[sys_ctrl.rled_time/10];
    		buf[7]=gsmg_code[sys_ctrl.rled_time%10];
    		smg_display(buf,1);
    		break;
    	}
    	//禁止通行显示、//南北通行显示、//东西通行显示
    	while(sys_ctrl.mode==2 || sys_ctrl.mode==3 || sys_ctrl.mode==4)
    	{
    		buf[0]=0x40;
    		buf[1]=0x40;
    		buf[2]=0x40;
    		buf[3]=0x40;
    		buf[4]=0x40;
    		buf[5]=0x40;
    		buf[6]=0x40;
    		buf[7]=0x40;
    		smg_display(buf,1);
    		break;	
    	}
    }
    
    //系统数据设置
    void sys_data_set(void)
    {
    	u8 key=0;
    	key=KEY_Scan(0);
    	if(sys_ctrl.mode==0)
    	{
    		//时间设置
    		if(key==KEY1_PRESS)
    		{
    			sys_ctrl.mode=1;
    			TIM_Cmd(TIM2,DISABLE);//关闭定时器
    		}	
    	}
    	//非时间设置模式
    	if(sys_ctrl.mode!=1)
    	{
    		if(key==KEY1_PRESS)
    		{
    			sys_ctrl.mode=0;
    			TIM_Cmd(TIM2,ENABLE);//打开定时器	
    		}
    		//禁止通行
    		else if(key==KEY2_PRESS)
    		{
    			sys_ctrl.mode=2;
    			TIM_Cmd(TIM2,DISABLE);//关闭定时器
    			//LED灯
    			NB_GLED=0;NB_YLED=0;NB_RLED=1;
    			DX_GLED=0;DX_YLED=0;DX_RLED=1;
    		}
    		//南北通行
    		else if(key==KEY3_PRESS)
    		{
    			sys_ctrl.mode=3;
    			TIM_Cmd(TIM2,DISABLE);//关闭定时器
    			//LED灯
    			NB_GLED=1;NB_YLED=0;NB_RLED=0;
    			DX_GLED=0;DX_YLED=0;DX_RLED=1;
    		}
    		//东西通行
    		else if(key==KEY4_PRESS)
    		{
    			sys_ctrl.mode=4;
    			TIM_Cmd(TIM2,DISABLE);//关闭定时器
    			//LED灯
    			NB_GLED=0;NB_YLED=0;NB_RLED=1;
    			DX_GLED=1;DX_YLED=0;DX_RLED=0;
    		}	
    	}
    	//时间设置模式
    	if(sys_ctrl.mode==1)
    	{
    		if(key==KEY2_PRESS)//加
    		{
    			sys_ctrl.gled_time++;
    			if(sys_ctrl.gled_time>90)sys_ctrl.gled_time=0;
    			sys_ctrl.rled_time=sys_ctrl.gled_time+YLED_TIME;		
    		}
    		else if(key==KEY3_PRESS)//减
    		{
    			sys_ctrl.gled_time--;
    			if(sys_ctrl.gled_time<0)sys_ctrl.gled_time=90;
    			sys_ctrl.rled_time=sys_ctrl.gled_time+YLED_TIME;	
    		}
    		else if(key==KEY4_PRESS)//确定
    		{
    			sys_ctrl.mode=0;
    			TIM_Cmd(TIM2,ENABLE);//打开定时器		
    		}		
    	}
    }
    
    
    //应用控制系统
    void appdemo_show(void)
    {
    	LED_Init();
    	KEY_Init();
    	smg_init();
    	SMG_DATAPORT(0);
    	sys_parm_init();//系统参数初始化
    	TIM2_Init(500-1,79);//定时10ms
    	
    	while(1)
    	{
    		sys_data_show();//系统数据显示
    		sys_data_set();//系统数据设置		
    	}
    }
    
    
    
    

    三、实验现象

    演示视频:https://space.bilibili.com/444388619







    联系作者

    专注于51单片机、STM32、国产32、DSP、Proteus、ardunio、ESP32、物联网软件开发,PCB设计,视频分享,技术交流。

    物联沃分享整理
    物联沃-IOTWORD物联网 » Proteus仿真:STM32单片机交通灯控制系统设计详解

    发表评论