单片机 | STM32F429IGT6启动文件解析及示例代码
编程步骤
- 开GPIO端口时钟(RCC AHB1 外设时钟使能寄存器 (RCC_AHB1ENR))
- 要先确定引脚号
- 要确定是输入还是输出
- 如果是输出,那么是推挽还是开漏输出 OTYPER
- 确定是上拉还是下拉
- 那么输出速度是多少呢?
配置IO(LED)
void GPIO_LED_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//打开LED_GPIO的时钟
RCC_AHB1PeriphClockCmd(LED_R_GPIO_CLK, ENABLE);
//选定LED_GPIO,就是具体的引脚
GPIO_InitStruct.GPIO_Pin = LED_R_GPIO_PIN;
//配置输出
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
//配置推挽输出
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
//配置上拉
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
//配置输出速度
GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed;
//初始化LED_GPIO口
GPIO_Init(LED_R_GPIO_PORT, &GPIO_InitStruct);
}
可避免文件在多个文件中重复定义
#ifndef _BSP_KEY_H
#define _BSP_KEY_H
//代码编写部分
#endif /*_BSP_KEY_H*/
配置IO(按键检测)
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//打开KEY_GPIO的时钟
RCC_AHB1PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);
//选定KEY_GPIO,就是具体的引脚
GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN;
//配置输入模式
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
//配置下拉
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
//初始化GPIO口
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct);
}
位带操作:(AHB2和AHB3不能实现位带操作(不在范围内))
SRAM和片上外设均有1MB的位带区,位带区里面的每一个位都可以通过位带别名区的地址来访问。位带区一位,对
应位带别名区的四个字节。
SRAM位带区地址 0X2000 0000~0X200F 0000
SRAM位带别名区地址 0X2000 0000~0X23FF FFFF
外设位带区与外设位带别名区的地址转换:
AliasAddr=0X4200 0000+(A-0X4000 0000)*8*4+n*4
SRAM位带区和SRAM位带别名区的地址转换:
AliasAddr=0X2200 0000+(A-0X2000 0000)*8*4+n*4
A:表示我们要操作的那个位所在的寄存器的地址
n:位号
要点:位带区的一个位在位带别名区会被膨胀成四字节
外设与SRAM位带区与位带别名区的地址转换:
统一地址:((addr&0XF000 0000)+0x0200 0000+((addr&0x000F FFFF)<<5)+(bitnum<<2))
addr:要操作的位所在寄存器的地址
bitnum:位号
启动文件作用
- 初始化堆栈指针SP(SP=_initial_sp)
- 初始化PC指针,指向复位程序(初始化PC 指针=Reset_Handler)
- 初始化中断向量表
- 配置系统时钟(SystemInit()函数配置时钟)
- 调用C 库函数_main 初始化用户堆栈,从而最终调用main 函数去到C 的世界(第一个启动的是__main函数)
向量表
- 向量表实际是一个32位的整型数组,一个元素对应一个异常(ESR),数组元素存的就是ESR的入口地址。
- 向量表在复位后从FLASH的0地址(存储器重映射)开始。
Stack栈
用于局部(全局)变量、函数调用、函数形参的开销
Heap堆
堆用于动态内存的分配,malloc函数