一、Boot配置
内存地址是固定的,代码从0x0000 0000开始,而数据从0x2000 0000开始,F4支持三种不同的boot模式
复位芯片时,在SYSCLK的第4个上升沿BOOT引脚值被锁存,STM32F407通过此时BOOT[1:0]引脚值选择Boot模式
BOOT1 | BOOT0 | mode | description |
---|---|---|---|
x | 0 | Main Flash | 从flash区域boot |
0 | 1 | System memory | 从系统存储区boot |
1 | 1 | Embedded SRAM | 从内置SRAM区域boot |
二、GPIO
每一个GPIO端口通过四个32位的配置寄存器、两个32位的数据寄存器、一个32位置/复位寄存器、一个32位的锁存寄存器和两个32位的复用功能寄存器进行工作
2.1 介绍
有以下特性
- 输出状态:推挽、开漏、上下拉
- 通过ODR或外设输出数据
- 输入状态:浮空、上下拉、模拟
- 通过IDR或外设输入数据
- 通过LCKR锁存端口
- 通过BSRR实现对ODR的位操作
STM32F4的GPIO端口可通过软件进行配置
2.2 特性
- 推挽输出
具有驱动能力强的特点,使用IC内部高电平 - 开漏输出
输出高电平由外部上拉电阻决定,用于匹配电平,由于存在上升时间,一般选择下降沿输出;只能输出低电平;可将多个开漏输出连接到一条线上,通过一只上拉电阻形成线与功能。 - 复用推挽和开漏
复用是指GPIO不作为普通I/O使用,而是由内部设备直接驱动。 - 四种输入模型
- 浮空输入:完全取决于外部电路,与CPU内部无关,会出现抖动
- 下拉输入:外部输入为低电平时,读取为低电平;外部无输入以及输入高电平时读取高电平
- 上拉输入:外部输入为高电平时,读取为高电平;外部无输入以及输入低电平时读取低电平
- 模拟输入:连接内部ADC模块
不使用的引脚推荐设置为模拟模式,以降低功耗和避免干扰
注意:STM32F407单个引脚最大拉电流和灌电流不超过25mA
三、必备API
3.1 哪些是必备API
- 上电复位进入
startup_stm32f407xx.s
,执行复位中断服务程序 - 复位中断服务程序里面执行
SystemInit
,此函数在system_stm32f4xx.c
里面 - 调用编译器封装函数进入
main
函数 - HAL库初始化函数
HAL_Init
,在stm32f4xx_hal.c
文件中 - 系统时钟初始化,用到文件
stm32f4xx_hal_rcc.c
- 各外设标准库文件
3.2 点亮LED
板载两颗LED,分别在PA6引脚和PA7引脚。这里给出板载LED驱动文件bsp_led.c
,代码如下
#include "bsp.h"
/*
*********************************************************************************************************
* Func Statement
*
* 板载两颗LED,LED1是PA6引脚,LED2是PA7引脚,低电平点亮,高电平熄灭
*********************************************************************************************************
*/
/* private define */
#define LED_GPIO_CLK_ALLENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define GPIO_PORT_LED1 GPIOA
#define GPIO_PIN_LED1 GPIO_PIN_6
#define GPIO_PORT_LED2 GPIOA
#define GPIO_PIN_LED2 GPIO_PIN_7
/*
**********************************************************************************
* @brief 配置板载LED
* @param None
* @return None
* @use
**********************************************************************************
*/
void bsp_InitLed()
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
/* 开启GPIO端口时钟 */
LED_GPIO_CLK_ALLENABLE();
/* 初始熄灭LED */
GPIO_PORT_LED1->BSRR = GPIO_PIN_LED1;
GPIO_PORT_LED2->BSRR = GPIO_PIN_LED2;
/* 配置LED */
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Pin = GPIO_PIN_LED1;
HAL_GPIO_Init(GPIO_PORT_LED1, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_LED2;
HAL_GPIO_Init(GPIO_PORT_LED2, &GPIO_InitStructure);
}
/*
**********************************************************************************
* @brief 点亮指定LED
* @param __no:LED序号,范围 1 - 2
* @return None
* @use
**********************************************************************************
*/
void bsp_LedOn(uint8_t __no)
{
__no--;
if(__no == 0)
{
GPIO_PORT_LED1->BSRR = (uint32_t)GPIO_PIN_LED1 << 16U;
}
else if(__no == 1)
{
GPIO_PORT_LED2->BSRR = (uint32_t)GPIO_PIN_LED2 << 16U;
}
}
/*
**********************************************************************************
* @brief 熄灭指定LED
* @param __no:LED序号,范围 1 - 2
* @return None
* @use
**********************************************************************************
*/
void bsp_LedOff(uint8_t __no)
{
__no--;
if(__no == 0)
{
GPIO_PORT_LED1->BSRR = GPIO_PIN_LED1;
}
else if(__no == 1)
{
GPIO_PORT_LED2->BSRR = GPIO_PIN_LED2;
}
}
/*
**********************************************************************************
* @brief 翻转指定LED
* @param __no:LED序号,范围 1 - 2
* @return None
* @use
**********************************************************************************
*/
void bsp_LedToggle(uint8_t __no)
{
if(__no == 1)
{
GPIO_PORT_LED1->ODR ^= GPIO_PIN_LED1;
}
else if(__no == 2)
{
GPIO_PORT_LED2->ODR ^= GPIO_PIN_LED2;
}
}
同时bsp_led.h
文件代码如下
#ifndef __BSP_LED_H
#define __BSP_LED_H
/* public statement */
void bsp_InitLed();
void bsp_LedOn(uint8_t __no);
void bsp_LedOff(uint8_t __no);
void bsp_LedToggle(uint8_t __no);
#endif
延时函数使用HAL自带的HAL_Delay()
即可