stm32f103实现流水灯(hal库)
思路
- 一、GPIO配置(led_init 函数)
- 定义一个 GPIO 初始化结构体变量
- 使能 GPIOx 的时钟
- 设置 GPIOx 某个引脚的默认电平,实现 led 一开始关闭
- 配置 GPIOx 引脚号、输入/输出方式、输出速度/输入类型
- 初始化这个GPIOx引脚,即使能
- 二、实现流水效果(main 函数)
- 需要一个 while 循环,保持程序一直运行
- 调用反转电平函数 HAL_GPIO_TogglePin(GPIOx,GPIO_PIN_x),让 led 打开
- 调用延时函数 HAL_Delay(500),让 led 保持打开 500ms
- 然后重新开始循环,led 关闭 500ms,如此重复就实现了流水灯效果
代码
void led_init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
int main(void) {
led_init();
while (1) {
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
}
}
函数分析
1. __HAL_RCC_GPIOx_CLK_ENABLE()
- 功能:GPIO端口时钟使能
- 用法:例如打开 GPIOB 时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
#define __HAL_RCC_GPIOF_CLK_ENABLE() do { \
__IO uint32_t tmpreg; \
SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPFEN);\
\
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPFEN);\
UNUSED(tmpreg); \
} while(0U)
2. void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
- 功能:设置或清除选定的数据端口位
- 参数: 1. GPIOx:其中x可以是(A…G,取决于所使用的设备)以选择GPIO外设
- GPIO_Pin:指定要写入的端口位,此参数可以是GPIO_PIN_x之一,其中x可以是(0…15)。
- PinState:指定要写入所选位的值,此参数可以是GPIO_PinState枚举值之一:
GPIO_PIN_RESET:清除端口引脚
GPIO_PIN_SET:设置端口引脚
- 用法:例如设置 GPIOB 的 5号引脚为高电平
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState){
assert_param(IS_GPIO_PIN(GPIO_Pin));
assert_param(IS_GPIO_PIN_ACTION(PinState));
if (PinState != GPIO_PIN_RESET){
GPIOx->BSRR = GPIO_Pin;
}
else{
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
}
}
3. void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
- 功能:根据GPIO_Init中的指定参数初始化GPIOx外设。
- 参数: 1. GPIOx:其中x可以是(A…G,取决于所使用的设备)以选择GPIO外设
- GPIO_Init:指向包含 指定GPIO外设的配置信息 的 GPIO_InitTypeDef 结构的指针
- 用法:例如初始化 GPIOE5
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
4. void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
- 功能:切换指定的GPIO引脚状态
- 参数: 1. GPIOx:其中x可以是(A…G,取决于所使用的设备)以选择GPIO外设
- GPIO_Pin:指定要切换的引脚。
- 用法:例如反转 GPIOE5 的电平
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin){
assert_param(IS_GPIO_PIN(GPIO_Pin));
GPIOx->ODR ^= GPIO_Pin;
}