什么是STM32?
STM32是STMicroelectronics(意法半导体)推出的一系列基于ARM Cortex-M内核的32位Flash微控制器。它们因高性能、低功耗、易于编程和广泛的外设集成而广泛应用于各种嵌入式系统项目中。
使用设备: STM32F103C6T6
我的 keil 装的是 C51 所以这里用 VS code 中 PlatformIO 建立工程 配置参考 博主 ODF..https://blog.csdn.net/DOF526570/article/details/130115865
添加一些配置 platformIO官方文档 stm32https://docs.platformio.org/en/latest/platforms/ststm32.html
[env:genericSTM32F103C6]
platform = ststm32
board = genericSTM32F103C6
framework = stm32cube
upload_protocol = stlink //用stlink 下载
upload_speed = 961200 //下载波特率设置
在src文件夹下创建main文件并上传测试
控制pc13 io 电平变化
库相关资料:
stm32f1xx_ll_gpio.h
和stm32f1xx_hal_gpio.h
都是STM32F1系列微控制器的GPIO驱动库,但它们在设计理念、使用方式和性能方面有所不同。以下是两者的对比:1. 设计理念
- HAL库 (
stm32f1xx_hal_gpio.h
):
- 硬件抽象层:HAL库提供了一个高度抽象的接口,使得开发者可以更容易地使用GPIO功能,而不需要深入了解底层硬件细节。
- 易用性:HAL库提供了丰富的函数和结构体,简化了GPIO的配置和操作。
- 可移植性:HAL库设计为跨平台使用,可以在不同的STM32系列之间轻松移植代码。
- LL库 (
stm32f1xx_ll_gpio.h
):
- 低层抽象:LL库提供了一个更接近硬件的接口,允许开发者更精细地控制GPIO引脚。
- 灵活性:LL库提供了更多的配置选项,适合需要高性能和精细控制的应用。
- 性能:由于减少了抽象层,LL库在某些情况下可以提供更好的性能。
2. 功能和使用
- HAL库 (
stm32f1xx_hal_gpio.h
):
- 数据结构:
GPIO_InitTypeDef
:用于初始化GPIO引脚的结构体,包含引脚编号、模式、速度等配置参数。- 函数:
HAL_GPIO_Init
:初始化GPIO引脚。HAL_GPIO_DeInit
:反初始化GPIO引脚。HAL_GPIO_WritePin
:设置GPIO引脚的输出电平。HAL_GPIO_ReadPin
:读取GPIO引脚的输入电平。HAL_GPIO_TogglePin
:切换GPIO引脚的输出电平。HAL_GPIO_LockPin
:锁定GPIO引脚的配置,防止后续修改。- LL库 (
stm32f1xx_ll_gpio.h
):
- 数据结构:
GPIO_TypeDef
:定义了GPIO端口的寄存器结构。- 函数:
LL_GPIO_Init
:初始化GPIO引脚。LL_GPIO_DeInit
:反初始化GPIO引脚。LL_GPIO_SetOutputPin
:设置GPIO引脚的输出电平。LL_GPIO_ResetOutputPin
:重置GPIO引脚的输出电平。LL_GPIO_TogglePin
:切换GPIO引脚的输出电平。LL_GPIO_GetInputPinState
:读取GPIO引脚的输入电平。LL_GPIO_SetPinMode
:设置GPIO引脚的模式(输入、输出等)。LL_GPIO_SetPinSpeed
:设置GPIO引脚的速度。LL_GPIO_SetPinPull
:设置GPIO引脚的上拉/下拉电阻。3. 性能和效率
- HAL库:
- 执行效率:由于增加了抽象层,HAL库在某些情况下可能不如LL库高效。
- 代码体积:HAL库通常会产生较大的代码体积,因为它提供了更多的功能和抽象。
- LL库:
- 执行效率:LL库由于减少了抽象层,通常具有更高的执行效率。
- 代码体积:LL库产生的代码体积通常较小,因为它提供了更少的抽象和更直接的硬件访问。
4. 使用场景
- HAL库:
- 初学者:适合初学者和需要快速开发项目的开发者,因为HAL库提供了简单易用的接口。
- 跨平台开发:适合需要在不同STM32系列之间移植代码的项目。
例程:
#include "stm32f1xx_hal.h" void GPIO_Init(void) { // 初始化GPIO __HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟 GPIO_InitTypeDef GPIO_InitStruct = {0}; // 配置GPIOA第0引脚为输出模式 GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 设置GPIOA第0引脚为高电平 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); }
- LL库:
- 高性能应用:适合需要高性能和精细控制的应用,如实时控制系统。
- 经验丰富的开发者:适合熟悉硬件细节和需要优化性能的开发者。
例程:
#include <stm32f1xx_ll_gpio.h> #include <stm32f1xx_ll_bus.h> void GPIO_Init(void) { // 使能GPIOA时钟 属于stm32f1xx_ll_bus.h 库中函数 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); // 配置GPIOA第0引脚为输出模式 属于stm32f1xx_ll_gpio.h 中 LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_0, LL_GPIO_MODE_OUTPUT); LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_0, LL_GPIO_SPEED_FREQ_LOW); LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_0, LL_GPIO_OUTPUT_PUSHPULL); LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_0, LL_GPIO_PULL_NO); // 设置GPIOA第0引脚为高电平 LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_0); }
这里我们随便选一个库使用 驱动pc13 引脚
- GPIOA:PA0 到 PA15
- GPIOB:PB0 到 PB15
- GPIOC:PC0 到 PC15
- GPIOD:PD0 到 PD15
#include <stm32f1xx_ll_gpio.h>
#include <stm32f1xx_ll_bus.h>
#include <stm32f1xx_ll_rcc.h>
#include <stm32f1xx_ll_system.h>
void GPIO_Init(void)
{
// 使能GPIOC时钟
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);
// 配置GPIOC第13引脚为输出模式
LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_13, LL_GPIO_MODE_OUTPUT); // 设置引脚模式为输出
LL_GPIO_SetPinSpeed(GPIOC, LL_GPIO_PIN_13, LL_GPIO_SPEED_FREQ_LOW); // 设置引脚最大输出速度为低速
LL_GPIO_SetPinOutputType(GPIOC, LL_GPIO_PIN_13, LL_GPIO_OUTPUT_PUSHPULL); // 设置引脚输出类型为推挽输出
LL_GPIO_SetPinPull(GPIOC, LL_GPIO_PIN_13, LL_GPIO_PULL_DOWN); // 设置引脚上拉/下拉电阻为下拉
LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_13);// 设置引脚电平为低电平
//对于我使用的设备 这条控制显然是多余的,因为其已经内部下拉了,默认电平为低电平
}
int main(void)
{
GPIO_Init();
while(1)
{
// 防止程序意外终止
}
}
设备电路图中可以得到
输出电平是由
LL_GPIO_SetOutputPin
和LL_GPIO_ResetOutputPin
函数控制的。
我们上述代码已经拉低了PC13 IO 所以 运行效果为