蓝桥杯嵌入式(二):从点亮LED开始

1.前言

不管是玩什么芯片,点灯都是一个绕不开的话题。在蓝桥杯的嵌入式比赛中,几乎每一年的省赛都涉及到与LED有关的设计。点灯说白了也很简单,无非就是分为点亮一个灯、点亮多个灯以及流水灯和灯闪烁等等情况。

接下来本文将会分别讲解如何实现上述功能。

2.硬件配置

点灯之前肯定要知道LED是怎么和STM32连接的,可以参考蓝桥杯嵌入式开发手册

从图中可以看出,开发板的8个LED连接在STM32的PC8~PC15,并且LED是共阳极连接,这表明GPIO引脚为低电平时,从才能点亮LED。图中的SN74HC573ADWR是一个锁存器,其控制位LE和STM32的PD2引脚连接。

那锁存器是干什么的呢?简单来说,它能够将输入到锁存器中的数据保存并输出,当打开锁存器的时候,LED才能接收到来自STM32的电平信号,当锁存器关闭时,LED无法被STM32的引脚高低电平影响。关于这个锁存器的详细信息可以通过查找其数据手册,此处我们只要知道,PD2引脚高电平可以打开该锁存器,低电平则是关闭

知道了这些,就可以在STM32CubeMX中控制配置相关的引脚,当然你可以选择和我一样,通过代码配置这些引脚。上述提到的GPIO引脚均可以配置为推挽输出模式,引脚速度为低速或者高速都可以。如果想要开发板的所有LED在上电时均保持熄灭,可以将PC8~PC15的初始电平全部设置为高电平

void Led_GPIO_Init(void)
{
	__HAL_RCC_GPIOC_CLK_ENABLE();
	
	GPIO_InitTypeDef gpio_led_init;
	gpio_led_init.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 |GPIO_PIN_11 |GPIO_PIN_12 |GPIO_PIN_13 |GPIO_PIN_14 |GPIO_PIN_15;
	gpio_led_init.Mode = GPIO_MODE_OUTPUT_PP;
	gpio_led_init.Speed = GPIO_SPEED_LOW;
		
	HAL_GPIO_Init(GPIOC, &gpio_led_init);
	
	__HAL_RCC_GPIOD_CLK_ENABLE();
	
	GPIO_InitTypeDef gpio_74HC573_init;
	gpio_74HC573_init.Pin = GPIO_PIN_2;
	gpio_74HC573_init.Mode = GPIO_MODE_OUTPUT_PP;
	gpio_74HC573_init.Speed = GPIO_SPEED_HIGH;
		
	HAL_GPIO_Init(GPIOD,&gpio_74HC573_init);

	HAL_GPIO_WritePin(GPIOC, gpio_led_init.Pin, GPIO_PIN_SET);
}

 3.代码实现

3.1点亮一个LED

点亮一个LED非常简单,只需要将LED对应的GPIO电平拉低即可。以下给出HAL库代码,当然你也可以选择通过修改寄存器的值实现。

void Led_Disp(void)
{
	//点亮LED1
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);

	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);//打开锁存器
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);//关闭锁存器
}

3.2点亮多个LED

这部分的代码和上述代码并没有什么区别,只需要将所需点亮的LED对应的引脚通过“|”相连接即可。

void Led_Disp(void)
{
	//点亮LED1和LED8
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8|GPIO_PIN_15, GPIO_PIN_RESET);
	
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

3.3LED闪烁

LED闪烁有两种办法可以实现,一种是先打开LED,延时一定时间(这段时间通常为ms级别)后关闭LED,再延时一定时间后再打开LED。

void Led_Disp(void)
{
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);//打开锁存器
	
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);
	HAL_Delay(500);//延时500ms
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);
	HAL_Delay(500);
	
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);//关闭锁存器
}

当然也可以使用HAL库自带的电平翻转函数实现。

void Led_Disp(void)
{
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
	HAL_Delay(500);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

3.4流水灯

STM32并没有专门实现流水灯的HAL库函数,这里提供一种通过写寄存器的方式实现的方法。

首先,该函数有比较大的局限性,只能放在main.c文件中,因为其涉及到了对全局变量led的修改。led是一个无符号整型变量,初始化的值代表流水灯上电时的LED状态。在下面的函数中,会对led的值进行修改,将其左移8为是因为所使用的GPIO引脚是PC8~PC15,对应的ODR寄存器的值是从第8位到第15位。将led值取反是因为在本开发板中LED是低电平点亮。每次运行该函数,都会使led的值向左移一位,当led的值全部溢出时,也就是全为0时,则重新设置led的值,使其从led1开始依次点亮。

void Led_Disp(void)
{
	
	GPIOC->ODR = ~led << 8;
	HAL_Delay(50);
	if(led == 0)	led = 1;
	else	led = led << 1;
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

以上就是本文的全部内容了,如有错误还请海涵指正。

  • 66
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值