嵌入式大厂面经 STM32定时器常见面试题(持续更新中!)
这是一个嵌入式大厂面试题专栏,每天更新高频面试题。专栏将包含题目描述、详细解析、相关知识点扩展以及实际代码示例。内容涵盖操作系统、驱动开发、通信协议等核心领域,并结合实际项目经验进行分析。每道题目都会附带面试官可能的追问方向,帮助大家更好地准备面试!
STM32定时器常见面试题
STM32定时器是STM32微控制器中非常重要的外设,在嵌入式系统开发中有广泛应用。以下是STM32定时器相关的常见面试题及解答:
1. STM32定时器的基本类型
STM32系列微控制器通常包含以下几种类型的定时器:
- 基本定时器:如TIM6、TIM7只有计数功能,主要用于触发DAC和产生中断16位计数器,无捕获/比较通道
- 通用定时器:如TIM2、TIM3、TIM4、TIM516位或32位计数器(TIM2/TIM5在某些系列中是32位)多个捕获/比较通道支持PWM输出、输入捕获等功能
- 高级定时器:如TIM1、TIM816位计数器支持通用定时器的所有功能额外支持互补输出、死区控制、刹车输入等功能适用于电机控制等应用
- 低功耗定时器:如LPTIM在低功耗模式下仍可工作功能相对简单,但功耗极低
2. 定时器的基本工作原理
// 基本定时器配置示例
void TIM_BasicConfig(void) {
// 时钟使能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
// 定时器基本配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
// 使能定时器中断
TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
// 启动定时器
TIM_Cmd(TIM6, ENABLE);
}
关键参数解析
- 预分频器(PSC):对输入时钟进行分频实际分频值 = PSC + 1
- 自动重装载寄存器(ARR):定义计数器的周期计数器达到ARR值时会产生更新事件
- 计数模式:向上计数:从0计数到ARR向下计数:从ARR计数到0中心对齐模式:在0和ARR之间来回计数
3. 定时器中断计算公式
定时时间 = (PSC + 1) * (ARR + 1) / 时钟频率
例如,对于72MHz的时钟频率,要实现1ms的定时:
// 方案1:PSC=71, ARR=999 TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // ARR=999 TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // PSC=71 // 计算: (71+1)*(999+1)/72MHz = 1ms // 方案2:PSC=7199, ARR=9 TIM_TimeBaseStructure.TIM_Period = 10 - 1; // ARR=9 TIM_TimeBaseStructure.TIM_Prescaler = 7200 - 1; // PSC=7199 // 计算: (7199+1)*(9+1)/72MHz = 1ms
4. PWM输出配置
void TIM_PWM_Config(void) {
// 时钟使能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// GPIO配置
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 定时器基本配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 1000 - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// PWM配置
TIM_OCInitTypeDef TIM_OCInitStructure;
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);
}
PWM模式解析
- PWM模式1:计数器值 < CCR值时,通道输出有效电平计数器值 ≥ CCR值时,通道输出无效电平
- PWM模式2:与PWM模式1相反的输出逻辑
- 占空比计算:
5. 输入捕获配置
void TIM_IC_Config(void) {
// 时钟使能
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// GPIO配置
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 定时器基本配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// 输入捕获配置
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
// 使能捕获中断
TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);
// 启动定时器
TIM_Cmd(TIM3, ENABLE);
}
// 中断处理函数
void TIM3_IRQHandler(void) {
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) {
// 读取捕获值
uint16_t captureValue = TIM_GetCapture1(TIM3);
// 处理捕获值...
// 清除中断标志
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
}
}
输入捕获应用
- 测量脉冲宽度:
- 测量频率:
6. 高级定时器特有功能
互补输出与死区时间
void TIM_AdvancedPWM_Config(void) {
// 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// GPIO配置
GPIO_InitTypeDef GPIO_InitStructure;
// PWM输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // TIM1_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 互补输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // TIM1_CH1N
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 定时器基本配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。
查看11道真题和解析