TIM的输入捕获

时间:2024-05-19 15:48:11

输入捕获原理及配置步骤

 

一、输入捕获概念

  STM32的输入捕获,简单的说就是通过检测 TIMx_CHx (定时器X的通道X)上的 边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT) 存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等。 

二、输入捕获流程:

 

输出比较模式的配置步骤: 

1. 选择计数器时钟(内部,外部,预分频器)。 

2. 将相应的数据写入TIMx_ARR和TIMx_CCRx寄存器中。 

3. 如果要产生一个中断请求,设置CCxIE位。

4. 选择输出模式,例如: 

─ 要求计数器与CCRx匹配时翻转OCx的输出引脚,设置OCxM=011 

─ 置OCxPE = 0禁用预装载寄存器

─ 置CCxP = 0选择极性为高电平有效

─ 置CCxE = 1使能输出 5

. 设置TIMx_CR1寄存器的CEN位启动计数器

三、输入捕获程序设计步骤:

设置 TIM3 时钟和的 GPIOC 端口霍尔捕获(连接引脚 06、07、08):

1)开启 TIM3 时钟和 GPIOC 时钟,重映射PC 6、7、8

 

要使用 TIM3,我们必须先开启 TIM3 的时钟以及输入的GPIO引脚。这里我们还要配置 PC6、7、8 为浮空输入

GPIO_Init()

{  

  GPIO_InitTypeDef        GPIO_InitStructure;

  GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);

    GPIO_StructInit(&GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7| GPIO_Pin_8;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

 

    GPIO_Init(GPIOC, &GPIO_InitStructure);

}

2)初始化 TIM3,设置 TIM3 的 ARR 和 PSC

在开启了 TIM3 的时钟之后,我们要设置 ARR 和 PSC 两个寄存器的值来设置输入捕获的自动重装载值和计数频率。

TIM_TimeBaseInit()

{  

TIM_TimeBaseInitTypeDef    TIM_TimeBaseInitStructure;
TIM_DeInit(HALL_TIMER);  
TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM 向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化 Tim3
}

3)设置 TIM3 的输入比较参数,开启输入捕获

输入比较参数的设置包括映射关系,滤波,分频以及捕获方式等。这里我们需要设置通道 1 为输入模式,且 IC1 映射到 TI1(通道 1)上面,并且使用滤波(提高响应速度)器,上升沿捕获。

参数设置结构体 TIM_ICInitTypeDef 的定义: 

typedef struct
{
uint16_t TIM_Channel;    //用来设置通道

uint16_t TIM_ICPolarity;  //用来设置输入信号的有效捕获极性

uint16_t TIM_ICSelection;  //映射

uint16_t TIM_ICPrescaler;     //配置输入分频

uint16_t TIM_ICFilter;           //滤波

} TIM_ICInitTypeDef; 

缺省值配置( TIM_ICStructInit(&TIM_ICInitStructure); 

TIM的输入捕获

配置程序:

TIM_ICInit

{

TIM_ICInitTypeDef TIM3_ICInitStructure;

TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1;             //选择输入端 IC1 映射到TI1 上
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;          //上升沿捕获
TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1 上 
TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;                 //配置输入分频,不分频
TIM3_ICInitStructure.TIM_ICFilter = 0x0B;                                          //IC1F=1011 配置输入滤波器

TIM_ICInit(TIM3, &TIM3_ICInitStructure); 
}

4)使能捕获和更新中断(设置 TIM3 的 DIER 寄存器)


//TIM3 预分频重载模式,预分频值立即填装(PSC)

    TIM_PrescalerConfig(TIM3, PSCTIM_PSCReloadMode_Immediate); 


    TIM_InternalClockConfig(TIM3);  //设置TIM3内部时钟

    TIM_SelectHallSensor(TIM3, ENABLE); //使能霍尔传感器接口

    TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);  //经滤波定时器输入1


//选中触发信号(TRGI)的上升沿重初始化计数器并触发寄存器的更新

    TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);   

 

//生成单一的脉冲:计数器在下一个更新事件停止

    TIM_UpdateRequestConfig(TIM3, TIM_UpdateSource_Regular); 

 

5)设置中断分组,编写中断服务函数

中断矢量配置

    NVIC_InitTypeDef        NVIC_InitHALLStructure;

    NVIC_InitHALLStructure.NVIC_IRQChannel = TIM3_IRQChannel;

    NVIC_InitHALLStructure.NVIC_IRQChannelPreemptionPriority = TIMx_PRE_EMPTION_PRIORITY; //先占优先级

    NVIC_InitHALLStructure.NVIC_IRQChannelSubPriority = TIMx_SUB_PRIORITY;//从优先级

    NVIC_InitHALLStructure.NVIC_IRQChannelCmd = ENABLE; 

    NVIC_Init(&NVIC_InitHALLStructure);

    TIM_ClearFlag(HALL_TIMER, TIM_FLAG_Update + TIM_FLAG_CC1 + TIM_FLAG_CC2 + \

                  TIM_FLAG_CC3 + TIM_FLAG_CC4 + TIM_FLAG_Trigger + TIM_FLAG_CC1OF + \

                  TIM_FLAG_CC2OF + TIM_FLAG_CC3OF + TIM_FLAG_CC4OF);  //清除标志位

    TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC1,ENABLE);//开中断

    TIM_SetCounter(HALL_TIMER, HALL_COUNTER_RESET); //计数器重置

接着是 TIM3_IRQChannel 中断通道对应的中断服务子程序的编写:

void TIM3_IRQHandler(void)

{

……………………………………

……………………………………

}

6)使能定时器

  TIM_Cmd(TIM3,ENABLE);