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

xiaoxiao2021-02-28  74

何为输入捕捉?其实就是检测到信号跳变后,锁住计数的寄存器并保存,发生捕获事件其实相当于发生了中断,可以根据相应的标志位来判断当前捕获了什么,其实捕获什么无非就是上升沿、下降沿! 关于捕捉的更多信息请参考官方的手册,个人觉得手册上讲的还是很容易懂得,因为寄存并不多! 下面我针对我的 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);这个函数是用来就是用来记录当前发生触发事件时的计数,这样我们可以利用每一次触发获得计数值计算触发事件之间的时间,最简单的应用就是占空比的获取,我们可以获得高电平的持续时间!

输入捕捉其实就这么简单,我建议只要了解流程就能明白,之所以代码写的少,是因为我觉得输入捕捉的概念比程序重要!希望先完完全全的明白输入捕捉,个人觉得编程没问题!
转载请注明原文地址: https://www.6miu.com/read-78704.html

最新回复(0)