资讯动态

STM32 定时器 输入捕获

发布时间:2026/10/19 6:45:46 来源:尧图企业网站定制
用于测频率测占空比IC(Input Capture)输入捕获输入捕获模式下当通道输入引脚出现指定电平跳变上升沿/下降沿时会让当前CNT的值将被锁存到CCR中可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数每个高级定时器和通用定时器都拥有4个输入捕获通道基本定时器没有输入捕获功能可配置为PWMI模式同时测量频率和占空比PWMI是PWM输入模式专门为测量PWM频率和占空比设计的可配合主从触发模式实现硬件全自动测量如上图左下角的三个输入连接在一个异或门当3个输入引脚有任何一个有电平翻转时输出引脚就产生一次电平反转输出通过数据选择器到达输入捕获通道1数据选择器可以选择上面或者下面一个不通过异或门设计这个异或门是为三相无刷电机服务的无刷电机有3个霍尔传感器检测转子位置可以根据转子的位置进行换相有了这个异或门3个通道就可以连接上无刷电机的霍尔传感器。输入滤波、边沿检测可以选择高电平触发、低电平触发当出现指定的电压时边沿检测电路就会触发后续电路执行动作有两套输入滤波、边沿检测电路通道一可以输出TI1FP1和TI1FP2去了IC2通道二也可以输出TI2FP1去了IC1和TI2FP2。可以灵活切换输入可以把一个引脚的输入映射到两个捕获单元第一个捕获通道使用上升沿触发用来捕获周期第二个通道使用下降沿触发捕获占空比两通道同时对一个引脚进行捕获就可以同时测量频率和占空比。通道3、4也是一样可以选择各自独立连接或者进行交叉。TRC信号在图上部分连接预分频器对输入的信号分频分频后的信号触发捕获电路进行工作每来一个触发信号CNT的值就会向CCR转运一次转运的同时发生一个捕获事件该事件会在状态寄存器置标志位同时也可以产生中断CCR捕获到的置就是公式里的NCNT清零可以使用主从触发模式来自动完成。CCMR1寄存器里的ICF位可以控制滤波器的参数滤波器工作原理在CCMR1寄存器一节边沿检测器捕获上升沿或者下降沿用CCER寄存器里的CC1P位可以选择极性最终得到TI1FP1触发信号通过数据选择器应当还有一条一样的电路得到TI1FP2的触发信号连通到通道2IC2CC1S位可以对数据选择器进行选择ICPS位可以配置分频器。选择不、2、4、8分频CC1E位控制输出使能或失能为方便下一次计数将CNT里的值捕获到CCR里面后清零CNT方便下一次捕获如何自动清零CNTTI1FP1信号和TI1的边沿信号都可以通向从模式控制器从模式里面有电路可以自动完成CNT清零频率测量上图是一个频率逐渐降低的方波波形左边频率最高右边最低只有高低电平的数字信号STM32只能测量数字信号如果要测量正弦波那则还需要搭建一个信号预处理电路最简单的就是用运放搭建一个比较器将正弦波转换为数字信号再输入给STM32即可。如果测量的电压信号非常高还要考虑隔离问题比如隔离放大器电压互感等元件隔离高压端和低压端保证电路安全。频率测量方法测周法用已知的标准频率fc的计次时钟来驱动计数器计算连续的两个上升沿之间的间隔时间从一个上升沿开始计计数器从0开始一直计到下一个上升沿停止计一个数的时间是1/fc计N个数时间是N/fcN/fc是周期fc/N则为周期。测频法适合测量高频信号测量结果更新慢数值相对稳定测周法适合测量低频信号测量结果更新快数值跳变快波动大存在正负1误差测频法在闸门时间内可能有的周期信号不完整比如在最后的时间周期才出现一半闸门时间就到了测周法在最后时刻一个数计到一半周期就结束了要减小误差就要增大N的值结合两个公式将N消掉得到两个方法误差相同时的频率中界频率当待测信号小于中界频率时测周法误差更小当待测信号大于中界频率时测频法误差更小。总结输入捕获基本结构这个结构只使用了1个通道只能测频率注意只有通道CH1、CH2可以使用从模式自动清零CNT通道CH3、CH4只能开启捕获中断来手动清零比较消耗软件资源。PWMI基本结构PWMI模式使用了两个通道捕获一个引脚可以同时测量周期和占空比。TI1FP1配置为上升沿触发触发CCR1捕获CNT值测量周期和清零CNT。TI1FP2配置为下降沿触发触发CCR2捕获CNT值。可以测量到高电平持续的时间计算占空比。测频法代码实现使用计数器每来一个上升沿计次加1再用定时器定一个1s的定时中断在中断里每隔1s取计数器的值同时清零计次为下一次做准备。输入捕获测频率 代码实现产生PMW波PSC和ARR都可以调节频率但是占空比CCR/ARR1通过调节ARR调节频率还会影响到占空比因此先固定ARR用PSC决定频率CRR控制占空比//用于单独设置PSC的值TIM_PSCReloadMode指定重装模式 /** TIM_PSCReloadMode的值可以是 TIM_PSCReloadMode_Update: The Prescaler is loaded at the update event.预分频器在更新事件重装周期结束时切断 TIM_PSCReloadMode_Immediate: The Prescaler is loaded immediately.预分频器立即重装可能在值改变时产生切断波形的现象比如一个周期还没完就直接切断了 **/ void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);时钟源频率为72Mhz频率 Freq 时钟源频率 / PSC1/ARR1占空比 Duty CCR /CCR1IC输入捕获配置书写初始化函数RCC开启GPIO和TIM时钟GPIO初始化配置GPIO为输入模式一般选择上拉或者浮空输入配置时基单元配置输入捕获单元包括滤波器、极性、直连通道还是交叉通道、分频器选择从模式的触发源选择为TI1FP1选择触发之后要执行的操作执行Reset最后调用TIM_Cmd函数启动定时器相关函数学习//初始化IC一次只能配一个通道四个IC通道共用这个函数 void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); /** TIM_ICInitStructure结构体参数解释 TIM_ICInitStructure.TIM_Channel TIM_Channel_1; //选择配置定时器通道1 TIM_ICInitStructure.TIM_ICFilter 0xF; //输入滤波器参数可以过滤信号抖动 TIM_ICInitStructure.TIM_ICPolarity TIM_ICPolarity_Rising; //极性选择为上升沿触发捕获 TIM_ICInitStructure.TIM_ICPrescaler TIM_ICPSC_DIV1; //捕获预分频选择不分频每次信号都触发捕获 TIM_ICInitStructure.TIM_ICSelection TIM_ICSelection_DirectTI; //输入信号交叉选择直通不交叉 **/ //可配置两个通道把外设电路配置成PWMI模式 void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); //给输入捕获结构体赋初始值 void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct); //选择输入触发源TRGI从模式的触发源选择 void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource); //选择输出触发源TRGO主模式输出的触发源 void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource); //选择从模式从模式的选择 void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode); //分别单独配置通道1、2、3、4的分频器 void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); //输出比较模式下CCR只写TIM_SetCompare1写入 //输入捕获模式下CCR只读TIM_GetCapture1读 //分别写入4个通道的CCR void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1); void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2); void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3); void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4); //分别读取4个通道的CCR uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx); uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx); uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx); uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑