别再死记硬背了!用这份STM32F103标准库函数速查表,快速定位GPIO、TIM、ADC等常用API
STM32F103标准库实战速查指南:按场景快速定位关键函数
刚接触STM32开发时,面对数百个库函数和复杂的寄存器配置,很多工程师都会陷入"该用哪个函数?参数怎么填?"的困境。本文不是简单的函数列表堆砌,而是从实际项目场景出发,将标准库中最常用、最易错的API按功能模块重新组织,配合典型代码片段和参数说明,让你在开发中快速找到解决方案。
1. GPIO配置:从基础操作到高级应用
GPIO是STM32开发中最基础也最常用的模块。很多新手会直接调用GPIO_SetBits/GPIO_ResetBits,却忽略了更高效的配置方式。以下按使用场景分类:
1.1 基础输入输出
- 初始化配置:必须设置时钟和引脚模式
// 启用GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; // PA5 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct);- 快速操作:
GPIO_SetBits(GPIOA, GPIO_Pin_5)输出高电平GPIO_ResetBits(GPIOA, GPIO_Pin_5)输出低电平GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET)带状态检查的写入
注意:输出模式选择
GPIO_Mode_Out_PP(推挽)还是GPIO_Mode_Out_OD(开漏)取决于驱动电路设计
1.2 中断与事件触发
外部中断配置需要联动NVIC模块:
// 配置EXTI线 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入 GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitTypeDef EXTI_InitStruct; EXTI_InitStruct.EXTI_Line = EXTI_Line0; EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; // 上升沿触发 EXTI_InitStruct.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStruct); // 配置NVIC NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x0F; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x0F; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct);2. 定时器应用:PWM生成与输入捕获
定时器是STM32最强大的外设之一,以下是两种典型场景:
2.1 PWM信号生成
配置TIM3的通道1输出PWM:
// 时钟使能 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // GPIO配置 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; // PA6对应TIM3_CH1 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // 定时器基础配置 TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_TimeBaseStruct.TIM_Period = 999; // 自动重装载值 TIM_TimeBaseStruct.TIM_Prescaler = 71; // 72MHz/(71+1)=1MHz TIM_TimeBaseStruct.TIM_ClockDivision = 0; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct); // PWM通道配置 TIM_OCInitTypeDef TIM_OCStruct; TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCStruct.TIM_Pulse = 500; // 初始占空比50% TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCStruct); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_Cmd(TIM3, ENABLE);动态调整占空比:
TIM_SetCompare1(TIM3, 750); // 修改为75%占空比2.2 输入捕获测频率
测量TIM2通道1的输入信号频率:
TIM_ICInitTypeDef TIM_ICInitStruct; TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStruct.TIM_ICFilter = 0x0; TIM_ICInit(TIM2, &TIM_ICInitStruct); // 配置捕获中断 TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE); NVIC_EnableIRQ(TIM2_IRQn); TIM_Cmd(TIM2, ENABLE);中断服务程序中计算频率:
void TIM2_IRQHandler(void) { static uint32_t last_capture = 0; if(TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) { uint32_t current_capture = TIM_GetCapture1(TIM2); uint32_t period = current_capture - last_capture; float frequency = 72000000.0 / (period * (TIM2->PSC + 1)); last_capture = current_capture; TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); } }3. ADC采样:单通道与多通道扫描
3.1 单次采样配置
ADC1通道1单次采样:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE); // GPIO配置 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStruct); // ADC配置 ADC_InitTypeDef ADC_InitStruct; ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; ADC_InitStruct.ADC_ScanConvMode = DISABLE; ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStruct.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStruct); // 通道配置 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5); ADC_Cmd(ADC1, ENABLE); // 开始转换 ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); uint16_t adc_value = ADC_GetConversionValue(ADC1);3.2 多通道DMA传输
使用DMA自动传输3个通道的采样值:
__IO uint16_t ADC_ConvertedValue[3]; // DMA配置 DMA_InitTypeDef DMA_InitStruct; DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)ADC_ConvertedValue; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStruct.DMA_BufferSize = 3; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; DMA_InitStruct.DMA_Priority = DMA_Priority_High; DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStruct); DMA_Cmd(DMA1_Channel1, ENABLE); // ADC多通道配置 ADC_InitStruct.ADC_ScanConvMode = ENABLE; ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; ADC_Init(ADC1, &ADC_InitStruct); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_55Cycles5); ADC_DMACmd(ADC1, ENABLE); ADC_Cmd(ADC1, ENABLE); // 启动连续转换 ADC_SoftwareStartConvCmd(ADC1, ENABLE);4. 通信接口:USART与SPI实战
4.1 USART中断接收
配置USART1中断接收:
// GPIO配置 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; // TX GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; // RX GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); // USART配置 USART_InitTypeDef USART_InitStruct; USART_InitStruct.USART_BaudRate = 115200; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStruct); // 使能接收中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); NVIC_EnableIRQ(USART1_IRQn); USART_Cmd(USART1, ENABLE);中断服务程序处理:
void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t data = USART_ReceiveData(USART1); // 处理接收数据 USART_SendData(USART1, data); // 回传 while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_ClearITPendingBit(USART1, USART_IT_RXNE); } }4.2 SPI全双工通信
SPI1主模式全双工通信:
// GPIO配置 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; // SCK/MISO/MOSI GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // SPI配置 SPI_InitTypeDef SPI_InitStruct; SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStruct.SPI_Mode = SPI_Mode_Master; SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStruct.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStruct); SPI_Cmd(SPI1, ENABLE); // 发送并接收数据 uint8_t SPI_Transfer(uint8_t data) { while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, data); while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); }