1. 前言
在前一章,讲解了 GPIO 端口,但是似乎有个函数没有解释,如下:
// 开启LED相关的GPIO外设时钟
RCC_APB2PeriphClockCmd( LED1_GPIO_CLK, ENABLE);
原因在于这个函数并不是在 GPIO 库文件中,而是属于 RCC(reset clock control)库文件。
另外上一章也表明了,如果你对 STM32 GPIO 口的寄存器内容并不了解,但是通过官方提供的库文件,我们就可以不了解寄存器,就能编写一个完整的程序。
同样这章还要讲解的是 STM32 的编译流程。
2. STM32 编译流程
在学习 C 语言的时候,我们都知道 main 函数是一个项目文件的入口。但是是谁在调用 main 函数呢?
在 STM32 中,由 startup_stm32f10x_hd.s 文件来调用 main 函数。startup_stm32f10x_hd.s 是一个汇编程序,原因如下:
(大约103行)
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors */
bl __libc_init_array
/* Call the application's entry point.*/
bl main 调用 main函数
bx lr
上文就是调用了main函数,但是很明显上文还调用了 SystemInit ,这个也是函数,却比 main 函数先调用,因为这个函数是用来设置 STM32 全局时钟,也就是我们所说的 STM32 稳定频率 75Mhz。
SystemInit 函数位于 system_stm32f10x.c 文件中。如图:
该函数中含有大量的寄存器操作,这个并不适合新手,但是建议看看。
3. RCC 库文件
这一章并没有明显得编程代码,主要是对上一节关于时钟部分进行解析。
#define LED_GPIO_CLK RCC_APB2Periph_GPIOB
/* 开启 LED 相关的 GPIO 外设时钟 */
RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE);
上问中有个词语 APB2,这个是 STM32 的一个总线,同一等级的还有 AHB 和 APB1。所以总线上有哪些资源是不一样的。比如 GPIOB 是挂载在 APB2 总线上的。那这些对于一个新手,不是很难辨别吗?但是库函数提供了一些提示,如下图:
但是很多并不是常用的,常用的如下:
APB1
|-RCC_APB1Periph_DAC
|-RCC_APB1Periph_I2C1
|-RCC_APB1Periph_I2C2
APB2
|-RCC_APB2Periph_ADC1
|-RCC_APB2Periph_ADC2
|-RCC_APB2Periph_ADC3
|-RCC_APB2Periph_GPIOA
|-RCC_APB2Periph_GPIOB
|-RCC_APB2Periph_GPIOC
|-RCC_APB2Periph_GPIOD
|-RCC_APB2Periph_GPIOE
|-RCC_APB2Periph_GPIOF
|-RCC_APB2Periph_GPIOG
|-RCC_APB2Periph_SPI1
|-RCC_APB2Periph_USART1
同样不同的总线,时钟开启的方法并不相同,这个就是RCC的函数方法:
1.使能 AHB 相关的端口时钟
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
2.使能 APB1 相关的端口时钟
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
3.使能 APB2 相关的端口时钟
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
到这里就结束了。