15.输入捕获

文章详细介绍了STM32中的输入捕获功能,用于测量脉宽和频率,通过配置库函数步骤实现定时器初始化、中断设置,并提供了实验示例,利用TIM5通道1检测高电平脉冲并打印时间。
摘要由CSDN通过智能技术生成

1.输入捕获介绍:

  • STM32除了基本定时器(定时器6和定时器7)之外,其他的都具有输入捕获功能;
  • 输入捕获可以对输入的信号的上升沿、下降沿或双边沿进行捕获,通常用于测量输入信号的脉宽、测量PWM输入信号的频率及占空比;
  • 首先将捕获到t1信号之后将CNT的值进行清零,清零之后并且下一次捕获是下降沿,将捕获极性设置为下降沿捕获;到达t2时,就会发生捕获事件,得到此时的CNT的值,将t2的值记为CCRx2,将(t2-t1)*T(计数频率的周期)=溢出时间;当在t1到t2时间内,可能高电平时间脉冲比较长,有可能定时器会产生溢出,如果溢出就会产生溢出中断,在溢出中断中用变量累计溢出的次数N,N*ARR=溢出次数;溢出次数*一次的值=N次溢出累计的时间;(N*ARR+CRRx2)=t1到t2的时间。

 2.输入捕获库函数配置步骤:

定时器相关库函数在stm32f10x_tim.c和stm32f10x_tim.h文件中;
  1. 使能定时器及端口时钟,并设置引脚模式等:RCC_APB1PeriphClockCmd()和GPIO_Init();
  2. 初始化定时器参数,包含自动重装载值,分频系数,计数方式等:void TIM_TimeBaseInit();
  3. 设置通用定时器的输入捕获参数,开启输入捕获功能;void TIM_ICInit()、TIM_OC1PolarityConfig();
  4. 开启捕获和定时器溢出(更新中断):void TIM_ITConfig();
  5. 设置定时器中断优先级,使能定时器中断通道;
  6. 编写定时器中断服务函数;
  7. 使能定时器:void TIM_Cmd();

3.输入捕获实验:

实现功能:实验定时器TIM5的CH1检测输入信号高电平脉冲,将检测的高电平脉冲时间通过printf函数打印出来,同时让LED0指示灯不断闪烁表示系统正常运行。

(1)原理图:

(2)主函数: 

#include "delay.h"
#include "led.h"
#include "usart1.h"
#include "input.h"



int main(){
    
    u8 i=0;                                          
    u32 indata=0;                                        //累计整个从上升沿到下降沿的次数
   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      //设置分组
    delay_init();                                        //延时初始化
    LED_Init();  
    usart1_Init(9600);                                   //串口通信初始化
    TIM5_CH1_Input_Init(0xffff,72-1);                    //输入捕获->定时器3通道1初始化
   
    while(1){
       if((TIM5_CH1_CAPTURE_STA&0x80))                   //判断捕获是否完成->这里表示完成 
       {
          indata=TIM5_CH1_CAPTURE_STA&0x3f;              //得到溢出次数
          indata*=0xffff;                                //将所有溢出次数换算成计数的次数
          indata+=TIM5_CH1_CAPTURE_VAL;
          printf("高电平持续时间:%d us\r\n",indata);
          TIM5_CH1_CAPTURE_VAL=0;                        //开启下一次捕获
            
       }
       
       i++;
       if(i%20==0)
       {
          LED0=!LED0;
       }

        delay_ms(20);
    }       
}

(3)头文件:

#ifndef __INPUT_H
#define __INPUT_H

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;

extern u8 TIM5_CH1_CAPTURE_STA;
extern u16 TIM5_CH1_CAPTURE_VAL;


void TIM5_CH1_Input_Init(u16 arr,u16 psc);         //输入捕获->定时器5通道1初始化


#endif

(4)输入捕获功能函数:

#include "stm32f10x.h"
#include "input.h"



/*
   功能:输入捕获->定时器5通道1初始化
   变量:arr:自动重装载值     psc:预分频系数
   返回值:
*/
void TIM5_CH1_Input_Init(u16 arr,u16 psc)
{
   GPIO_InitTypeDef GPIO_InitStruct;
   TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
   TIM_ICInitTypeDef TIM_ICInitStruct;
   NVIC_InitTypeDef NVIC_InitStruct;
   
   //1.使能定时器和端口时钟,并设置引脚模式;
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);     //使能端口时钟
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);      //使能定时器时钟
   
   GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;                 //输入下拉
   GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;                     //PA0
   GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
   GPIO_Init(GPIOA,&GPIO_InitStruct);
      
   //2.定时器初始化
   TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;      //1分频
   TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;  //计数模式->向上计数
   TIM_TimeBaseInitStruct.TIM_Period=arr;                      //自动重装载值
   TIM_TimeBaseInitStruct.TIM_Prescaler=psc;                   //预分频系数
   TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStruct);
   
   //3.设置通用定时器的输入捕获,开启输入捕获功能
   TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;                 //设置为通道1
   TIM_ICInitStruct.TIM_ICFilter=0x00;                         //滤波器长度->不使用滤波
   TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;      //捕获极性->上升沿捕获
   TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;            //1分频
   TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;  //映射->直接映射
   TIM_ICInit(TIM5,&TIM_ICInitStruct);
   
   //4.开启捕获和定时器溢出中断
   TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);
   
   //5.设置定时器中断优先级,使能定时器中断通道
   NVIC_InitStruct.NVIC_IRQChannel=TIM5_IRQn;                  //设置中断通道
   NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;                     
   NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;        //抢占优先级
   NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;               //子优先级
   NVIC_Init(&NVIC_InitStruct);
   
   //6.使能定时器
   TIM_Cmd(TIM5,ENABLE);
     
}



/*
   功能:中断服务函数
   变量:无
   返回值:无
   注意:
      如果捕获到了上升沿再到下一次捕获到下降沿就完成了一次捕获,让TIM5_CH1_CAPTURE_STA最高位 置1,
      如果捕获到上升沿让TIM5_CH1_CAPTURE_STA的次高位 置1,
      将TIM5_CH1_CAPTURE_STA剩下的6位,累计溢出次数;


*/

u8 TIM5_CH1_CAPTURE_STA=0;      //输入捕获状态
u16 TIM5_CH1_CAPTURE_VAL=0;     //输入状态值

void TIM5_IRQHandler(void)
{
   /*注意:处理完第一次捕获成功的数据之后,才能处理下一次捕获的数据*/
   if((TIM5_CH1_CAPTURE_STA&0x80)==0)              // TIM5_CH1_CAPTURE_STA的最高位为0时->未捕获完成
   {
      if(TIM_GetITStatus(TIM5,TIM_IT_Update))      //溢出中断
      {
         if((TIM5_CH1_CAPTURE_STA&0x40))           //已经捕获到上升沿
         {
            if((TIM5_CH1_CAPTURE_STA&0x3f)==0x3f)        //判断当STA后六位全为1时,累计次数已满
            {
               TIM5_CH1_CAPTURE_STA|=0x80;         //将TIM5_CH1_CAPTURE_STA最高位设置为1,表示捕获成功
               TIM5_CH1_CAPTURE_VAL=0xffff;        //将TIM5_CH1_CAPTURE_VAL设置为最大;
            }
            else                                   //当STA后六位不全为1时,说明还没有累计完
            {
               TIM5_CH1_CAPTURE_STA++;
            } 
         }  
      } 
      
      if(TIM_GetITStatus(TIM5,TIM_IT_CC1))                  //捕获中断
      {
         if((TIM5_CH1_CAPTURE_STA&0x40))                    //当STA次高位为1时,说明捕获到上升沿
         {
            TIM5_CH1_CAPTURE_STA|=0x80;                     //设置STA最高位为1;表示捕获成功
            TIM5_CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);     //将定时器5通道1的比较值赋值给VAL
            TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_High);    //设置捕获极性为上升沿捕获->为下一次捕获做准备
         }
         else                                               //当STA的次高位不为1时,则没有捕获到上升沿
         {
            TIM5_CH1_CAPTURE_STA=0;
            TIM5_CH1_CAPTURE_VAL=0;
            TIM_SetCounter(TIM5,0);                         //清零计数器的值
            TIM5_CH1_CAPTURE_STA|=0x40;                     //第一次捕获到上升沿时,将STA的次高位设置为1
            TIM_OC1PolarityConfig(TIM5,TIM_OCPolarity_Low); //设置捕获极性为下降沿捕获
               
         }  
      } 
   }
   
   TIM_ClearITPendingBit(TIM5,TIM_IT_Update|TIM_IT_CC1);                                 //清除定时器标志位       
 
}



(6)实验结果:

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jhan;

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值