硬件设计
链接: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);//延时 速度快慢调这里
}
}
.
.