能源网站建设方案,网推公司怎么收费,登录网站后没有转页面,专业企业网站制作怎么做输入捕获简介#xff1a; 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32 的定时器#xff0c;除了 TIM6 和 TIM7#xff0c;其他定时器都有输入捕获功能。STM32 的输入捕获#xff0c;简单的说就是通过检测 TIMx_CHx 上的边沿信号#xff0c;在边沿信号发生跳变 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32 的定时器除了 TIM6 和 TIM7其他定时器都有输入捕获功能。STM32 的输入捕获简单的说就是通过检测 TIMx_CHx 上的边沿信号在边沿信号发生跳变比如上升沿/下降沿的时候将当前定时器的值TIMx_CNT存放到对应的通道的捕获/比较寄存器TIMx_CCRx里面完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。 STM32 PWM工作过程 STM32 输入捕获工作过程通道1为例 一句话总结工作过程通过检测TIMx_CHx上的边沿信号在边沿信号发生跳变比如上升沿/下降沿的时候将当前定时器的值(TIMx_CNT)存放到对应的捕获/比较寄存器TIMx_CCRx)里面完成一次捕获。
步骤1设置输入捕获滤波器通道1为例 步骤2设置输入捕获极性通道1为例 步骤三设置输入捕获映射通道通道1为例 步骤四设置输入捕获分频器通道1为例 步骤五捕获到有效信号可以开启中断 最后看看定时器通道对应引脚TIM5为例 输入捕获通道初始化函数
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);ypedef struct
{uint16_t TIM_Channel; //捕获通道1-4 uint16_t TIM_ICPolarity; //捕获极性uint16_t TIM_ICSelection; //映射关系uint16_t TIM_ICPrescaler; //分频系数uint16_t TIM_ICFilter; //滤波器
} TIM_ICInitTypeDef;TIM5_ICInitStructure.TIM_Channel TIM_Channel_1; //选择输入端 IC1
TIM5_ICInitStructure.TIM_ICPolarity TIM_ICPolarity_Rising; //上升沿捕获
TIM5_ICInitStructure.TIM_ICSelection TIM_ICSelection_DirectTI; //映射到 TI1 上
TIM5_ICInitStructure.TIM_ICPrescaler TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_ICInitStructure.TIM_ICFilter 0x00; //IC1F0000 配置输入滤波器 不滤波
TIM_ICInit(TIM5, TIM5_ICInitStructure); //初始化 TIM5 输入捕获通道 1通道极性设置独立函数
void TIM_OCxPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity)获取通道捕获值
uint32_t TIM_GetCapture1(TIM_TypeDef* TIMx)输入捕获的一般配置步骤
1、初始化定时器和通道对应IO的时钟
初始化IO口模式为输入
GPIO_Init();
GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPD; //PA0 输入初始化定时器ARRPSC
TIM_TimeBaseInit();2、初始化输入捕获通道
TIM_ICInit();3、如果要开启捕获中断 TIM_ITConfig();NVIC_Init();4、使能定时器
TIM_Cmd();5、编写中断服务函数
TIMx_IRQHandler();更新中断和捕获中断
u8 TIM5CH1_CAPTURE_STA0; //输入捕获状态
u16 TIM5CH1_CAPTURE_VAL; //输入捕获值//定时器5中断服务程序
void TIM5_IRQHandler(void)
{ if((TIM5CH1_CAPTURE_STA0X80)0)//还未成功捕获 { if (TIM_GetITStatus(TIM5, TIM_IT_Update) ! RESET){ if(TIM5CH1_CAPTURE_STA0X40)//已经捕获到高电平了{if((TIM5CH1_CAPTURE_STA0X3F)0X3F)//高电平太长了{TIM5CH1_CAPTURE_STA|0X80;//标记成功捕获了一次TIM5CH1_CAPTURE_VAL0XFFFF;//计数器的最大值}else TIM5CH1_CAPTURE_STA;//标记有几次更新事件} }if (TIM_GetITStatus(TIM5, TIM_IT_CC1) ! RESET)//捕获1发生捕获事件{ if(TIM5CH1_CAPTURE_STA0X40) //捕获到一个下降沿 { TIM5CH1_CAPTURE_STA|0X80; TIM5CH1_CAPTURE_VALTIM_GetCapture1(TIM5);//标记成功捕获到一次高电平脉宽TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P0 设置为上升沿捕获}else //还未开始,第一次捕获上升沿{TIM5CH1_CAPTURE_STA0; //清空TIM5CH1_CAPTURE_VAL0;TIM_SetCounter(TIM5,0);TIM5CH1_CAPTURE_STA|0X40; //标记捕获到了上升沿TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //CC1P1 设置为下降沿捕获} } }TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位}main.c部分代码
#include led.h
#include delay.h
#include key.h
#include sys.h
#include usart.h
#include timer.hextern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态
extern u16 TIM5CH1_CAPTURE_VAL; //输入捕获值 int main(void){ u32 temp0; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级2位响应优先级uart_init(115200); //串口初始化为115200LED_Init(); //LED端口初始化TIM3_PWM_Init(899,0); //不分频。PWM频率72000/(8991)80KhzTIM5_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 while(1){delay_ms(10);TIM_SetCompare2(TIM3,TIM_GetCapture2(TIM3)1);if(TIM_GetCapture2(TIM3)300)TIM_SetCompare2(TIM3,0); if(TIM5CH1_CAPTURE_STA0X80)//成功捕获到了一次上升沿{tempTIM5CH1_CAPTURE_STA0X3F;temp*65536;//溢出时间总和tempTIM5CH1_CAPTURE_VAL;//得到总的高电平时间printf(HIGH:%d us\r\n,temp);//打印总的高点平时间TIM5CH1_CAPTURE_STA0;//开启下一次捕获}}}看中断部分代码时建议从下向上看从else向上看最开始初始化设置的就是上升沿捕获所以先执行最后一个else然后再进行下降沿的捕获进入if语句从而完成了一次高电平脉宽的测量若脉宽比较长在计时器溢出后还没有变为低电平则在判断是否发生更新事件若发生则执行TIM5CH1_CAPTURE_STA记录溢出的次数最大为2的6次方若TIM5CH1_CAPTURE_STA0x3f0x3f说明已达到TIM5CH1_CAPTURE_STA所能记录的最大溢出次数所以就结束捕获然后就会进入main函数进行计算高电平的脉宽。
以上是个人理解若有错误请指正