何为输入捕捉?其实就是检测到信号跳变后,锁住计数的寄存器并保存,发生捕获事件其实相当于发生了中断,可以根据相应的标志位来判断当前捕获了什么,其实捕获什么无非就是上升沿、下降沿!

关于捕捉的更多信息请参考官方的手册,个人觉得手册上讲的还是很容易懂得,因为寄存并不多!


下面我针对我的STM32f103VBT6来进一步了解输入捕捉模式!


我选择定时器TIM4,它对应的输入捕捉有很多通道,其实就是TIM4对应的IO口!我这里设置3个输入捕捉的通道,分别是PB6 PB7 PB8  对应CH1 CH2 CH3  通道,这个根据芯片手册是有对应关系的(除了重映射,这个先别管)!


第一步:初始化函数void TIM4_Cap_Init(unsigned int arr,unsigned int psc){}


这个函数代码如下:
void TIM4_Cap_Init(unsigned int arr,unsigned int psc)
{
        //这些都是一些结构体的声明,去下载一本库函数手册一看就知道 很简单的 
      GPIO_InitTypeDef GPIO_InitStructure;
      TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_ICInitTypeDef  TIM4_ICInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;


        //这个就是时钟使能了 我使能TIM4 和GPIOB
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);


        //输入捕捉,当然端口要设置为输入模式了
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);

TIM_TimeBaseStructure.TIM_Period = arr;  //这个就是设置计数值的最大值,就是这个寄存器能计多少个数,一般设置成0XFFFF
TIM_TimeBaseStructure.TIM_Prescaler =psc;  //上面这个计数寄存器的频率的分频系数 分频的值=psc+1 所以你要2分频的话,psc= 1,以此类推
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分割 这在有一些情况用,这里我们不受影响 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //计数向上计数 
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);  //初始化
  
TIM4_ICInitStructure.TIM_Channel = TIM_Channel_1;             //选择通道1
 TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;  //上升沿触发还是下降沿触发的设置
TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TT1上
 TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;        //配置输入分频 不分频
 TIM4_ICInitStructure.TIM_ICFilter = 0x01;                        //滤波的问题 先不管
 TIM_ICInit(TIM4, &TIM4_ICInitStructure);

TIM4_ICInitStructure.TIM_Channel = TIM_Channel_2;               
  TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; 
  TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 
  TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;       
  TIM4_ICInitStructure.TIM_ICFilter = 0x01; 
  TIM_ICInit(TIM4, &TIM4_ICInitStructure);

TIM4_ICInitStructure.TIM_Channel = TIM_Channel_3;                
  TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;  
  TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 
  TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;       
  TIM4_ICInitStructure.TIM_ICFilter = 0x01;    
  TIM_ICInit(TIM4, &TIM4_ICInitStructure);



//中断设置
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4发生中断 其实就是上面发生你设置上升沿和下降沿触发事件
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占中断等级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         //从中断等级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道Ü
NVIC_Init(&NVIC_InitStructure);  //初始化 

TIM_ITConfig(TIM4,TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3,ENABLE);//使能各个中断

        TIM_Cmd(TIM4,ENABLE ); //使能定时器TIM4
}


第二步:中断程序:


void TIM4_IRQHandler(void)

    if(TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET) //CH1通道(PB6)发生触发事件
   { 
     /* 处理代码 **/
    }
 
   if(TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET) //CH2通道(PB7)发生触发事件
   { 
     /* 处理代码 **/
    }


   if(TIM_GetITStatus(TIM4, TIM_IT_CC3) != RESET) //CH3通道(PB8)发生触发事件
   {  
       /* 处理代码 **/
    }
 
 

    TIM_ClearITPendingBit(TIM4, TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3); //清楚中断标志
 
}


特别说明TIM_GetCapture1(TIM4);这个函数是用来就是用来记录当前发生触发事件时的计数,这样我们可以利用每一次触发获得计数值计算触发事件之间的时间,最简单的应用就是占空比的获取,我们可以获得高电平的持续时间!

【STM32F103攻城笔记】输入捕捉实战



输入捕捉其实就这么简单,我建议只要了解流程就能明白,之所以代码写的少,是因为我觉得输入捕捉的概念比程序重要!希望先完完全全的明白输入捕捉,个人觉得编程没问题!

相关文章:

  • 2022-12-23
  • 2021-08-04
  • 2022-12-23
  • 2021-09-30
  • 2021-09-10
  • 2021-08-18
  • 2021-12-11
  • 2022-01-24
猜你喜欢
  • 2021-04-25
  • 2022-12-23
  • 2022-02-08
  • 2021-05-14
  • 2021-07-07
  • 2021-08-22
  • 2022-12-23
相关资源
相似解决方案