stm32f103 整 理笔记
在正式复习stm32f1103之前 ,我们得新整 理一下,方便以后看日记
引脚功能:
GPIO_MODE_INPUT 浮空输入: 引脚电平完全由外部决定,悬空时电平乱跳。用于按键、传感器、外部信号输入。 GPIO_MODE_OUTPUT_PP 推挽输出: 能直接输出强高低电平,驱动能力强。用于LED、蜂鸣器、继电器、普通控制。 GPIO_MODE_OUTPUT_OD 开漏输出: 只能拉低电平,高电平要靠外部上拉,可多芯片共用总线。用于I2C、1-Wire、电平转换。 GPIO_MODE_AF_PP 复用推挽: 给串口、PWM、SPI等外设用,强驱动输出。用于串口TX、PWM输出、SPI时钟。 GPIO_MODE_AF_OD 复用开漏: 给外设开漏用,只能拉低,需上拉。用于硬件I2C的SDA/SCL。 GPIO_MODE_AF_INPUT 复用输入: 给外设专用输入口。用于串口RX、SPI输入、定时器捕获。 GPIO_MODE_ANALOG 模拟模式: 只测电压,不走数字信号。用于ADC采样、模拟信号输入。
1. 什么是 MSP?
它的核心工作,就是给单片机的各种外设(比如串口、定时器、GPIO、中断这些)做最基础的初始化:
- 给外设开时钟(相当于给外设通电,不通电外设没法干活)
- 配置外设用到的 GPIO 引脚(比如串口要用到 TX/RX 两个引脚,得先把这俩脚设成串口模式)
- 配置外设相关的中断(比如串口接收数据要触发中断,得先把中断打开、设好优先级)
举个例子:你要用串口(USART)发数据,HAL 库会先自动调用串口的 MSP 函数,把串口的时钟、引脚、中断都配置好,再执行发数据的功能,不用你手动去管这些底层操作。
2. MSP 的调用逻辑
- 程序从
main()函数开始运行 - 先执行
HAL_Init(),初始化 HAL 库的基础环境 - 自动调用
HAL_MspInit(),这就是全局的 MSP 初始化入口 - 后续你初始化某个具体外设(比如串口、SPI)时,HAL 库会自动调用对应外设的 MSP 函数,完成该外设的底层配置
编写第一个示例,点亮一个灯,首先打开stmcubeMx 选中芯片型号 ,选择我们当下用的是gpio8,和9 开发板是立创星空学习板

需要用stmcubeMx 创立工程, 选中型号 然后配置引脚 gpio 8 gpio 9 ,因为我们要做点亮灯,默认要高电平,所以要配置为高电平 ,推换推出,由于是输出,下上拉无意义,这儿不用管, 如果设低电平,默认灯就亮了,好像也不是不行,这儿其实任意哈,,,
关于stmcubeMx 要下载6.14.1,老版有很多坑,传说6.15也有乱码的坑,所以还是选6.14.1 老版本的坑比如中文乱码问题 ,配置的时钟与实际硬件运行频率不一致(差一半、翻倍),如果用低本遇到需要解决中文乱码可以先增加一个环境变量,
选择新建,在变量名和变量值如下如下内容 变量名称: JAVA_TOOL_OPTIONS 变量值:-Dfile.ecoding=UTF-8 修改完成后,全部点确定。然后重启stm32CubeMX软件即可。
配置好工程后,可以用kial 或vscode 找开项目,在maian.c 写引脚 代码,完成第一个示例
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); // led1 熄灭
HAL_Delay(500); // 延时500ms
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); // led1 点亮
HAL_Delay(500); // 延时500ms
}
/* U
这儿我们可以看到软件工作文件目录,需要介绍一下, stm32f1xx.it 是中断函数的编写地方,
stm32f1xx.hal.map.c 是核心底层配置的地方,stm32f1xx_hal_msp.c。 是 STM32CubeMX 自动生成, MSP = MCU Support Package,MCU 底层支撑配置
专门存放所有外设的底层硬件初始化:比如以下配置
- 开启外设时钟(GPIO、UART、ADC、TIM 等)
- 配置引脚复用功能
- 配置 NVIC 中断
- 配置 DMA(如果用到)
所有
HAL_XXX_MspInit()统一放在这里。以下这个文件的代码片断,可能总结为main.c 虽然也有配置,他是基于这个文件的配置,这个文件才是操作硬 件的配置
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
__HAL_RCC_USART1_CLK_ENABLE(); // 开时钟
// 配置GPIO、NVIC等
}
其它文件的分布,如下,

常见方法介绍:
main.c 文件中常用方法介绍:
HAL_Init() 初始化项目和初始化hal 库 ,项目第一句代码,不要在HAL_Init()之前调用任何外设相关的代码,否则会出奇怪的 bug。
SystemClock_Config() 配置时钟,CubeMX 生成的工程里,这个函数会自动写好,一般不用自己改。时钟 没 配置对,外设波特率、定时器、延时都会出错。
MX_GPIO_Init() 这个函数是 CubeMX 生成的,里面会调用HAL_GPIO_Init()。帮你一次性配置好所有引脚的输入 / 输出模式、上下拉电阻、速度等。不要在这个函数里手动写引脚操作代码, 否则重新生成工程会被覆盖。
HAL_GPIO_WritePin() 控制 GPIO 引脚输出高 / 低电平。给引脚 “发信号”,比如让 LED 亮 / 灭、给模块发指令。
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // PA5输出高电平 参数介绍,第一个参数,那一组引脚 ,第二个参数,这组引脚中那个编号 第三个参数,高还是低电平
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // PA5输出低电平
HAL_Delay() 毫秒级延时函数,让程序 “等一会儿再往下走” 这个延时是阻塞的,延时期间程序什么都做不了,游戏里用多了会卡顿。高优先级中断会打断延时,导致实际延时时间变长。
HAL_Delay_Us()(或自定义微秒延时) 功能同上,只是时间不同
其它以后才用到的函数
HAL_GPIO_ReadPin() 读取 GPIO 引脚的电平状态,判断按键是否按下。
HAL_GPIO_TogglePin() 翻转 GPIO 引脚的电平状态(高变低、低变高)。
HAL_TIM_Base_Start() / HAL_TIM_Base_Start_IT() 启动定时器,用来做定时任务、PWM、游戏帧率控制。
HAL_TIM_PWM_Start() 启动定时器的 PWM 输出,用来驱动蜂鸣器、电机、LED 呼吸灯。
在正式写代码前,先了解一下软件环境 ,比如中文支持,界面样式,在kail5 的 edit 有一个 Configuration菜单,里面有软件相关配置

编译流程:
我们在写代码的时候,有部份代码是给编译器看的,比如以下的注解:

一个完成的功能包装封,包括功能封装,示例 我们要点灯,并且要把功能封装成来。
第一步,核心代码是
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // PA5输出高电平 参数介绍,第一个参数,那一组引脚 ,第二个参数,这组引脚中那个编号 第三个参数,高还是低电平 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // PA5输出低电平
封装:
我们们gpio.c 写函数本身 在gpio.h 需要爆露出宏定义和函数名,方便主函数据调用
gpio.c 新增二个函数功能代码,一个是功能函数,一个是测试函数
void LED_Control(uint8_t device, uint8_t cmd) { GPIO_PinState state = cmd ? GPIO_PIN_RESET : GPIO_PIN_SET; if(device == LED1) HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, state); else if(device == LED2) HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, state); }
测试函数:
void LED_Test(void) { LED_Control(LED1,ON); LED_Control(LED2,OFF); HAL_Delay(500); LED_Control(LED1,OFF); LED_Control(LED2,ON); HAL_Delay(500); }
载图如下 :

其它写法参考:
void LED_Control(uint8_t device, uint8_t cmd)
{
switch(device)
{
case LED1: HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, cmd ? 0 : 1); break;
case LED2: HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, cmd ? 0 : 1); break;
}
}
最后主函数调用:

以下功能通常 蜂鸣器 接触器 开发都是一样,通过调节电平来控制,所以基础控制电位的的功能先不介结了,以下开始研究按健扫描
中断模式
要使中断的话,意思是事件,比如我们要绑定在gpio 让这个按扭中低变平或高电平发生时,运行一个函数就叫中断,中断还可以帮在定时器到点,按健被 按下等场
示例一
第一在stm32cubeMx中 将一下gpio绑定于引脚 为中断模式

然后在gpio 的配置中配置一下什么条件触发

还差一步,使其使能,这一步完成后就可以ai 可以写代码了

000000000000000000000

浙公网安备 33010602011771号