概述
单个定时器的多个通道可以捕获不同的方波信号
1.初始化配置
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //通道选择
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿触发
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //管脚与寄存器对应关系
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入预分频。意思是控制在多少个输入周期做一次捕获,如果//输入的信号频率没有变,测得的周期也不会变。比如选择4分频,则每四个输入周期才做一次捕获,这样在输入信号变化不频繁的情况下,
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
一定要分开写,切记不可TIM_ICInitStructure.TIM_Channel = TIM_Channel_2|TIM_Channel_3; 会出问题
2.原理
先配置上升沿触发
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;位置一
清零CNT计数器TIM_SetCounter(TIM2,0);
并且设置下降沿触发
位置二
下降沿触发进入,捕获此时CNT IIM2_CH2ReadValue1 = TIM_GetCounter(TIM2);
并且设置上升沿触发
位置三
上升沿触发进入,捕获此时CNT IIM2_CH2ReadValue2 = TIM_GetCounter(TIM2);
此时利用IIM2_CH2ReadValue1,IIM2_CH2ReadValue2 计算频率占空比
循环进入位置一
两个通道需要交替进行捕获,否则由于一个TIM只有一个CNT计数器,第一个上升沿清零会混乱
这就需要另一个定时器计时分配捕获时间
if(capture_time>=100)//100ms
{
if(TIM_CaptureNumber==2)
TIM_CaptureNumber=3;//通道三捕获
else if(TIM_CaptureNumber==3)
TIM_CaptureNumber=2;
capture_time=0;//通道二捕获
}
下面以TIM2的CH2、CH3通道演示
初始化代码
__IO uint16_t IIM2_CH2ReadValue1 = 0, IIM2_CH2ReadValue2 = 0,
IIM2_CH3ReadValue1 = 0, IIM2_CH3ReadValue2 = 0;
__IO uint16_t IIM2_CH2CaptureNumber = 0,IIM2_CH3CaptureNumber=0;
__IO uint32_t IIM2_CH2Freq = 0,IIM2_CH3Freq=0;
u8 TIM_CaptureNumber=2;
//__IO uint32_t Capture = 0;
//__IO uint32_t TIM2Freq = 0;
float TIM2_Duty2;
float TIM2_Duty3;
void pwm2_capture_init(void)
{
TIM_ICInitTypeDef TIM_ICInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM2 channel 2 pin (PA.01,02) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOA and GPIOB clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
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(TIM2, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;//一定要与TIM_Channel_2分开写
TIM_ICInit(TIM2, &TIM_ICInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_CC3, ENABLE);
}
定时器中断捕获代码
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
{
/* Clear TIM2 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
if(TIM_CaptureNumber==2)
{
if(IIM2_CH2CaptureNumber == 0)
{
TIM_SetCounter(TIM2,0);
TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Falling);
IIM2_CH2CaptureNumber = 1;
}
else if(IIM2_CH2CaptureNumber == 1)
{
/* Get the Input Capture value */
IIM2_CH2ReadValue1 = TIM_GetCounter(TIM2);
TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);
IIM2_CH2CaptureNumber=2;
}
else if(IIM2_CH2CaptureNumber == 2)
{
/* Get the Input Capture value */
IIM2_CH2ReadValue2 = TIM_GetCounter(TIM2);
IIM2_CH2Freq = (uint32_t)SystemCoreClock/IIM2_CH2ReadValue2;
TIM2_Duty2= IIM2_CH2ReadValue1*100 /IIM2_CH2ReadValue2;
IIM2_CH2CaptureNumber=0;
}
}
}
if(TIM_GetITStatus(TIM2, TIM_IT_CC3) == SET)
{
/* Clear TIM2 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
if(TIM_CaptureNumber==3)
{
if(IIM2_CH3CaptureNumber == 0)
{
TIM_SetCounter(TIM2,0);
TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Falling);
IIM2_CH3CaptureNumber = 1;
}
else if(IIM2_CH3CaptureNumber == 1)
{
/* Get the Input Capture value */
IIM2_CH3ReadValue1 = TIM_GetCounter(TIM2);
TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising);
IIM2_CH3CaptureNumber=2;
}
else if(IIM2_CH3CaptureNumber == 2)
{
/* Get the Input Capture value */
IIM2_CH3ReadValue2 = TIM_GetCounter(TIM2);
IIM2_CH3Freq = (uint32_t)SystemCoreClock/IIM2_CH3ReadValue2;
TIM2_Duty3= IIM2_CH3ReadValue1*100 /IIM2_CH3ReadValue2;
IIM2_CH3CaptureNumber=0;
}
}
}
}
定时器分配捕获时间
void TIM4_IRQHandler(void)
{
static u8 capture_time;
if (TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET)
{
capture_time++;
if(capture_time>=100)//100ms
{
if(TIM_CaptureNumber==2)
TIM_CaptureNumber=3;
else if(TIM_CaptureNumber==3)
TIM_CaptureNumber=2;
capture_time=0;
}
}
}
最后
以上就是拉长篮球为你收集整理的stm32 单个定时器多路捕获测量频率与占空比(排坑)的全部内容,希望文章能够帮你解决stm32 单个定时器多路捕获测量频率与占空比(排坑)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复