32-TIM输入捕获
注意与输出比较区分。
频率测量方法
测频法实现:例如使用红外传感器,每个上升沿计次加一,再用一个定时器,定1S的定时中断,在中断里,每隔一秒取一下计次值,同时清零计次,所计的值就是频率。
主从触发模式(TRGO、TRGI)
主模式将定时器内部的引脚映射到TRGO,用于触发别的外设。
从模式接受其他外设的信号,用于控制自身定时器的运行。
GPIO的输入信号,经滤波器和极性选择,TI1FP1信号兵分两路,CNT的值转运到CCR中,同时CNT清零(从模式完成)。
PWMI使用两个通道,可以同时测量频率和占空比,CCR2是高电平期间的CNT的计数值,CCR1是整个周期的计数值,那么使用CCR2/CCR1就能得到占空比,使用CCR1可以得到频率。
代码
在PA0产生一个PWM信号,然后PA6进行输入捕获,测量输入信号的占空比、频率。
void PWM_Init() { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); TIM_InternalClockConfig(TIM2);//选择使用内部时钟 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period=100 -1; //ARR 自动重装载 在这里固定ARR的值为100,下面利用单独的函数修改PSC的值 TIM_TimeBaseInitStruct.TIM_Prescaler=720 -1; //PSC 预分频器 TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);//配置时基单元 TIM_OCInitTypeDef TIM_OCInitStruct; TIM_OCStructInit(&TIM_OCInitStruct); TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; TIM_OCInitStruct.TIM_Pulse=50; //CCR TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable; TIM_OC1Init(TIM2,&TIM_OCInitStruct); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //如果想用片上外设(这里是定时器)来控制引脚,需要使用复用推挽开漏输出模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); TIM_Cmd(TIM2,ENABLE);//使能定时器 } void PWM_TIM_SetCompare1(uint16_t Compare) //重新写入CCR的值 { TIM_SetCompare1(TIM2,Compare); } void PWM_SetPSC(uint16_t PSC) //重新写入PSC的值 { TIM_PrescalerConfig(TIM2,PSC,TIM_PSCReloadMode_Immediate); }
首先,需要打开GPIOA和复用功能时钟的使能,以及TIM2时钟的使能。
然后,需要初始化PA0口为复用推挽输出模式。
接着,需要初始化TIM2的基本定时器参数,包括自动重装值、分频系数、时钟分割和计数模式等。
接下来,需要初始化TIM2的PWM输出参数,包括PWM模式、输出使能、极性和初始占空比等。
最后,需要使能TIM2。
在主函数中调用两个独立函数分别设置CCR和PSC的值,这样,就可以在PA0口产生一个占空比为50%,频率为1KHZ的PWM信号了。
接下来写输入捕获部分的代码(根据上图)
第一步开启GPIO和TIM时钟
第二步GPIO初始化,配置成输入模式
第三步配置时基单元,让CNT在内部时钟的驱动下自增运行
第四步配置输入捕获单元,包括滤波器、极性、直连还是交叉通道、分频器等参数
第五步选择从模式的触发源,并选择触发之后的操作,用于复位
最后开启定时器即可
void IC_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); TIM_InternalClockConfig(TIM3);//选择使用内部时钟 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period=65536 -1; //ARR 自动重装载 TIM_TimeBaseInitStruct.TIM_Prescaler=720 -1; //PSC 预分频器 TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);//配置时基单元 TIM_ICInitTypeDef TIM_ICInitStruct; TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; // TIM_ICInitStruct.TIM_ICFilter=0xF; //滤波 TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising; //上升沿触发 TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1; //不分频 TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI; //选择直连通道 TIM_ICInit(TIM3,&TIM_ICInitStruct); TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1); TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset); TIM_Cmd(TIM3,ENABLE); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律