【蓝桥杯嵌入式组】HAL库STM32CubeMx学习笔记三:01-LED

一、开发板资源介绍

如原理图所示,开发板上有8个可供编程的LED。但8个LED与LCD引脚复用。若同时使用LED和LCD会出现冲突。
在这里插入图片描述

所以开发板上使用了74HC573锁存器,只有在PD2引脚由高到低时,LED的状态才会刷新。由此解决LED和LCD冲突的问题。

8个LED为低电平时点亮。
在这里插入图片描述

二、配置工程

1、配置引脚

在引脚图上单击某个引脚,选择想要配置的模式,即可配置成功。如下图为配置PD2引脚为输出模式。
在这里插入图片描述

由于开发板上8个LED与LCD引脚冲突,所以需要将PD2设置为输出模式,我习惯性将该引脚重命名为LE,也可不命名。LED的状态将在PD2的由高到低时刷新。

8个LED对应引脚为PC8-PC15,同样设置为输出模式。

如下图即为配置完成。
在这里插入图片描述

2、设置变量

在main.c中用户添加变量区内设置变量

uint8_t ucLed;

3、通用函数

在main.c中用户添加代码区添加以下代码

此函数在为通用函数,只要涉及有LED的题目,都需要编写此函数。

void LED_Disp(uint8_t led)
{
	GPIOC->ODR = ~led<<8;
	//LED的状态将在PD2的由高到低时刷新。CubeMx中已将PD2重命名为LE。
	HAL_GPIO_WritePin(LE_GPIO_Port,LE_Pin,GPIO_PIN_SET);
	HAL_GPIO_WritePin(LE_GPIO_Port,LE_Pin,GPIO_PIN_RESET);
}

函数使用方法:

  1. 若想让LED1点亮,只需调用函数LED_Disp(0x01);
    因为0x01=0000 0001,取反,~0x01=1111 1110,再<<8,即为PC引脚高8位为1111 1110。也就是PC8为低电平,由原理图可知LED低电平时被点亮。
  2. 若想要LED1和LED5被点亮,只需调用函数LED_Disp(0x11);
    因为0x11=0001 0001,取反,~0x11=1110 1110,再<<8,即为PC引脚高8位为1110 1110。也就是PC8和PC12为低电平。
以下代码是基于2设置变量,3通用函数的基础上编写的功能函数。

4、应用函数

由于题目中对于LED的要求一般是,在xxx情况下点亮,在xxx情况下熄灭。在xxx情况下以0.5s频率闪烁,因此我们需要根据题意编写应用函数。

4.1 LED1在lck≠0时点亮,否则熄灭;LED2在VR37>1时闪烁,否则熄灭。

1.在main.c中用户添加代码区添加以下代码

//通过ucLed按位或、与、异或的方式可改变某个LED状态而不影响其他LED,记得调用 LED_Disp(ucLed);  
void LED_Proc(void)              		 	
{
    if(lck != 0)
        ucLed |= 1;//按位或,LD1亮 例如: 1111 1110|0000 0001=1111 1111
    else
        ucLed &= ~1;//按位与,LD1灭 例如1010 1111&1111 1110=1010 1110

    if(VR37 > 1)
        ucLed ^= 2;//按位异或 1^1=0  0^1=1,LD2状态翻转
    else
        ucLed &= ~2;//按位与1&0=0 0&0=0,LD2灭  
        
    LED_Disp(ucLed);                 		
}

2.最后在while中调用LED_Proc();

在这里插入图片描述

4.2 LED1以0.5s频率闪烁

1.在stm32g4xx_it.c中声明变量

uint32_t ulTime;

2.在stm32g4xx_it.c中void SysTick_Handler(void)下添加以下代码

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
    ulTime++;
    if(ulTime % 500 == 0)	
        ucLedState ^= 1;
  /* USER CODE END SysTick_IRQn 1 */
}

每过1ms,ulTime加一;每到ulTime是500的倍数(每隔0.5s)时,ucLedState翻转,在LED_Proc(void)中,ucLedState=1点亮,ucLedState=0熄灭,即每隔0.5sLED1状态翻转1次,LED1以0.5s频率闪烁。

3.在main.c中用户添加代码区添加以下代码

void LED_Proc(void)              		 	
{
    if(ucLedState)//以0.5s频率闪烁
        ucLed |= 1;
    else
        ucLed &= ~1;

    LED_Disp(ucLed);                 		
}

4.最后在while中调用LED_Proc();

在这里插入图片描述

三、真题小练习

1、 按键按下后LD1亮3秒之后灭

1.在main.c中设置变量

uint16_t usLed;

2.main.c中添加代码

void KEY_Proc(void)
{
    if(ucKEY==1)//如果按键1被按下,按键检测函数可查阅学习笔记四
        usLed = 3000;
}
void LED_Proc(void)
{	
    if(usLed>0)     
        ucLed |= 1;
    else
        ucLed &= ~1;

    LED_Disp(ucLed);
}

3.在stm32g4xx_it.c中声明外部变量

extern uint16_t usLed;

4.在stm32g4xx_it.c中void SysTick_Handler(void)下添加代码

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
    if(usLed>0)
	usLed--;
  /* USER CODE END SysTick_IRQn 1 */
}

5.最后在while中调用LED_Proc();

2、 LED状态和LED序号均改变

LED状态根据电压值改变
R37 输出电压值超过电压上限值时(VR37>V 上限),上限提醒指示灯以 0.2 秒为间隔闪烁,下限指示灯熄灭。
R37 输出电压值低于电压下限值时(VR37<V 下限),下限提醒指示灯以 0.2 秒为间隔闪烁,上限指示灯熄灭。
R37 输出电压值介于上限和下限电压之间时(V 下限≤VR37≤V 上限),上限、下限提醒指示灯熄灭。
竞赛板上除当前用做超出上限、低于下限提醒功能的指示灯外,其它指示灯应处于熄灭状态。

LED序号根据按键值改变
B3:定义为“加”按键,LED 指示灯序号加 1。
B4:定义为“减”按键,LED 指示灯序号减 1。

1.在main.c中设置变量

uint8_t ucLed,ucLedState;
uint16_t Led_All[8]={GPIO_PIN_8,GPIO_PIN_9,GPIO_PIN_10,GPIO_PIN_11,
                    GPIO_PIN_12,GPIO_PIN_13,GPIO_PIN_14,GPIO_PIN_15};

2.main.c中添加代码

void LED_Disp(uint8_t led)
{
	GPIOC->ODR = ~led<<8;
	//LED的状态将在PD2的由高到低时刷新。CubeMx中已将PD2重命名为LE。
	HAL_GPIO_WritePin(LE_GPIO_Port,LE_Pin,GPIO_PIN_SET);
	HAL_GPIO_WritePin(LE_GPIO_Port,LE_Pin,GPIO_PIN_RESET);
}
void LED_Proc(void)
{
    //如果用原来改变ucled的方法,在切换led时会出现,几个led同时亮的情况,所以用下面的方法
    //设置数组的目的是按键可改变上下限指示灯,Led_Upper和Led_Lower的值在按键函数中改变
    
    LED_Disp(ucLed);//此时ucLed=0,所以灯全熄灭。
    
    if(VR37 > MaxVolt)
        HAL_GPIO_WritePin(GPIOC,Led_All[Led_Upper-1],ucLedState);
    else
        HAL_GPIO_WritePin(GPIOC,Led_All[Led_Upper-1],GPIO_PIN_SET);
    if(VR37 < MinVolt)
        HAL_GPIO_WritePin(GPIOC,Led_All[Led_Lower-1],ucLedState);
    else
        HAL_GPIO_WritePin(GPIOC,Led_All[Led_Lower-1],GPIO_PIN_SET);
	
    HAL_GPIO_WritePin(LE_GPIO_Port,LE_Pin,GPIO_PIN_SET);
    HAL_GPIO_WritePin(LE_GPIO_Port,LE_Pin,GPIO_PIN_RESET);	
}

3.在stm32g4xx_it.c中声明变量

uint32_t ucLedTime;
extern uint8_t ucLedState ;

4.在stm32g4xx_it.c中void SysTick_Handler(void)下添加代码

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
    ucLedTime++;
    if(ucLedTime%200 == 0)
        ucLedState ^=1;
  /* USER CODE END SysTick_IRQn 1 */
}

5.最后在while中调用LED_Proc();

LED的题目要求往往要和其他条件相连,所以可以再学习其他模块后做真题过程中强化LED。

在这里有一些学习资料建议,欢迎批评指正【蓝桥杯嵌入式组】HAL库STM32CubeMx学习笔记汇总:学习建议及资料

  • 8
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KkKde小火柴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值