历史上的今天
返回首页

历史上的今天

今天是:2024年09月23日(星期一)

正在发生

2019年09月23日 | stm32库函数学习篇---通用定时器(输入捕获功能)

2019-09-23 来源:eefocus

实现功能:PA8随意延时驱动led灯闪烁,并且将PA8用杜邦线连接到PA7口,PA7是通用定时器TIM3的2通道,在TIM3_CH2触发中断程序中取反连接到PD2口的led灯,指示中断程序运行,并且每次进入中断后改变触发捕获的极性。实现两个led灯会交替闪烁。


先有必要了解stm32定时器的输入触发模块,如下图:

需要注意的是,一眼望去一个定时器似乎有8个通道,左边四个,右边四个,但其实左边和右边是共用相同的IO引脚,所以名称标注是一模一样。也就是说,每个通用定时器都只有四个独立通道,当某一通道作为了输入触发功能那就不能再作为输出匹配功能。这一点我们也可以从其他地方找到印证。比如TIM_ITConfig()函数中如下:

image.png?imageView2/2/w/550

Enables or disables the specified TIM interrupts.

Parameters:

image.png?imageView2/2/w/550

我们可以看到此函数TIM_IT参数的取值范围如下:


TIM_IT_Update: TIM update Interrupt source


TIM_IT_CC1: TIM Capture Compare 1 Interrupt source


TIM_IT_CC2: TIM Capture Compare 2 Interrupt source


TIM_IT_CC3: TIM Capture Compare 3 Interrupt source


TIM_IT_CC4: TIM Capture Compare 4 Interrupt source


TIM_IT_COM: TIM Commutation Interrupt source


TIM_IT_Trigger: TIM Trigger Interrupt source


TIM_IT_Break: TIM Break Interrupt source


也就是说每个通道的捕获和比较功能是共用一个中断标志。


stm32定时器输入触发功能其实挺简单的,与AVR单片机几乎一样。就是单片机引脚上一旦出现一个有效边沿(可以配置为上升、下降或者上升下降均触发),那么定时器计数器CNT里面的值就会被相应的Capture/Compare X Register保存下来。这里X可以是1,2,3,4任何一个。并且中断标志位被置位。但是此时TIM的计数寄存器CNT却不管这一事件的发生,继续自己的计数。此功能可以用来测量外部信号的脉宽或者是周期。


对于定时器的时基单元TIM_TimeBaseStructure就不作说明了,在我前面的文章有专门介绍。下面就重点讲解输入触发单元TIM_ICInitStructure。


首先看次结构体原型的定义如下:


typedef struct

{

   uint16_t TIM_Channel;      /*!< Specifies the TIM channel.

                                  This parameter can be a value of @ref TIM_Channel */

   uint16_t TIM_ICPolarity;   /*!< Specifies the active edge of the input signal.

                                   This parameter can be a value of @ref TIM_Input_Capture_Polarity */

   uint16_t TIM_ICSelection;  /*!< Specifies the input.

                                  This parameter can be a value of @ref TIM_Input_Capture_Selection */

   uint16_t TIM_ICPrescaler;  /*!< Specifies the Input Capture Prescaler.

                                   This parameter can be a value of @ref TIM_Input_Capture_Prescaler */

  uint16_t TIM_ICFilter;     /*!< Specifies the input capture filter.

                                   This parameter can be a number between 0x0 and 0xF */

} TIM_ICInitTypeDef;

 

它一共有5个成员,5个成员具体作用,我们只要看看3.5版本固件库的说明就清楚了。


uint16_t TIM_ICInitTypeDef::TIM_Channel


Specifies the TIM channel. This parameter can be a value of TIM_Channel


其中TIM_Channel的取值范围如下:


TIM_Channel_1.


TIM_Channel_2


TIM_Channel_3


TIM_Channel_4


uint16_t TIM_ICInitTypeDef::TIM_ICFilter


Specifies the input capture filter. This parameter can be a number between 0x0 and 0xF


说实话这个成员具体作用我没有深入了解,仅仅知道是作为对输入信号的滤波作用,估计是让用户设定用多少个采样时钟来确定最终输入信号,起到滤波作用,避免高频信号干扰,反正不管它了。


uint16_t TIM_ICInitTypeDef::TIM_ICPolarity


Specifies the active edge of the input signal. This parameter can be a value of TIM_Input_Capture_Polarity


这个就是触发边沿的极性选择了,取值范围如下:


TIM_ICPolarity_BothEdge


TIM_ICPolarity_Rising


TIM_ICPolarity_Falling


uint16_t TIM_ICInitTypeDef::TIM_ICPrescaler


Specifies the Input Capture Prescaler. This parameter can be a value of TIM_Input_Capture_Prescaler


这个成员是对外部信号进行分频,也即是设置上图中的Prescaler,可以设置为1/2/4/8分频。


uint16_t TIM_ICInitTypeDef::TIM_ICSelection


Specifies the input. This parameter can be a value of TIM_Input_Capture_Selection


这个成员的作用就必须要对照上面的示意图才能明白。仔细看上面的图,可以发现定时器的4个通道并不是完全独立的,而是1、2一组,3、4一组,同组之间的通道是有联系的。也就是可以出现交叉触发。而TIM_ICSelection就是选择要不要使用交叉来触发,如果不明白可以看固件库的说明文档,如下是此结构体成员的取值范围:


#define TIM_ICSelection_DirectTI   ((uint16_t)0x0001)


TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, IC2, IC3 or IC4, respectively


#define TIM_ICSelection_IndirectTI   ((uint16_t)0x0002)


TIM Input 1, 2, 3 or 4 is selected to be connected to IC2, IC1, IC4 or IC3, respectively.


#define TIM_ICSelection_TRC   ((uint16_t)0x0003)


TIM Input 1, 2, 3 or 4 is selected to be connected to TRC.


也就是说,根据不同的取值,可以讲外部引脚的触发信号连到内部不同的单元,这样就使得单片机更加灵活了。


下面是main.c文件


#include "stm32f10x.h"


 GPIO_InitTypeDef GPIO_InitStructure;


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


TIM_ICInitTypeDef  TIM_ICInitStructure;


NVIC_InitTypeDef NVIC_InitStructure;


 void delay()


{


u32 i,j;


for(i=0;i<1000;i++)


for(j=0;j<5000;j++)


;


}


 void rcc_cfg()


{


 ;


}


 void gpio_cfg()


{


  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA, ENABLE);



  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //随意延时led取反,且将PA8作为触发定时器电平


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;


  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;


  GPIO_Init(GPIOA, &GPIO_InitStructure);


 


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                       //触发中断时,取反PD2


  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;


  GPIO_Init(GPIOD, &GPIO_InitStructure);


 


  /* TIM3 channel 2 pin (PA.07) configuration */


   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;


   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;


   GPIO_Init(GPIOA, &GPIO_InitStructure);


}


 


void nvic_cfg()


{


        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


              /* Enable the TIM3 global Interrupt */


       NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断


       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级


       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级


       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能


       NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器


}


 


void tim3_cfg()


{


  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);


   TIM_DeInit(TIM3);


  TIM_InternalClockConfig(TIM3);


  //预分频系数为36000-1,这样计数器时钟为72MHz/36000 = 2kHz


  TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1;


  //设置时钟分割


  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;


  //设置计数器模式为向上计数模式


  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;


  //设置计数溢出大小,每计2000个数就产生一个更新事件


  TIM_TimeBaseStructure.TIM_Period = 2000 - 1;


  //将配置应用到TIM2中


  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);


   //禁止ARR预装载缓冲器


  TIM_ARRPreloadConfig(TIM3, DISABLE);


 


 //下面是对 TIM_ICInitStructure的配置


   TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;


   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;


   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;


   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;    


   TIM_ICInitStructure.TIM_ICFilter = 0x0;       /*选择输入比较滤波器,滤波设置,经历几个周期跳变认定波形稳定0x0~0xF*/


    TIM_ICInit(TIM3, &TIM_ICInitStructure);


 


  //开启TIM2的中断


  TIM_ClearFlag(TIM3, TIM_IT_CC2);


  TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE);


 


  TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设


}


 


/**


  * @brief  Main program.


  * @param  None


  * @retval None


  */


int main(void)


{


      rcc_cfg();


      gpio_cfg();


      nvic_cfg();


      tim3_cfg();


  while (1)


  {


    /* Set PA8 */


    GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);


       delay();


    /* Reset PA8 */


    GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);


       delay();


  }


}


 


注意定时器3通道2引脚设置为浮空输入。


 


 


 


下面是stm32f10x_it.c文件


 


#include "stm32f10x_it.h"


 u8 flag=0;


extern TIM_ICInitTypeDef  TIM_ICInitStructure;


void TIM3_IRQHandler(void)


{


  if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET)


  {


    /* Clear TIM3 Capture compare interrupt pending bit */


    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);


      //每次进入中断就改变捕获触发方式,且翻转PD2的电平


       if(flag==0)


              {


              flag=1;


              TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;


              TIM_ICInit(TIM3, &TIM_ICInitStructure);


              GPIO_WriteBit(GPIOD, GPIO_Pin_2, Bit_RESET);


              }


       else


              {


              flag=0;


              TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;


              TIM_ICInit(TIM3, &TIM_ICInitStructure);


              GPIO_WriteBit(GPIOD, GPIO_Pin_2, Bit_SET);


              }


   }


}


 


程序运行后,可以看到板子上两个led灯交替闪烁。


我并没有对捕获值作任何处理,因为我只是测试程序是否能顺利进入捕获中断。

推荐阅读

史海拾趣

台湾富致(FUZETEC)公司的发展小趣事

除了在工业控制和汽车领域取得显著成就外,Futaba还将其技术延伸至休闲娱乐领域。公司开发的遥控飞机、车、船等产品,凭借其先进的无线遥控技术和卓越的性能表现,成为户外休闲运动的热门选择。特别是2.4G接收机的推出,进一步丰富了Futaba的产品线,满足了不同消费者的需求。在航模遥控器市场中,Futaba凭借其独特的技术优势和品牌影响力,占据了重要地位。这一领域的拓展不仅为公司带来了新的增长点,还进一步提升了Futaba在全球电子行业中的知名度和影响力。

ERP Power公司的发展小趣事

在这个故事中,我们将关注ERP Power在国际市场的拓展情况。通过与国际知名企业的合作和交流,ERP Power系统成功打入国际市场并获得了广泛认可。这一过程中,ERP Power不仅提升了自身的技术实力和服务水平还积累了丰富的国际化经验。

DATEL Inc公司的发展小趣事

随着技术的不断进步,DATEL Inc.的数据采集产品逐渐在军事领域找到了用武之地。公司接到一项为军方开发高精度数据采集系统的订单。经过深入研究和反复测试,DATEL Inc.成功交付了一套满足军方严苛要求的数据采集系统,为军方提供了准确、可靠的数据支持。这一突破不仅为DATEL Inc.赢得了军方的高度认可,也进一步扩大了公司在军事领域的影响力。

Advanced Monolythic Ceramics公司的发展小趣事

随着技术的不断进步,DATEL Inc.的数据采集产品逐渐在军事领域找到了用武之地。公司接到一项为军方开发高精度数据采集系统的订单。经过深入研究和反复测试,DATEL Inc.成功交付了一套满足军方严苛要求的数据采集系统,为军方提供了准确、可靠的数据支持。这一突破不仅为DATEL Inc.赢得了军方的高度认可,也进一步扩大了公司在军事领域的影响力。

Dymec公司的发展小趣事

在国内市场取得一定成绩后,Dymec公司开始寻求更广阔的发展空间。公司决定进军国际市场,通过参加国际展会、建立海外销售渠道等方式,逐步打开了国际市场的大门。在拓展国际市场的过程中,Dymec公司不仅提升了品牌影响力,还积累了丰富的国际业务经验。

ETERNA公司的发展小趣事

2014年,ETERNA成为了ATP世界网球巡回赛瑞士公开赛的指定合作伙伴。这一合作标志着ETERNA在品牌建设和市场推广方面取得了新的突破。通过与ATP的合作,ETERNA不仅成功地将品牌与高端体育赛事相结合,还进一步提升了品牌形象和知名度。同时,ETERNA还为赛事提供了精准的计时服务,展现了其在电子技术领域的实力。

问答坊 | AI 解惑

积分、威望金钱是怎么计算的???

亲善大使给大家介绍一下啊!…

查看全部问答>

手机SIM卡常识(转)

手机是什么?几乎所有人都知道答案:就是那特烧钱、特不保值的玩意!SIM卡是什么?估计许多人无法给出一个比较完整的答案,只知道是一张小小的卡片!但是您也许不知道手机离开了这张小小的SIM卡是几乎做不了工作的,除了在特殊情况下用户可以通过不 ...…

查看全部问答>

单电源运放应用图集

单电源运放应用图集,包括放大器,和各种滤波器的设计。其中公式中的p应该是π 两个附件一样,请大家下载5芯片币的那个 [ 本帖最后由 xuwq2 于 2009-6-26 20:07 编辑 ]…

查看全部问答>

从SD卡读取的数据错误

请教大家一个问题: 平台ARM9+WinCE5.0,使用90多张不同品牌不同大小的卡来做测试,其中有一张Nokia 2G的卡在读取某个文件的时候,有些时候数据是正确的,有些时候数据是错误的。 该文件有1.02MB,调用Readfile每次读取1024Bytes,在中间的某一 ...…

查看全部问答>

WINCE下调用DLL的问题

用EVC开发,WINCE4.2 为何我调用动态链接库总是说\"找不到testdlg(或他的某一个组件)\" 其中testdlg调用testdll,在VC下试通过了啊 请各位帮帮忙,看看是什么原因,WINCE下调用动态链接库有什么特殊的地方么? …

查看全部问答>

wince 如何支持向消息队列服务器发送消息?

wince 如何支持向消息队列服务器发送消息?我有个设想,每次在pda上发送消息到消息队列服务器,消息队列服务器从接收到消息后,执行相应的处理。现在存在问题是:在pc机发送都很正常,但是移植到ppc模拟器上,却出现了找不到消息队列服务器错误,为 ...…

查看全部问答>

modelsim 6.5b的破解方法和破解文件

modelsim的所有版本都可以在官网上下载,官网地址是http://model.com/,不过下载前要填写以下自己信息 破解方法和破解文件都在附件中,使用破解文件时要关闭全部杀毒啊 …

查看全部问答>

stm107疑似重大BUG

今天做串口DMA的测试,用DMA1的channle4和channle5对串口1进行收、发测试。发现只要是出现收发同时发生时,发送就会出错。 也就是说DMA的各个通道不能同时使用。唉,这样的话STM的串口的收发效率也就太低了。…

查看全部问答>

msp430f149用P4.1发脉冲,抖动严重,为什么?

用TimerB0中断,让P4.1发脉冲,TBCCR0到大约30时,用示波器观察P4.1的脉冲波形,抖动严重,为什么? void Init_TimerB(void) { TBCTL = TBSSEL1 + TBCLR + TBIE; // 时钟源SMCLK, TBCCTL0 = CCIE; // C ...…

查看全部问答>

LM3S811定时器输入捕捉功能分析与应用

LM3S系列单片机的定时器模块一共有三种工作模式:(1)定时器模式(2)输入捕捉模式(3)PWM模式这里主要研究一下输入捕捉功能。定时器的输入捕捉模式是用来捕捉外部事件发生的时间或者对外部事件进行计数。当定时器工作于输入捕捉模式时,定时器被配置为 ...…

查看全部问答>