STM32F103标准库实战速查手册:5分钟精准定位关键函数

刚接触STM32开发时,最让人头疼的不是写代码,而是每次配置外设都要翻手册查函数名。GPIO_Init的第4个参数到底填什么?TIM_TimeBaseInit结构体里哪个字段对应分频系数?这些问题会打断开发节奏,降低效率。本文将用场景化的方式整理STM32F103最常用的标准库函数,配合典型配置代码,让你快速找到需要的函数并正确使用。

1. GPIO配置速查

GPIO是STM32开发中最基础的外设,从点亮LED到驱动复杂外设都离不开它。标准库提供了丰富的GPIO操作函数,但实际项目中常用的集中在几个核心场景。

1.1 初始化GPIO引脚

配置一个GPIO引脚需要三个步骤:使能时钟、设置参数、初始化。以下是点亮LED的典型配置(假设LED接在PA5):

// 使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;
// 配置PA5为推挽输出,速度50MHz
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

// 点亮LED
GPIO_SetBits(GPIOA, GPIO_Pin_5);

常用模式对照表:

GPIO_Mode参数 适用场景
GPIO_Mode_Out_PP 推挽输出(驱动LED等)
GPIO_Mode_Out_OD 开漏输出(I2C等)
GPIO_Mode_IN_FLOATING 浮空输入(按键检测等)
GPIO_Mode_IPU 上拉输入
GPIO_Mode_IPD 下拉输入

1.2 复用功能配置

使用USART、SPI等外设时需要配置GPIO的复用功能:

// 配置PA9为USART1_TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

关键点 :复用功能必须配合 GPIO_PinRemapConfig 使用,例如:

// 重映射USART1到PB6/PB7
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);

2. 定时器PWM生成实战

TIM定时器是STM32最复杂的外设之一,但PWM输出是电机控制、LED调光等场景的必备功能。

2.1 基础PWM配置

以下代码配置TIM3的通道1产生1kHz PWM(假设系统时钟72MHz):

// 使能TIM3时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

// 时基配置:1kHz PWM
TIM_TimeBaseStructure.TIM_Period = 999; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 71; // 分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

// PWM模式配置(通道1)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 500; // 初始占空比50%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);

// 使能预装载寄存器
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);

// 启动定时器
TIM_Cmd(TIM3, ENABLE);

2.2 动态调整占空比

运行时修改PWM占空比只需更新CCR寄存器:

// 修改TIM3通道1占空比为75%
TIM_SetCompare1(TIM3, 750);

注意 :高级定时器(TIM1/TIM8)还需要额外使能主输出:

TIM_CtrlPWMOutputs(TIM1, ENABLE);

3. ADC采样配置指南

STM32的ADC支持单次、连续、扫描等多种模式,以下是单通道采样典型配置:

3.1 单通道ADC初始化

// 使能ADC1和GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);

// 配置PA1为模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);

ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 单通道
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // 单次转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);

// 配置通道1,采样时间55.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);

// 开启ADC并校准
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));

3.2 触发采样并读取结果

// 启动转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// 等待转换完成
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
// 读取转换值
uint16_t adcValue = ADC_GetConversionValue(ADC1);

多通道采样技巧 :启用扫描模式并设置DMA传输:

// 启用扫描模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
// 配置DMA(需先初始化DMA通道)
ADC_DMACmd(ADC1, ENABLE);

4. 中断与NVIC配置精要

合理使用中断能大幅提高系统响应效率,STM32的中断配置分为外设级和NVIC级两步。

4.1 外设中断使能

以配置USART1接收中断为例:

// 使能USART1接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

常用中断标志:

外设 中断标志 触发条件
USART USART_IT_RXNE 接收寄存器非空
USART USART_IT_TXE 发送寄存器空
TIM TIM_IT_Update 定时器溢出
TIM TIM_IT_CC1 捕获/比较通道1事件
EXTI EXTI_Line0 外部中断线0

4.2 NVIC优先级配置

STM32使用4位优先级分组,建议在main()开头统一设置:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 2位抢占优先级,2位子优先级

配置USART1中断通道:

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

4.3 中断服务函数模板

void USART1_IRQHandler(void) {
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        uint8_t data = USART_ReceiveData(USART1);
        // 处理接收数据
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

关键点 :必须在中断服务函数中清除对应中断标志,否则会重复进入中断。

Logo

免费领 150 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐