stm32定时器输入捕获pwm

时间:2021-11-13 23:21:36

花了两天时间终于把stm32f103的定时器输入捕获弄懂了,这里以TIM3的通道ch1为例,要实现输入捕获需要配置一下寄存器,TIMx_ARR,TIMx_PSC,TIMx_CCMR1,TIMx_CCER,TIMx_DIER,TIMx_CR1,TIMx_CCR1.这里抓取了一些收据手册中寄存器描述的图

下面一一介绍:

TIMx_ARR寄存器为自动重装载的值

TIMx_CR1这里了只要用到它的第0位即使能位。

TIMx_CCMR可以配置对应通道映射到那个IC,TI。

stm32定时器输入捕获pwm

这里我们是第一通道故只需配置低8位,cc1s为配置ch1映射到那个TI,IC1PSC为配置是否分频,1c1f为配置是否滤波。

stm32定时器输入捕获pwm

TIMx_psc寄存器

stm32定时器输入捕获pwm

stm32定时器输入捕获pwm

TIMx_DIER寄存器如下图:

stm32定时器输入捕获pwm

第0位为更新中断使能位,即定时器值更新时产生的中断,第一1c通道发生捕获时间中断使能位。

下面附上程序:(注意下面程序用的是ch2)

void timer3init()
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能TIM3时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟

GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_7;  //PA7 清除之前设置  
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PA7 输入  
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_7);//PA7 上拉

TIM3->ARR=0XFFFF;  //设定计数器自动重装值   
TIM3->PSC=71;  //预分频器 

TIM3->CCMR1|=0X0100;//CC1S=01 选择输入端 IC2映射到TI2上
 // TIM3->CCMR1|=0<<4; //IC1F=0000 配置输入滤波器 不滤波
// TIM3->CCMR1|=0<<10; //IC2PS=00 配置输入分频,不分频 


TIM3->CCER|=0X0010; //CC1P=0 上升沿捕获
// TIM3->CCER|=1<<0; //CC1E=1 允许捕获计数器的值到捕获寄存器中


TIM3->DIER|=0X005;   //允许捕获中断
// TIM3->DIER|=1<<0;   //允许更新中断
// TIM3->CR1|=0x01;    //使能定时器2
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 

TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC2,ENABLE);//允许更新中断 ,允许CC1IE捕获中断

    TIM_Cmd(TIM3,ENABLE ); //使能定时器3
}
 
void TIM3_IRQHandler(void)

  if((TIM3CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{  
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) 
{    
if(TIM_GetCapture1(TIM3)==0xffff)
TIM3CH1_CAPTURE_STA++;
}
}
  if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)//捕获1发生捕获事件
{
printf("icc2");
val2=TIM_GetCapture1(TIM3);
TIM3CH2_CAPTURE_STA=0;//清空
TIM3CH2_CAPTURE_VAL=0;
TIM_SetCounter(TIM3,0);
TIM3CH2_CAPTURE_STA|=0X80;//标记捕获到了上升沿  
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2|TIM_IT_Update); //清除中断标志
}
}