2021-08-10

这篇博客介绍了作者初次学习STM32LL库的经历,选择了LL库而非HAL库,因为其性能更优且与HAL库可混用。作者使用野火STM32F103VET6开发板,通过STM32CubeMX生成配置代码。文中详细解析了LL_GPIO_InitTypeDef结构体和Pin宏,并展示了如何使用相关函数进行GPIO初始化和控制LED灯的亮灭。实验中通过翻转GPIO实现LED灯的闪烁效果。
摘要由CSDN通过智能技术生成

为什么是LL

我是首次学习STM32,虽然之前有大致的了解但总是没有开始。我开始学之前大致了解了一下:

  1. ST 做了一个叫STM32CubeMX的东西,用于自动生成STM32的配置代码,它支持HAL库和LL库,不支持标准库。
  2. 据说HAL库被做的性能不好,于是后来开发了LL库。
  3. LL库是做为HAL库的补充,可以与HAL库混用。
    显而易见啊,我这么懒,肯定标准库劝退啊,肯定选HAL和LL;其次Keil的编辑器有点丑,我之前做视觉习惯用Clion,所以就按网上配了一套gcc-arm-none-eadi + OpenOCD的ToolChain(其实Keil自己改一下也还不错);LL库性能更好,所以选LL库,当然,必须要用HAL库的时候,还是用HAL库。

库结构

LL库作为HAL库的补充,源文件和HAL放在一起,进目录看LL库的文件,的确是一个补充,文件数量少了一半,有一些外设是没有LL实现的,但是作为新手,简单的外设用LL完全没有问题。

我的编译器

昨天更新CubeMX的时候被官方告知了未来将不支持此工具链了。(我没事更啥新呢)
所以在文章中与编译环境相关的东西不会出现。编译环境与CubeMX的代码生成设置一样就好。

开始!!点灯!!

开发平台
单片机:野火STM32F103VET6(指南者)
STM32CubeMX版本:6.3.0

CubeMX生成代码

其他文章有,不赘述了,和HAL库的一样,就是在Project ManagerAdvanced Settings里把你想用LL库的外设改成LL库的就行。
设置CubeMX改用LL库

实验硬件

我的板子上LED灯在GPIOB的0、1、5,分别是绿、蓝、红色灯(在一个灯里有三个灯珠,好高级的样子)

“灯大、灯亮、灯会闪”要做什么

我们要点灯自然要看GPIO库,根据HAL库的教程,点灯分几步:

  1. 初始化GPIO
  2. 置高/置低/翻转 GPIO

看看库里有什么

初始化结构体 LL_GPIO_InitTypeDef

/**
  * @brief LL GPIO Init Structure definition
  */
typedef struct
{
  uint32_t Pin;          /*!< Specifies the GPIO pins to be configured.
                              This parameter can be any value of @ref GPIO_LL_EC_PIN */

  uint32_t Mode;         /*!< Specifies the operating mode for the selected pins.
                              This parameter can be a value of @ref GPIO_LL_EC_MODE.

                              GPIO HW configuration can be modified afterwards using unitary function @ref LL_GPIO_SetPinMode().*/

  uint32_t Speed;        /*!< Specifies the speed for the selected pins.
                              This parameter can be a value of @ref GPIO_LL_EC_SPEED.

                              GPIO HW configuration can be modified afterwards using unitary function @ref LL_GPIO_SetPinSpeed().*/

  uint32_t OutputType;   /*!< Specifies the operating output type for the selected pins.
                              This parameter can be a value of @ref GPIO_LL_EC_OUTPUT.

                              GPIO HW configuration can be modified afterwards using unitary function @ref LL_GPIO_SetPinOutputType().*/

  uint32_t Pull;         /*!< Specifies the operating Pull-up/Pull down for the selected pins.
                              This parameter can be a value of @ref GPIO_LL_EC_PULL.

                              GPIO HW configuration can be modified afterwards using unitary function @ref LL_GPIO_SetPinPull().*/
} LL_GPIO_InitTypeDef;

Pin宏

#define LL_GPIO_PIN_0                    ((GPIO_BSRR_BS0  << GPIO_PIN_MASK_POS) | 0x00000001U)  /*!< Select pin 0  */
#define LL_GPIO_PIN_1                    ((GPIO_BSRR_BS1  << GPIO_PIN_MASK_POS) | 0x00000002U)  /*!< Select pin 1  */
#define LL_GPIO_PIN_2                    ((GPIO_BSRR_BS2  << GPIO_PIN_MASK_POS) | 0x00000004U)  /*!< Select pin 2  */
#define LL_GPIO_PIN_3                    ((GPIO_BSRR_BS3  << GPIO_PIN_MASK_POS) | 0x00000008U)  /*!< Select pin 3  */
#define LL_GPIO_PIN_4                    ((GPIO_BSRR_BS4  << GPIO_PIN_MASK_POS) | 0x00000010U)  /*!< Select pin 4  */
#define LL_GPIO_PIN_5                    ((GPIO_BSRR_BS5  << GPIO_PIN_MASK_POS) | 0x00000020U)  /*!< Select pin 5  */
#define LL_GPIO_PIN_6                    ((GPIO_BSRR_BS6  << GPIO_PIN_MASK_POS) | 0x00000040U)  /*!< Select pin 6  */
#define LL_GPIO_PIN_7                    ((GPIO_BSRR_BS7  << GPIO_PIN_MASK_POS) | 0x00000080U)  /*!< Select pin 7  */
#define LL_GPIO_PIN_8                    ((GPIO_BSRR_BS8  << GPIO_PIN_MASK_POS) | 0x04000001U)  /*!< Select pin 8  */
#define LL_GPIO_PIN_9                    ((GPIO_BSRR_BS9  << GPIO_PIN_MASK_POS) | 0x04000002U)  /*!< Select pin 9  */
#define LL_GPIO_PIN_10                   ((GPIO_BSRR_BS10 << GPIO_PIN_MASK_POS) | 0x04000004U)  /*!< Select pin 10 */
#define LL_GPIO_PIN_11                   ((GPIO_BSRR_BS11 << GPIO_PIN_MASK_POS) | 0x04000008U)  /*!< Select pin 11 */
#define LL_GPIO_PIN_12                   ((GPIO_BSRR_BS12 << GPIO_PIN_MASK_POS) | 0x04000010U)  /*!< Select pin 12 */
#define LL_GPIO_PIN_13                   ((GPIO_BSRR_BS13 << GPIO_PIN_MASK_POS) | 0x04000020U)  /*!< Select pin 13 */
#define LL_GPIO_PIN_14                   ((GPIO_BSRR_BS14 << GPIO_PIN_MASK_POS) | 0x04000040U)  /*!< Select pin 14 */
#define LL_GPIO_PIN_15                   ((GPIO_BSRR_BS15 << GPIO_PIN_MASK_POS) | 0x04000080U)  /*!< Select pin 15 */
#define LL_GPIO_PIN_ALL                  (LL_GPIO_PIN_0  | LL_GPIO_PIN_1  | LL_GPIO_PIN_2  | \
                                          LL_GPIO_PIN_3  | LL_GPIO_PIN_4  | LL_GPIO_PIN_5  | \
                                          LL_GPIO_PIN_6  | LL_GPIO_PIN_7  | LL_GPIO_PIN_8  | \
                                          LL_GPIO_PIN_9  | LL_GPIO_PIN_10 | LL_GPIO_PIN_11 | \
                                          LL_GPIO_PIN_12 | LL_GPIO_PIN_13 | LL_GPIO_PIN_14 | \
                                          LL_GPIO_PIN_15)                                      /*!< Select all pins */

主要相关函数

__STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask); //对GPIOx的PinMask引脚置高电平(多引脚用或连接)

__STATIC_INLINE void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask); //对GPIOx的PinMask引脚置低电平

__STATIC_INLINE void LL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint32_t PinMask); //翻转GPIOx的PinMask引脚置电平

__STATIC_INLINE void LL_GPIO_WriteOutputPort(GPIO_TypeDef *GPIOx, uint32_t PortValue);//对GPIOx的所有引脚赋值

实验主要代码

int main() {
	/* Some initial code*/
	Init();

	/* infinite loop*/
	while (1) {
		//Toggle Pin0 by set and reset function
		LL_GPIO_SetOutputpin(GPIOB, LL_GPIO_PIN_0);
		LL_mDelay(500);
		LL_GPIO_ResetOutputpin(GPIOB, LL_GPIO_PIN_0);
		LL_mDelay(500);
		
		//Toggle Pin1 by toggle function
		LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_1);
		LL_mDelay(500);
	}

原理

打开源文件stm32f1xx_ll_gpio.c 可以看到函数的源码

__STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)
{
  WRITE_REG(GPIOx->BSRR, (PinMask >> GPIO_PIN_MASK_POS) & 0x0000FFFFU);
}

可以看到LL是写寄存器操作

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值