跳转至

4.2 STM32系统开发-固件库与固件库编程

前言

STM32固件库简介

STM32固件库是意法半导体为了提高代码的可移植性,为了加快产品开发所提供的一整套API,这些API一方面向下直接操作硬件寄存器,一方面向用户提供可编程接口,使得用户可以在不用知道知道具体寄存器的情况下编写应用程序,而且便于移植。

如果读者曾经学习过51单片机的话,可能会比较容易理解。因为在51单片机开发的过程中,我们常常直接操作寄存器,即或读或写取指定位。比如要控制51的IO口的高低电平状态,使用字节赋值方式操作寄存器:

1
P0 = 0x21

上面这段代码会将P0.0和P0.5位口置高,同样在STM32的开发中,我们也可以直接操作寄存器,只不过是每次操作的寄存器的位长由原先的8位变成了32位:

1
GPIOx->BRR = 0x0021

51的寄存器数量少,字长短,掌握每个寄存器的用法进而直接操作寄存器进行编程还不算太难,但是STM32的寄存器数量有数百个,而且字长均为32位,这个体量掌握起来就非常有难度了。于是意法半导体将对这些底层寄存器的操作封装起来,提供一整套API供开发者使用。这使得开发者有时不需要知道操作的具体是哪个寄存器,就可以编写应用程序。比如上面通过向BRR寄存器写值的代码在官方固件库中都已经封装好了:

1
2
3
4
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
    GPIOx->BRR = GPIO_Pin;
}

只需要知道操作的是哪组GPIO口和GPIO口的哪一位,就可以直接调用GPIO_ResetBits(GPIOx, GPIO_Pin)来操作,而且由于固件库都有很好的命名规范,所以基本上通过函数名字就可以大概了解这个函数的功能是什么,相比寄存器编程方式来说,也大大提高了程序的可读性。

总结

使用固件库编程是有其固定的程序编写方法的,一般上是先初始化硬件驱动,初始化使用固件库的一般格式是:

使能对应外设的时钟 -> 定义外设初始化结构体 -> 设置初始化结构体各成员变量的值 -> 对于给定待初始化外设变量和初始化结构体调用初始化函数

比如使用固件库来初始化GPIOA的格式如下:

1
2
3
4
5
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

注意

这里只是为了讲解固件库初始化的一般方式,GPIO的具体用法和相应参数后面会详细讲解。

上面代码先定义了一个GPIO口的初始化结构体 GPIO_InitTypeDef 类型的变量 GPIO_InitStructure,然后对其成员变量按照用户要求赋值,最后对 GPIOAGPIO_InitStructure 调用 GPIO_Init 函数来实现对GPIOA第5个端口的初始化。

参考