使用库函数点亮LED,不用我们自己去查看寄存器,方便我们的开发,但是库函数是怎样封装的呢?
int main(void)
{
//声明一个结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
//使能GPIO外设时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
//定义一个结构体
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9 |GPIO_Pin_10;//连接LED的引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //输出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF,&GPIO_InitStructure);
delay_init(84);
while(1)
{
GPIO_SetBits(GPIOF,GPIO_Pin_9 |GPIO_Pin_10);
delay_ms(1000);
GPIO_ResetBits(GPIOF,GPIO_Pin_9 |GPIO_Pin_10);
delay_ms(1000);
}
}
一. 首先我们应该先从整体上了解内存地址分布,从0~0xFFFFFFFF,将其分成8个block,每个block为512M。
在block0中,比较关心的应该是flash,也就是我们存放代码的地方(应该可以说是二进制代码)。
在block1中,是SRAM,128KB。
在block2中,这个才是这里最关键要讲的,这里包含了APB1,APB2,其中有很多的外设如IIC,SPI,TIMER等,从图中,我们就可以看到该外设的总线的基地址。
二.先明确一点,我们通常是如何操作寄存器的。
*((uint32_t *)0x42024000)=0x00000001;
将一个数值将其强制装换为一个32位地址,然后就可以将其进行32位的存取操作
三.接下看看库函数中是如何封装的,以GPIOF为例
思路:先判断GPIO在那条总线上,然后找到其总线基地址,然后GPIOF的偏移量是多少
所以如下图可知,GPIOF在AHB1总线上,找到AHB1的总线地址,为0x40020000(上面图少个一个0,是4个字节)
在头文件stm32f4xx.h
总外设的基地址:
AHB1外设总线的基地址为:
因此,地址显而易见
0x40000000+0x00020000=0x40020000
接下来我们再找到GPIO的基地址:
在STM32F4xx中文参考手册中,我们可以找到这样的文字,看出它的偏移地址为0x00001400
因此GPIOF的基地址定义如下
四.寄存器结构体(我自己命名的,不知道有没有这种说法)
所谓寄存器结构体,就是将某种功能的寄存器,一起封装而成,以GPIOF为例
我们知道要操作一个IO口,要进行多种寄存器配置,所以库函数头文件stm32f4xx.h中,就有如下结构体
为什是要按照这个顺序排列呢,从下面几图就可以清楚看出来
封装之后这些寄存器就好控制了,但是现在和我们上面说的基地址有什么关系?自己刚看出来的时候,觉得巧妙
库函数中对其进行如下处理:
将以GPIOF_BASE为基地址转化为结构体指针 ,也就是说,该结构体以0x40021400为基地址,结构体中的寄存器进行4个字节偏移的偏移,然后进行操作,如下图所示
先将GPIOF指针传入,然后直接进行寄存器进行操作,库函数的寄存器封装到此为止
五.人性化结构体(这也是我自己这样叫的)
所谓人性化结构体,就是以我们正常人比较好理解的方式进行封装成结构体,如下
这种结构体我们一下就可以看出它是做什么的,怎么赋值的,所以人性化,
一般常见于,我们平常所要用的外设头文件中,所以该结构体在是stm32f4xx_gpio.h中(点到为止,该类结构体类似)
将该人性化结构体进行声明,定义之后,就可以将其传入库函数中,判断,拆解之后,直接用 寄存器结构体 操作底层寄存器,进行GPIO的初始化。
最后就可以进行GPIO的控制了,当然是在GPIOF时钟使能之后了
-----------------------这是终结线------------------------------------------
其他外设也是如此,可以去库函数中以此类推
系列文章导航:
从STM32F4的库函数分析如何实现点亮一个LED(代码存放位置)(一)
:https://blog.youkuaiyun.com/qq_33974167/article/details/89191926
从STM32F4的库函数分析如何实现点亮一个LED(代码启动)(二)
:https://blog.youkuaiyun.com/qq_33974167/article/details/89202764
从STM32F4的库函数分析如何实现点亮一个LED(点亮LED)(三)
:https://blog.youkuaiyun.com/qq_33974167/article/details/89208357