STM32通用定时器输入捕获实验

本章要实现的功能是:

通过 TIM5 的通道 1(PA0)捕获外界输入信号的高电平脉宽,通过 printf 打印

捕获的高电平时间,DS0 指示灯不断闪烁表示系统正常运行。

开发步骤

(1)使能定时器及端口时钟,并设置引脚模式等 因为输入捕获也是通用定时器的一个功能,所以需要使能相应定时器时钟。 由于输入捕获通道是对应着 STM32F1 芯片的 IO 口,所以需要使能对应的端口时 钟,并将对应 IO 口设置为输入模式功能。例如本章输入捕获实验,我们是使用 TIM5 的 CH1 通道来测量输入信号的脉宽,因此需要使能 TIM5 时钟,调用的库函 数如下: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);//使能 TIM5 时 钟 而 TIM5 的 CH1 通道对应的管脚是 PA0,在 STM32F1 芯片数据手册引脚功能上 都有介绍如下: 所以需要使能 GPIOA 端口时钟。因为我们使用 PA0 来测量输入信号的高电平 时间,因此需要将 PA0 配置为下拉输入模式。GPIO 初始化如下: 1. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//管脚设置 2. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//设置下拉输入模式 3. GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化结构体 (2)初始化定时器参数,包含自动重装值,分频系数,计数方式等 要使用定时器功能,必须对定时器内相关参数初始化,其库函数如下: voidTIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); 这个在定时器中断章节就已经介绍。 (3)设置通用定时器的输入捕获参数,开启输入捕获功能 初始化定时器后,需要设置对应输入捕获通道参数,比如输入通道、滤波、 分频系数、映射关系、捕获极性等。输入捕获参数初始化函数如下: void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct); 函数的第一个参数相信大家一看就清楚,是用来选择定时器的。第二个参数 是一个结构体指针变量,同样我们看下这个结构体 TIM_ICInitTypeDef 成员变 量: 1. typedef struct 2. { 3. uint16_t TIM_Channel; //通道 4. uint16_t TIM_ICPolarity; //捕获极性 5. uint16_t TIM_ICSelection;//映射 6. uint16_t TIM_ICPrescaler;//分频系数 7. uint16_t TIM_ICFilter; //滤波器长度 8. } TIM_ICInitTypeDef; TIM_Channel:输入捕获通道设置,通用定时器每个多达 4 个通道,假如我 们使用 TIM5 的通道 1,参数为 TIM_Channel_1。 TIM_ICPolarity:输入信号的有效捕获极性设置,假如我们需要对输入信号 上升沿开始捕获,参数为 TIM_ICPolarity_Rising,如果是下降沿捕获,参数为 TIM_ICPolarity_Rising。库函数内还提供了单独设置通道捕获极性的函数,假 如要修改 TIM5 的通道 1 捕获极性为下降沿,函数如下: TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); 此函数可以理解为通用函数 TIM_OCxPolarityConfig(),函数中的 x 表示通 道,所以如果是对通道 2 捕获极性操作,可以调用 TIM_OC2PolarityConfig 函数。 TIM_ICSelection:映射设置,在“定时器中断实验”章节中,我们分析了 通用定时器结构框图,知道 ICx 可以映射到 2 个 TIx 上,比如 IC1 可以直接映射 到 TI1 上,也可以间接映射到 TI2 上,但是不能映射到 TI3 和 TI4 上。假如我们 直接映射在 TI1 上,参数为 TIM_ICSelection_DirectTI。 TIM_ICPrescaler:分频系数设置,分频系数可以为 TIM_ICPSC_DIV1、 TIM_ICPSC_DIV2、TIM_ICPSC_DIV4、TIM_ICPSC_DIV8,假如我们不分频,参数为 TIM_ICPSC_DIV1。 TIM_ICFilter:滤波长度设置,假如我们不使用滤波器,参数为 0。 如果我们需要配置 TIM5 的通道 1 为输入捕获功能,并且为上升沿捕获、不 分频、直接映射到 TI,可以如下配置: 1. TIM_ICInitTypeDef TIM_ICInitStructure; 2. TIM_ICInitStructure.TIM_Channel=TIM_Channel_1; //通道 1 3. TIM_ICInitStructure.TIM_ICFilter=0x00; //滤波 4. TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//捕获极性 5. TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; //分频系数 6. TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//直接映射到 TI1 7. TIM_ICInit(TIM5,&TIM_ICInitStructure); (4)开启捕获和定时器溢出(更新)中断 假如我们需要检测输入信号的高电平脉宽,就需要在第一次上升沿到来时捕 获一次,然后设置为下降沿捕获,等到下降沿到来时又捕获一次。如果输入信号 的高电平脉宽比较长,那么定时器就可能溢出,所以需要对定时器溢出进行处理, 否则计算的高电平时间将不准。所以需要开启定时器溢出中断。 对定时器中断类型和使能设置的函数如下: void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); 假如我们要开启 TIM5 的捕获中断和定时器溢出中断,调用函数如下: TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE); (5)设置定时器中断优先级,使能定时器中断通道 在上一步我们已经使能了定时器的捕获和更新中断,只要使用到中断,就必 需对 NVIC 初始化,NVIC 初始化库函数是 NVIC_Init(),这个在前面讲解 STM32 中断时就已经介绍过,不清楚的可以回过头看下。 (6)编写定时器中断服务函数 最后我们还需要编写一个定时器中断服务函数,通过中断函数处理定时器产 生的相关中断。定时器中断服务函数名在 STM32F1 启动文件内就有,TIM5 中断 函数名如下: TIM5_IRQHandler 因为定时器的中断类型有很多,所以进入中断后,我们需要在中断服务函数 开头处判断是哪种类型,根据不同中断类型完成相应功能,比如我们需要在捕获 中断内完成捕获成功记录,更新中断内完成溢出次数的累计。在中断结束时要清 除中断标志,这些在前面定时器中断实验中都有介绍。 库函数中用来读取定时器中断状态标志位的函数如下: ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT); 清除中断标志位的函数如下: void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT); 当进入第一次捕获中断,我们会先清空计数器内值,例如对 TIM5 计数器值 清空,函数如下: TIM_SetCounter(TIM5,0); //定时器初值为 0 (7)使能定时器 前面几个步骤已经将定时器输入捕获配置好,但还不能正常使用,只有开启 定时器了才能让它正常工作,开启定时器的库函数如下: void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); 例如我们要开启 TIM5,那么调用此函数如下: TIM_Cmd(TIM5,ENABLE); //开启定时器 将以上几步全部配置好后,我们就可以正常使用定时器输入捕获功能了

input.h+input.c

main.c

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值