蓝桥杯嵌入式_cubemx设置方法以及hal库编程思路

GPIO学习和了解——初步掌握HAL库编程思路以及Cubemx配置方法

 本次文章没有探究hal库和fw库的差别,目前没有细读hal库的文档例程;

1.cubemx生成工程框架

主要是将配置RCC的外部晶振时钟,把时钟树参数填好(后续对时钟配置有更高的要求时再讨论如何配置)

目前直接配置成80MHz

2.建立两个文件夹,一个用来存放cubemx直接生成的文件,主要是一些初始化代码,但是由于代码风格不佳,所以不直接使用;

另一个文件为正式工程文件,将cubemx初始化代码按自己风格移植,并且编写bsp层代码,使用main函数调用实现功能。

3.GPIO点灯实验

蓝桥杯嵌入式_cubemx设置方法以及hal库编程思路

 

 蓝桥杯嵌入式_cubemx设置方法以及hal库编程思路

 

 生成框架之后,文件复制到另一个文件夹里面,之后根据实现目的,继续进行外设初始化,下面进行GPIO初始化。

蓝桥杯嵌入式_cubemx设置方法以及hal库编程思路

 

 根据LED电路原理图,了解output mode以及level,并且因为有锁存器的存在,需要额外注意多一个PD2需要控制。

蓝桥杯嵌入式_cubemx设置方法以及hal库编程思路

 

 蓝桥杯嵌入式_cubemx设置方法以及hal库编程思路锁存器使用三态门控制存储,

LE为high时,Q更新为D;OE为low时,Qn更新为Q;所以在OE接gnd的情况下,LE为高电平则锁存器打开,pin值送给led,否则关闭。(LED低电平点亮)

 

 蓝桥杯嵌入式_cubemx设置方法以及hal库编程思路

 

 PC8-PC15属于既连接了led,又连接了LCD,所以需要锁存器保证led和lcd互不干扰。

 4.程序改写

生成框架产生的gpio.c文件只有一句简单代码:

  __HAL_RCC_GPIOF_CLK_ENABLE();

而led相关的gpio初始化之后,cubemx生成的代码包含了上述代码,因此,可以直接改写。

(ps:这个地方看起来好像很傻,因为框架生成的代码被更进一步的gpio生成代码所包含,这是肯定的但是在后续更多外设的使用中,不可避免出现代码混乱,所以每一步都依次改写,不嫌麻烦,是有必要的,至少对我这个新手来说。)

改写方式如下:新建bsp层,建立bsp_led.c,设置好头文件路径等之后,在bsp_led.c中做gpio的初始化,以及调用GPIOWRITEPIN更改寄存器值,实现开关锁存器并输出高低电平。

#include "led\bsp_led.h"

void Led_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);

  /*Configure GPIO pins : PC13 PC14 PC15 PC8
                           PC9 PC10 PC11 PC12 */
  GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
                          |GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PD2 */
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

}
//函数名:Led_Disp
//函数入口:ucLed
//函数出口:void
//函数功能ucLed的数值传递给GPIOC的pin8-pin15,实现点亮对应Led的功能
void Led_Disp(unsigned char ucLed)
{
    //switch off all the leds.
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
    
    //switch on the specific leds.
    HAL_GPIO_WritePin(GPIOC, ucLed<<8, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
    
}

之后在main.c中调用Led_Disp写入需要点亮的led就可以了。

(右移八位——因为PC8-15为led对应pin,所以一个unsigned char为8位,右移八位才能变成高8为数值,变成鱼Pin8-Pin15一样的数字。)

 

 

end

 

上一篇:5.STM32F407之HAL库——串口通信


下一篇:stm32F4/L4 UART学习汇总