基于STM32的交通灯数码管显示proteus仿真

硬件设计

链接:https://pan.baidu.com/s/1wFrmwNwNZaIt_wF29_CHDg
提取码:xz0b
仿真图如下所示:
在这里插入图片描述

程序设计

#include "stm32f103_config.h"


#define LED595_DATA   	PBout(7)
#define LED595_CLK		PBout(8)
#define LED595_LATCH  	PBout(9)

#define DXR  PBout(0)
#define DXG  PBout(1)
#define DXY  PBout(10)

#define NBR  PBout(11)
#define NBG  PBout(12)
#define NBY  PBout(13)

unsigned char duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void io_Init(void)//初始化GPIO
{
	GPIO_InitTypeDef  GPIO_InitStructure;	

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;	//GPIO_PIN0-16		
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 
	GPIO_Init(GPIOB, &GPIO_InitStructure);					 
	GPIO_ResetBits(GPIOB,GPIO_Pin_All);		
}


void _delay_ms(int i)//延时函数
{
	u16 j;
	while(i--)
	{
		for(j=0;j<5600;j++);
	}
}

void _delay_us(int i)//延时函数
{
	u16 j;
	while(i--)
	{
		for(j=0;j<5;j++);
	}
}

void inp(unsigned char OutData)
{
	unsigned char i; 
	for(i=0; i<8; i++) //将8位数据按位发送,先发送高字节后发送低字节
	{
		LED595_CLK=0;//时钟线低电平
		_delay_us(1);
		if( (OutData & 0x80) == 0x80)//判断数据高低位
		{
			LED595_DATA=1;                   //数据线高电平
		}
		else
		{
			 LED595_DATA=0;          //数据线低电平
		}
		_delay_us(1);
		OutData = OutData << 1;         //数据左移1位
		LED595_CLK=1;                 //时钟线高电平
		_delay_us(1);
	}
}

void LED595SendData(int a,int b)
{
	inp(duan[b%10]);
	inp(duan[b/10]);
	
	inp(duan[a%10]);
	inp(duan[a/10]);
	
    LED595_LATCH=0;  
	_delay_us(1);
    LED595_LATCH=1;
	_delay_us(1);
}


int main(void)//主函数
{	
	int state=0;
	int num=30;
	
	
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_5);//系统时钟初始化
	io_Init();//引脚初始化
	uart_init(9600);//串口初始化
	sendDat(0x02);sendDat(0x04);
	while(1)
	{
		num--;//倒计时
		if(num==0)
		{
			state++;if(state==4)state=0;//四种模式对应
			/*
			(1)南北红灯 东西绿灯(30秒)
			(2)南北红灯 东西黄灯(05秒)
			(3)南北绿灯 东西红灯(30秒)
			(4)南北黄灯 东西红灯(05秒)

			*/
			switch (state)//更新时间
			{
				case 0: num=30;sendDat(0x02);sendDat(0x04);break;
				case 1: num= 5;sendDat(0x03);sendDat(0x04);break;
				case 2: num=30;sendDat(0x01);sendDat(0x05);break;
				case 3: num= 5;sendDat(0x01);sendDat(0x06);break;
			}
		}
		
		switch (state)//根据状态点亮LED
		{
			case 0: DXR=0;DXY=0;DXG=1;NBR=1;NBY=0;NBG=0;break;
			case 1: DXR=0;DXY=1;DXG=0;NBR=1;NBY=0;NBG=0;break;
			case 2: DXR=1;DXY=0;DXG=0;NBR=0;NBY=0;NBG=1;break;
			case 3: DXR=1;DXY=0;DXG=0;NBR=0;NBY=1;NBG=0;break;
		}
		
		switch (state)//根据状态显示当前倒计时
		{
			case 0: LED595SendData(num,num+5);break;
			case 1: LED595SendData(num,num);break;
			case 2: LED595SendData(num+5,num);break;
			case 3: LED595SendData(num,num);break;
		}
				
		_delay_ms(100);//延时  速度快慢调这里
	}

}











.

.

硬件设计:采用Proteus进行电路原理图设计与仿真 1)单片机选用AT89C51,它与8051系列单片机全兼容,但其内部带有4KB的FLASH ROM,设计时无需外接程序存储器。 2)显示部分:南北向和东西向各采用2个LED数码管计时,对该方向的指示灯的点亮时间进行倒计时,最长计时范围为99秒。 3)键盘部分:设置键、增加键、减少键。 本系统的工作流程: 1)系统启动后,系统按程序给定的时间工作,即东西向通行60秒,南北向通行40秒,黄灯亮4秒,工作模式如表1所示。首先东西向通行,然后南北向通行,如此循环。 2)通行时间的设置:当需要更改主、次干道的通行时间时,可以用设置键、增加键、减少键”进行设置。 第一次按“设置键”时,东西向的绿灯亮,东西向的LED数码管显示当前东西向的通行时间,并且按每秒3次的频率闪烁(每秒钟亮3次暗3次),其余的信号指示灯和南北向的LED数码管熄灭,此时可以用“增加键”和“减少键”来改变南北向的通行时间,每按一次键,数码管的显示时间增加1秒或减少1秒,长按键(按下的时间超过1秒钟以上),则数码管显示的时间按每秒钟增加或减少10的速度快速变化。 第二次按“设置键”时,东西向的黄灯亮,东西向的数码管显示当前东西向黄灯的点亮时间,并且按每秒3次的频率闪烁,其余的信号指示灯和南北向的数码管熄灭,此时可以用“增加键”和“减少键”来改变东西向黄灯的点亮时间。 第三次按“设置键”时,南北向的绿灯亮,南北向的数码管显示当前南北向绿灯的通行时间,并且按每秒3次的频率闪烁,其余的信号指示灯和东西向的数码管熄灭,此时可以用“增加键”和“减少键”来改变南北向绿灯的通行时间。 第四次按“设置键”时,南北向的黄灯亮,南北向的数码管显示当前南北向黄灯的点亮时间,并且按每秒3次的频率闪烁,其余的信号指示灯和东西向的数码管熄灭,此时可以用“增加键”和“减少键”来改变南北向黄灯的点亮时间。 第五次按“设置键”时,系统退出设置状态,回到交通信号灯状态,并且东西向先通行,南北向后通行 软件设计:采用Keil C开发环境与语言 1)软件模块:根据上述工作流程和设计要求,软件设计可以分为以下几个功能模块: 主程序:初始化及键盘监控。 计时程序模块:为定时器的中断服务子程序。 显示程序模块:完成12个发光二极管和4个LED数码管的显示驱动。 键盘扫描程序模块:判断是否有键按下,并求取键号。 键处理程序模块:分别是“设置键”、“增加键”、“减少键”的处理子程序。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值