自学《STM32不完全手册》的笔记三

自学《STM32不完全手册》的笔记三

MDK固件库快速组织代码

例:初始化某个 GPIO 端口
定义 GPIO 初始化函数为:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

函数的入口参数是 GPIO_TypeDef 类型指针和 GPIO_InitTypeDef 类型指针,go to definition of ‘GPIO_Init’

typedef struct
{ uint16_t GPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode; GPIOMode_TypeDef */
}GPIO_InitTypeDef;

我们首先要定义一个结构体变量:
GPIO_InitTypeDef GPIO_InitStructure;
接着我们要初始化结构体变量 GPIO_InitStructure。首先我们要初始化成员变量 GPIO_Pin。在 GPIO_Init 函数里有 assert_param 函数,第一行是对第一个参数 GPIOx 进行有效性判断,双击“IS_GPIO_ALL_PERIPH”右键点击“go to defition of…” 可得GPIOx 的取值规定只允许是 GPIOA~GPIOG。同样的方法可以查看GPIO_Mode和 GPIO_Speed 的参数限制。

了解后可以组织以下代码:

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(GPIOB, &GPIO_InitStructure);

tips:我们可以通过|(或)的方式同时初始化多个 IO 口。这样操作的前
提是,他们的 Mode 和 Speed 参数相同,因为 Mode 和 Speed 参数并不能一次定义多种。所以
初始化多个 IO 口的方式可以是如下:

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7; //指定端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //端口模式: 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化

问题:每次使能时钟的时候都要去查看时钟树看那些外设是挂载在那个总线之下的,好麻烦。
解决:stm32f10x.h 文件里面我们可以看到如下的宏定义:

#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB ((uint32_t)0x00000008)
#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010)
#define RCC_APB1Periph_TIM2 ((uint32_t)0x00000001)
#define RCC_APB1Periph_TIM3 ((uint32_t)0x00000002)
#define RCC_APB1Periph_TIM4 ((uint32_t)0x00000004)
#define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001)
#define RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002)

可得GPIOA~GPIOC 是挂载在 APB2 下面, TIM2~TIM4 是挂载在 APB1下面,DMA 是挂载 在AHB下面。 则使能DMA调用RCC_AHBPeriphClock()函数,使能GPIO 的时候调用的是 RCC_APB2PeriphResetCmd()函数。

上一篇:基于STM32的简易Bootloader实现


下一篇:leetcode 190. 颠倒二进制位(c++)