蓝桥杯嵌入式(二)LED配置

LED是开发板上较为简单的模块,我们来学习如何配置LED,最后实现简单的流水灯。

蓝桥杯嵌入式板子上共有8路LED输出,在进行LED的配置之前,我们先要了解LED所对应的引脚。

打开蓝桥杯比赛提供中的原理图,可以看到8个LED灯对应PC端口的PC8~PC15,LED灯的左边连接着一个74HC573锁存器

LE为锁存控制端,OE为使能端,1D~8D为数据输入端,1Q~8Q为数据输出端。LE为高时,Q输出将随数据D输入而变;当LE为低时,将输出锁存在已建立的数据电平上。锁存器的输出控制不影响锁存器的内部工作,即老数据可以保持,甚至当输出被关闭时,新的数据也可以置入。这个锁存器的手册在蓝桥杯比赛提供的数据手册文件夹中就有,可以查阅它更加具体的功能。

因为8路LED的引脚和LCD显示屏的引脚是共用的,如果不进行数据锁存,那么8路LED将会亮灭混乱

了解了LED的连接,接下来我们就可以开始配置LED了,配置代码如下:

void LED_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = 0xff00;                       
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //推挽输出
	GPIO_Init(GPIOC, &GPIO_InitStructure);    

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	GPIOC->ODR |= 0xff00;
	GPIOD->ODR |= (0x1 << 2);    //打开LE锁存器
	GPIOD->ODR &= ~(0x1 << 2);   //关闭LE锁存器
}

第一步:在配置STM32外设的时候,任何时候都要先使能该外设的时钟。GPIO是挂载在APB2总线上的外设,在固件库中对挂载在APB2总线上的外设时钟使能是通过函数RCC_APB2PeriphClockCmd()来实现的。在stm32f10x_rcc.h中可以快速找到这个函数,第5行代码的作用是使能APB2总线上的GPIOC、GPIOD的时钟。

第二步:在配置完时钟之后,我们就要对引脚进行具体配置,在stm32f10x_gpio.h中找到GPIO_Init()函数,GPIOC和GPIOD的IO口的初始化参数都是在结构体变量GPIO_InitStructure中。因为端口用做LED输出,所以配置为推挽输出模式。

由于需要配置的端口较多,一个一个写很麻烦,我们找到固件库的定义。

我们把Pin8~Pin15端口直接加起来得到0xff00,所以在代码第7行直接一次性配置完。由上面的原理图可看出锁存器的控制引脚为PD2,所以还需配置PD2引脚。

第三步:因为开发板复位后,LED默认是点亮的,因此初始化时我们要把LED全熄灭。接下来就是对锁存器的操作了,其实就是对PD2引脚的控制(拉高、拉低),可以使用库函数进行配置,也可以直接操作寄存器,我个人比较喜欢直接对寄存器进行操作,两种方法按个人喜好选取。

u16 LED=0xffff;
void Led_Set(void)
{
	GPIOC->ODR = 	LED;
	GPIOD->ODR |= (1<<2);			//打开锁存
	GPIOD->ODR &= ~(1<<2);			//关闭锁存
}
void Led_Set(u16 led,u8 state)
{
	if(state==1)
	{
		GPIO_ResetBits(GPIOC,led);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);				//打开锁存
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);			//关闭锁存
	}
	else
	{
		GPIO_SetBits(GPIOC,led);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);
	}
}

寄存器配置方法使用到ODR寄存器,ODR为端口输出寄存器,它的具体作用可以查看stm32手册,有详细介绍每一位的作用。

到此,LED的配置就完成了,现在我们来写个简单的流水灯来试试效果。

LED配置与上面代码相同,既然是流水灯,就应该有流水间隔,工程模版中提供了延时函数,就没有必要自己再配置一个定时器做延时。

代码如下

#include "stm32f10x.h"
#include "io.h"

u32 TimingDelay = 0;
void Delay_Ms(u32 nTime);

extern u16 LED;
//流水灯
void LED_Show()
{
	static u8 i=8;
	
	LED = 0xffff;
	LED &= ~(0x01<<i);
	
	if(++i>=16)
		i=8;
	Led_Set();
}

//Main Body
int main(void)
{
	SysTick_Config(SystemCoreClock/1000);
	Led_Init();

	while(1)
	{
		LED_Show();
		Delay_Ms(500);
	}
}
//1ms延时函数
void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

流水间隔为500ms,可以根据需要调整,把程序烧录到开发板中,就可以看到流水灯效果。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值