当前位置:文档之家› stm32f407通用定时器输入捕获

stm32f407通用定时器输入捕获

stm32f407通用定时器输入捕获
stm32f407通用定时器输入捕获

通用定时器输入捕获

通用定时器作为输入捕获的使用。我们用TIM5的通道1(PA0)来做输入捕获,捕获PA0上高电平的脉宽(用KEY_UP按键输入高电平),通过串口来打印高电平脉宽时间。

输入捕获模式可以用来测量脉冲宽度或者测量频率。我们以测量脉宽为例,用一个简图来说明输入捕获的原理:

如图所示,就是输入捕获测量高电平脉宽的原理,假定定时器工作在向上计数模式,图中t1~t2时间,就是我们需要测量的高电平时间。测量方法如下:首先设置定时器通道x为上升沿捕获,这样,t1时刻,就会捕获到当前的CNT值,然后立即清零CNT,并设置通道x为下降沿捕获,这样到t2时刻,又会发生捕获事件,得到此时的CNT值,记为CCRx2。这样,根据定时器的计数频率,我们就可以算出t1~t2的时间,从而得到高电平脉宽。在t1~t2之间,可能产生N次定时器溢出,这就要求我们对定时器溢出,做处理,防止高电平太长,导致数据不准确。如图所示,t1~t2之间,CNT计数的次数等于:N*ARR+CCRx2,有了这个计数次数,再乘以CNT的计数周期,即可得到t2-t1的时间长度,即高电平持续时间。

STM32F4的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。STM32F4的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA等。这里我们用TIM5_CH1来捕获高电平脉宽。

============================================================== =====================

捕获/比较通道(例如:通道1 输入阶段)

============================================================== =====================

接下来介绍我们需要用到的一些寄存器配置,需要用到的寄存器:TIMx_ARR、TIMx_PSC、

TIMx_CCMR1、TIMx_CCER、TIMx_DIER、TIMx_CR1、TIMx_CCR1 (这里的x=5)。

首先TIMx_ARR和TIMx_PSC,这两个寄存器用来设自动重装载值和TIMx的时钟分频。

---------------------------------------------------------------------------------------------------------------------------------------

捕获/比较模式寄存器1:TIMx_CCMR1,这个寄存器在输入捕获的时候,非常有用:

TIMx 捕获/比较模式寄存器1 (TIMx_CCMR1)

TIMx capture/compare mode register 1 偏移地址:0x18 复位值:0x0000

当在输入捕获模式下使用的时候,对应图的第二行描述,从图中可以看出,TIMx_CCMR1是针对2个通道的配置,低八位[7:0]用于捕获/比较通道1的控制,而高八位[15:8]则用于捕获/比较通道2的控制,因为TIMx还有CCMR2这个寄存器,所以可以知道CCMR2是用来控制通道3和通道4(详见《STM32F4xx中文参考手册》435页,15.4.8节)。这里我们用到的是TIM5的捕获/比较通道1,我们重点介绍TIMx_CCMR1的[7:0]位(其高8位配置类似),TIMx_CCMR1的[7:0]位详细描述见图所示:

位7:4 IC1F:输入捕获1滤波器(Input capture 1 filter)

此位域可定义TI1输入的采样频率和适用于TI1的数字滤波器带宽。数字滤波器由事件计数器组成,每N 个事件才视为一个有效边沿:

0000:无滤波器,按f DTS频率进行采样1000:f SAMPLING=f DTS/8,N=6

0001:f SAMPLING=f CK_INT,N=2 1001:f SAMPLING=f DTS/8,N=8

0010:f SAMPLING=f CK_INT,N=4 1010:f SAMPLING=f DTS/16,N=5

0011:f SAMPLING=f CK_INT,N=8 1011:f SAMPLING=f DTS/16,N=6

0100:f SAMPLING=f DTS/2,N=6 1100:f SAMPLING=f DTS/16,N=8

0101:f SAMPLING=f DTS/2,N=8 1101:f SAMPLING=f DTS/32,N=5

0110:f SAMPLING=f DTS/4,N=6 1110:f SAMPLING=f DTS/32,N=6

0111:f SAMPLING=f DTS/4,N=8 1111:f SAMPLING=f DTS/32,N=8

注意:在当前硅版本中,当ICxF[3:0]= 1、2或3时,将用CK_INT代替公式中的f DTS。

输入捕获1滤波器IC1F[3:0],这个用来设置输入采样频

率和数字滤波器长度。其中,f CK_INT是定时器的输入频

率(TIMxCLK),一般为84Mhz/168Mhz(看该定时器

在哪个总线上),而f DTS则是根据TIMx_CR1的CKD[1:0]

的设置来确定的,如果CKD[1:0]设置为00,那么

f DTS=f CK_INT。N值就是滤波长度,举个简单的例子:假

设IC1F[3:0]=0011,并设置IC1映射到通道1上,且为

上升沿触发,那么在捕获到上升沿的时候,再以f CK_INT

的频率,连续采样到8次通道1的电平,如果都是高电

平,则说明却是一个有效的触发,就会触发输入捕获中

断(如果开启了的话)。这样可以滤除那些高电平脉宽低

于8个采样周期的脉冲信号,从而达到滤波的效果。这

里,我们不做滤波处理,所以设置IC1F[3:0]=0000,只

要采集到上升沿,就触发捕获。

位3:2 IC1PSC:输入捕获1预分频器(Input capture 1 prescaler)

此位域定义CC1输入(IC1)的预分频比。

只要CC1E=0(TIMx_CCER寄存器),预分频器便立即复位。

00:无预分频器,捕获输入上每检测到一个边沿便执行捕获

01:每发生2个事件便执行一次捕获

10:每发生4个事件便执行一次捕获

11:每发生8个事件便执行一次捕获

输入捕获1预分频器IC1PSC[1:0],我们是1次边沿就触

发1次捕获,所以选择00。

位1:0 CC1S:捕获/比较1选择(Capture/Compare 1 selection)

此位域定义通道方向(输入/输出)以及所使用的输入。

00:CC1通道配置为输出

01:CC1通道配置为输入,IC1映射到TI1上

10:CC1通道配置为输入,IC1映射到TI2上

11:CC1通道配置为输入,IC1映射到TRC上。此模式仅在通

过TS位(TIMx_SMCR寄存器)选择内部触发输入时有效

注意:仅当通道关闭时(TIMx_CCER中的CC1E = 0),才

可向CC1S位写入数据。

其中CC1S[1:0],这两个位用于CCR1的通道配置,这里

我们设置IC1S[1:0]=01,也就是配置IC1映射在TI1上。---------------------------------------------------------------------------------------------------------------------------------------

TIMx 捕获/比较使能寄存器(TIMx_CCER)

TIMx capture/compare enable register 偏移地址:0x20 复位值:0x0000

位1 CC1P:捕获/比较1输出极性(Capture/Compare 1

output Polarity)。

CC1通道配置为输出:

0:OC1高电平有效1:OC1低电平有效

CC1 通道配置为输入:CC1NP/CC1P位可针对触发或捕获

操作选择TI1FP1和TI2FP1的极性。

00:非反相/上升沿触发

电路对TIxFP1上升沿敏感(在复位模式、外部时钟模式或

触发模式下执行捕获或触发操作),TIxFP1未反相(在门控

模式或编码器模式下执行触发操作)。

01:反相/下降沿触发

电路对TIxFP1下降沿敏感(在复位模式、外部时钟模式或

触发模式下执行捕获或触发操作),TIxFP1反相(在门控模

式或编码器模式下执行触发操作)。

10:保留,不使用此配置。

11:非反相/上升沿和下降沿均触发

电路对TIxFP1上升沿和下降沿都敏感(在复位模式、外部

时钟模式或触发模式下执行捕获或触发操作)

位0 CC1E:捕获/比较1输出使能(Capture/Compare 1 output enable)。

CC1通道配置为输出:

0:关闭––OC1未激活1:开启––在相应输出引脚上输出OC1信号

CC1通道配置为输入:

此位决定了是否可以实际将计数器值捕获到输入捕获/比较寄存器1 (TIMx_CCR1) 中。

0:禁止捕获1:使能捕获

所以要使能输入捕获,必须设置CC1E=1,而CC1P则根据自己的需要来配置。

---------------------------------------------------------------------------------------------------------------------------------------

接下来我们再看看DMA/中断使能寄存器:TIMx_DIER,该寄存器的各位描述见图

TIMx_ DIER 寄存器各位描述

我们需要用到中断来处理捕获数据,所以必须开启通道1的捕获比较中断,即CC1IE设置为1。---------------------------------------------------------------------------------------------------------------------------------------

控制寄存器:TIMx_CR1,我们只用到了它的最低位,也就是用来使能定时器的。

控制寄存器1(TIMx_CR1)

位9:8 CKD:时钟分频(Clock division)

此位域指示定时器时钟(CK_INT) 频率与数字滤波器所使用的采样时钟(ETR、TIx之间的分频比,

00:t DTS = t CK_INT 01:t DTS = 2 × t CK_INT

10:t DTS = 4 × t CK_INT 11:保留

------------------------------------------------------------------------------- 最后再来看看捕获/比较寄存器1:TIMx_CCR1,该寄存器用来存储捕获发生时,TIMx_CNT的值,我们从TIMx_CCR1就可以读出通道1捕获发生时刻的TIMx_CNT值,通过两次捕获(一次上升沿捕获,一次下降沿捕获)的差值,就可以计算出高电平脉冲的宽度(注意,对于脉宽太长的情况,还要计算定时器溢出的次数)。

============================================================== =====================输入捕获库函数配置:

1)开启TIM5时钟,配置PA0为复用功能(AF2),并开启下拉电阻。

要使用TIM5,我们必须先开启TIM5的时钟。同时我们要捕获TIM5_CH1上面的高电平脉宽,所以先配置PA0为带下拉的复用功能,同时,为了让PA0的复用功能选择连接到TIM5,所以设置PA0的复用功能为AF2,即连接到TIM5上面。

开启IM5时钟的方法为:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //TIM5 时钟使能

当然,这里我们也要开启PA0对应的GPIO的时钟。

配置PA0为复用功能,所以我们首先要设置PA0引脚映射AF2,方法为:

GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5);

最后,我们还要初始化GPIO的模式为复用功能,同时这里我们还要设置为开启下拉。方法为:GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉

GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0

跟上一讲PWM输出类似,这里我们使用的是定时器5的通道1,所以我们从STM32F4对应的数据手册可以查看到对应的IO口为PA0:

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

在开启了TIM5的时钟之后,我们要设置ARR和PSC两个寄存器的值来设置输入捕获的自动重装载值和计数频率。这在库函数中是通过TIM_TimeBaseInit函数实现的,

TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式

TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);//初始化TIM5

3)设置TIM5的输入捕获参数,开启输入捕获。

TIM5_CCMR1寄存器控制着输入捕获1和2的模式,包括映射关系,滤波和分频等。这里我们

需要设置通道1为输入模式,且IC1映射到TI1(通道1)上面,并且不使用滤波器(提高响应速度)。库函数是通过TIM_ICInit函数来初始化输入比较参数的:

void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)

同样,我们来看看参数设置结构体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_Channel很好理解,用来设置通道。我们设置为通道1,为TIM_Channel_1。

参数TIM_ICPolarit是用来设置输入信号的有效捕获极性,这里我们设置为TIM_ICPolarity_Rising,上升沿捕获。同时库函数还提供了单独设置通道1捕获极性的函数为:TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);

这表示通道1为上升沿捕获,我们后面会用到,同时对于其他三个通道也有一个类似的函数,使用的时候一定要分清楚使用的是哪个通道该调用哪个函数,格式为TIM_OCxPolarityConfig()。参数TIM_ICSelection是用来设置映射关系,我们配置IC1直接映射在TI1上,选择

TIM_ICSelection_DirectTI。

参数TIM_ICPrescaler用来设置输入捕获分频系数,我们这里不分频,所以选中TIM_ICPSC_DIV1,还有2,4,8分频可选。

参数TIM_ICFilter设置滤波器长度,这里我们不使用滤波器,所以设置为0。

我们的配置代码是:

TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端IC1 映射到TI1上

TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获

TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上

TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频

TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器不滤波

TIM_ICInit(TIM5, &TIM5_ICInitStructure);

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

因为我们要捕获的是高电平信号的脉宽,所以,第一次捕获是上升沿,第二次捕获时下降沿,必须在捕获上升沿之后,设置捕获边沿为下降沿,同时,如果脉宽比较长,那么定时器就会溢出,对溢出必须做处理,否则结果就不准了,不过,由于STM32F4的TIM5是32位定时器,假设计数周期为1us,那么需要4294秒才会溢出一次,这基本上是不可能的。这两件事,我们都在中断里面做,所以必须开启捕获中断和更新中断。

这里我们使用定时器的开中断函数TIM_ITConfig即可使能捕获和更新中断:

TIM_ITConfig( TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断和捕获中断

5)设置中断优先级,编写中断服务函数

因为我们要使用到中断,所以我们在系统初始化之后,需要先设置中断优先级分组,这里方法跟我们前面讲解一致,调用NVIC_PriorityGroupConfig()函数即可,我们系统默认设置都是分组2。设置中断优先级的方法前面多次提到这里我们不做讲解,主要是通过函数NVIC_Init()来完成。设置优先级完成后,我们还需要在中断函数里面完成数据处理和捕获设置等关键操作,从而实现高电平脉宽统计。

在中断服务函数里面,跟以前的外部中断和定时器中断实验中一样,

我们在中断开始的时候要进行中断类型判断,在中断结束的时候要清除中断标志位。使用到的函数在上面的实验已经讲解过,分别为TIM_GetITStatus()函数和TIM_ClearITPendingBit()函数。if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET){}//判断是否为更新中断

if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET){}//判断是否发生捕获事件

TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);//清除中断和捕获标志位

在我们实验的中断服务函数中,我们还使用到了一个设置计数器值的函数为:

TIM_SetCounter(TIM5,0);

上面语句的意思是将TIM5的计数值设置为0。这个相信是比较好理解的。

6)使能定时器(设置TIM5的CR1寄存器)

最后,必须打开定时器的计数器开关,启动TIM5的计数器,开始输入捕获。

TIM_Cmd(TIM5,ENABLE ); //使能定时器5

通过以上6步设置,定时器5的通道1就可以开始输入捕获了,同时因为还用到了串口输出结果,所以还需要配置一下串口。

我们在timer.c和timer.h 中主要是添加了输入捕获初始化函数TIM5_CH1_Cap_Init 以及中断服务函数TIM5_IRQHandler。

接下来我们来看看timer.c文件中,我们添加的两个函数的内容:

TIM_ICInitTypeDef TIM5_ICInitStructure;

//定时器5通道1输入捕获配置

//arr:自动重装值(TIM2,TIM5 是32 位的!!) psc:时钟预分频数

void TIM5_CH1_Cap_Init(u32 arr,u16 psc)

{

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //TIM5 时钟使能

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA 时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉

GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0

GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0 复用位定时器5

TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式

TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);

TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端IC1 映射到TI1 上TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获

TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1 上

TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频

TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器不滤波

TIM_ICInit(TIM5, &TIM5_ICInitStructure); //初始化TIM5 输入捕获参数

TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新和捕获中断

TIM_Cmd(TIM5,ENABLE ); //使能定时器5

NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2

NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;//响应优先级0

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

NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器、

}

//捕获状态

//[7]:0,没有成功的捕获;1,成功捕获到一次.

//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.

//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒) u8 TIM5CH1_CAPTURE_STA=0; //输入捕获状态

u32 TIM5CH1_CAPTURE_VAL; //输入捕获值(TIM2/TIM5是32位)

//定时器5中断服务程序

void TIM5_IRQHandler(void)

{

if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获

{

if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)//溢出

{

if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了

{

if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了

{

TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次

TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;

}else TIM5CH1_CAPTURE_STA++;

}

}

if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获1发生捕获事件

{

if(TIM5CH1_CAPTURE_STA&0X40) //捕获到一个下降沿

{

TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获到一次高电平脉宽

TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//获取当前的捕获值.

TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P=0设为上升沿捕获

}else //还未开始,第一次捕获上升沿

{

TIM5CH1_CAPTURE_STA=0; //清空

TIM5CH1_CAPTURE_VAL=0;

TIM5CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿

TIM_Cmd(TIM5,DISABLE ); //关闭定时器5

TIM_SetCounter(TIM5,0);

TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);//CC1P=1设为下降沿捕获

TIM_Cmd(TIM5,ENABLE ); //使能定时器5

}

}

}

TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位

}

此部分代码包含两个函数,其中TIM5_CH1_Cap_Init函数用于TIM5通道1的输入捕获设

置,其设置和我们上面讲的步骤是一样的,这里就不多说,特别注意:TIM5是32位定时器,所以arr是u32类型的。接下来,重点来看看第二个函数。TIM5_IRQHandler是TIM5的中断服务函数,该函数用到了两个全局变量,用于辅助实现高电平捕获。其中TIM5CH1_CAPTURE_STA,是用来记录捕获状态,该变量类似我们在usart.c里面自行定义的USART_RX_STA 寄存器(其实就是个变量,只是我们把它当成一个寄存器那样来使用)。TIM5CH1_CAPTURE_STA 各位描述如表

另外一个变量TIM5CH1_CAPTURE_VAL,则用来记录捕获到下降沿的时候,TIM5_CNT的值。

现在介绍一下,捕获高电平脉宽的思路:首先,设置TIM5_CH1捕获上升沿,这在TIM5_Cap_Init 函数执行的时候就设置好了,然后等待上升沿中断到来,当捕获到上升沿中断,此时如果TIM5CH1_CAPTURE_STA的第6位为0,则表示还没有捕获到新的上升沿,就先把

TIM5CH1_CAPTURE_STA、TIM5CH1_CAPTURE_VAL 和计数器值TIM5->CNT等清零,然后再设置TIM5CH1_CAPTURE_STA的第6位为1,标记捕获到高电平,最后设置为下降沿捕获,待下降沿到来。如果等待下降沿到来期间,定时器发生了溢出(对32位定时器来说,很难溢出),就在TIM5CH1_CAPTURE_STA里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记捕获完成(虽然此时还没有捕获到下降沿)。当下降沿到来的时候,先设置TIM5CH1_CAPTURE_STA的第7位为1,标记成功捕获一次高电平,然后读取此时的定时器值到TIM5CH1_CAPTURE_VAL里面,最后设置为上升沿捕获,回到初始状态。这样,我们就完成一次高电平捕获了,只要TIM5CH1_CAPTURE_STA的第7位一直为1,那么就不会进行第二次捕获,我们在main函数处理完捕获数据后,将TIM5CH1_CAPTURE_STA置零,就可以开启第二次捕获。接下来,我们看看main 函数内容:

extern u8 TIM5CH1_CAPTURE_STA; //输入捕获状态

extern u32 TIM5CH1_CAPTURE_VAL;//输入捕获值

通过设置TIM5_Cap_Init(0XFFFFFFFF,84-1),将TIM5_CH1 的捕获计数器设计为1us 计数一次,并设置重装载值为最大以达到不让定时器溢出的作用(溢出时间为232-1 us),所以我们的捕获时间精度为1us。主函数通过TIM5CH1_CAPTURE_STA 的第7位,来判断有没有成功捕获到一次高

电平,如果成功捕获,则将高电平时间通过串口输出到电脑.

if(TIM5CH1_CAPTURE_STA&0X80) //成功捕获到了一次高电平

{

temp=TIM5CH1_CAPTURE_STA&0X3F;

temp*=0XFFFFFFFF; //溢出时间总和

temp+=TIM5CH1_CAPTURE_VAL; //得到总的高电平时间

printf("HIGH:%lld us\r\n",temp); //打印总的高点平时间

TIM5CH1_CAPTURE_STA=0; //开启下一次捕获

}

PA1(CH2)无法使用。尝试如下:

PA0,2,3,4捕获一起打开,程序在TIM5初始化完成后陷入死循环,无法进入while的大循环。PA1单独打开,同样无法捕获到。

所以TIM5只有PA0,2,3即通道1,3,4能用,并且如果PA0,1,2,3一起插上PWM信号,则全部无法工作。

设计STM32F407 的TIM5通道捕获PWM时需要注意这一点。

LTE常见事件解释及定时器

1.1 4.5.1 切换正常流程 同频切换同时支持同eNodeB切换,同MME的异eNodeB切换,跨MME的异eNodeB切换场景。对于后两种场景依据eNodeB间是否建立X2接口,切换信令流程略有不同。 图4-2 同MME异eNodeB间切换流程 同MME异eNodeB间的同频切换信令流程如图4-2所示: 1.在无线承载建立时,源eNodeB下发RRC Connection Reconfiguration至UE,其中包含 source eNodeB 配置的Measurement Configuration消息,用于控制UE连接态的测量过程。

2.UE根据测量结果上报Measurement Report。 3.源eNodeB根据测量报告进行切换决策。 4.当源eNodeB决定切换后,源eNodeB发出HandoverRequest消息给目标eNodeB,通知 目标eNodeB准备切换。 5.目标eNodeB进行准入判断,若判断为资源准入,再由目标eNodeB依据EPS的QoS信息 执行准入控制。 6.目标eNodeB在L1/L2准备切换并对源eNodeB发送HANDOVER REQUEST ACKNOWLEDGE消息。 1.2 报告配置(A1至A5 B1至B2) 事件触发上报是3GPP 36.331协议中为切换测量与判决定义的一个概念。报告配置包含相应事件的相关参数。目前eNodeB应用以下事件触发相应动作: ●事件A1表示服务小区质量高于一定门限,当满足事件触发条件时UE便上报测量报告,eNodeB 停止异频/异系统测量。但在基于频率优先级的切换中,事件A1用于启动异频测量。 ●事件A2表示服务小区质量低于一定门限,当满足事件触发条件时UE便上报测量报告,eNodeB 启动异频/异系统测量。但在基于频率优先级的切换中,事件A2用于停止异频测量。 ●事件A3表示同频/异频邻区质量相比服务小区质量高出一定门限,当满足事件触发条件的小区信息被上报时,源eNodeB启动同频/异频切换请求。 ●事件A4表示异频邻区质量高于一定门限,满足事件触发条件的小区信息被上报时,源eNodeB 启动异频切换请求。 ●事件A5表示服务小区质量低于一定门限,同时异频邻区质量高于一定门限,满足事件触发条 件的小区信息被上报时,源eNodeB启动异频切换请求。 ●事件B1表示异系统邻区质量高于一定门限,满足事件触发条件的小区信息被上报时,源eNodeB启动异系统切换请求。 ●事件B2表示服务小区质量低于一定门限,同时异系统邻区质量高于一定门限,满足事件触发 条件的小区信息被上报时,源eNodeB启动异系统切换请求。 事件转周期上报 事件被触发并上报之后将转为周期上报满足该事件的测量信息,此方式称为事件转周期上报。UE的测量结果通过事件转周期的方式上报给eNodeB。周期上报将在事件取消条件满足或达到最大上报次数或UE收到切换命令后后取消。 事件转周期上报方式有如下作用: ●可有效防止因测量报告的遗失或内部处理流程的失败对切换造成影响。 ●对于准入拒绝,可以起到重试的作用。 ●测量报告中,邻区可能一次报不完。并且随着UE的移动,会上报不同的邻区,通过事件转周 期可以得到比较完整的测量结果。 1.3 事件A3的触发(LST INTRAFREQHOGROUP) 同频切换通过事件A3触发,且事件上报方式采用事件转周期的上报方式。 事件A3的触发,即邻区质量高于服务小区一定偏置值。参照3GPP协议36.331规定事件 A3的判决公式。 触发条件:Mn+Ofn+Ocn-Hys>Ms+Ofs+Ocs+Off

05_STM32F4通用定时器详细讲解精编版

STM32F4系列共有14个定时器,功能很强大。14个定时器分别为: 2个高级定时器:Timer1和Timer8 10个通用定时器:Timer2~timer5 和 timer9~timer14 2个基本定时器: timer6和timer7 本篇欲以通用定时器timer3为例,详细介绍定时器的各个方面,并对其PWM 功能做彻底的探讨。 Timer3是一个16位的定时器,有四个独立通道,分别对应着PA6 PA7 PB0 PB1 主要功能是:1输入捕获——测量脉冲长度。 2 输出波形——PWM 输出和单脉冲输出。 Timer3有4个时钟源: 1:内部时钟(CK_INT ),来自RCC 的TIMxCLK 2:外部时钟模式1:外部输入TI1FP1与TI2FP2 3:外部时钟模式2:外部触发输入TIMx_ETR ,仅适用于TIM2、TIM3、TIM4,TIM3,对应 着PD2引脚 4:内部触发输入:一个定时器触发另一个定时器。 时钟源可以通过TIMx_SMCR 相关位进行设置。这里我们使用内部时钟。 定时器挂在高速外设时钟APB1或低速外设时钟APB2上,时钟不超过内部高速时钟HCLK ,故当APBx_Prescaler 不为1时,定时器时钟为其2倍,当为1时,为了不超过HCLK ,定时器时钟等于HCLK 。 例如:我们一般配置系统时钟SYSCLK 为168MHz ,内部高速时钟 AHB=168Mhz ,APB1欲分频为4,(因为APB1最高时钟为42Mhz ),那么挂在APB1总线上的timer3时钟为84Mhz 。 《STM32F4xx 中文参考手册》的424~443页列出与通用定时器相关的寄存器一共20个, 以下列出与Timer3相关的寄存器及重要寄存器的简单介绍。 1 TIM3 控制寄存器 1 (TIM3_CR1) SYSCLK(最高 AHB_Prescaler APBx_Prescaler

STM32高级定时器死区时间设置探究

STM32高级定时器死区时间设置探究 一、死区设置位置: 决定死区时间设置的位是‘刹车和死区寄存器TIM1->BDTR’中的DTG[7:0],设置范围是0x00~0xff。 二、死区时间设置公式如下: DT为死区持续时间,TDTS为系统时钟周期时长,Tdtg为系统时钟周期时长乘以倍数后的死区设置时间步进值。 在72M的定时器时钟下TDTS=1/72M=13.89ns. 所以以第一个公式,死区时间能以13.89ns的步进从0调整到127*13.89ns=1764ns 第二个公式则能(64+0)*2*13.89~(64+63)*2*13.89=1777.9ns~3528.88ns 换个角度看,就是(128~254)*13.89

同理,第三个公式就是3555.84ns~7000.56ns 换个角度看,就是(256~504)*13.89 第四个公式就是7111.68ns~14001.12ns 换个角度看,就是(512~1008)*13.89 综上: 死区时间就是不同的公式代表不同范围的死区时间设置,这个范围是互不重叠的。而但是在不同的死区时间范围内死区时间设置步进是不同的。 若某个系统时钟下的死区时间不够,可以通过改变定时器时钟来改变最大死区时间范围。 当根据硬件电路的特性定下死区时间后,可以根据目标死区时间范围来找到相应的公式,然后代入公式求解出相应的整数(有时候不一定是整数,那就选择最近的那个),拼接DTG[7:5]+DTG[4:0]即可。 例子:这样当我需要3us的死区持续时间时,则可这么计算: 3us在第二个公式决定的死区范围之内。所以选择第二个公式。 3000/(13.89*2)=108,所以DTG[5:0]=108-64=44,所以DTG=127+44=171=0Xab TIM1->BDTR|=0xab; 反过来验算//72Mhz,死区时间=13.89nsX108*2=3000us 经示波器验证,完全正确。 By zxx2013.07.18

MC9S12XS128之时间模块TIM输入捕捉

买了本《嵌入式系统——使用HCS12微控制器的设计与应用》这本书,看了觉得帮助不大。因为里面有些东西讲得不够详细,并且这本书不是针对XS128来写的。网上也有一些网友写的资料,那都只是针对某一方面的。我觉得最好的资料还是英文版的说明文档,里面好多东西都讲得很详细,虽然看起来有点费劲,但那里值得的。 接下来就自己的学习经历。 TIM中的功能比较多,有输入捕捉、输出比较,还有脉冲累加器。这里主要记一下输入捕捉和输出比较。输入捕捉这个功能很有用,他不仅可以捕捉外界事件的发生(这个功能和51中的外部中断差不多),还可以捕捉外界事件发生的时间。捕捉外界时间这个功能可以运用到驱动超声波测距中去。 IOC0~IOC7是输入捕捉\输出比较的外部针脚。当IOSx=0时(IOSx=1时为输出比较),则将相应的通道配置为输入捕捉了。当输入捕捉检测到有上升沿或下降沿时,就会把那时寄存器的值锁存到TCx中,这样就可以通过查询TCx来确定事件发生的时间了。如果输入捕捉控制寄存器TIE(CxI=1)中允许输入捕捉中断,则捕捉到事件时,系统会产生一次中断。 接下来依次说明一下相关的寄存器设置: TSCR1: TEN是定时器允许位。TEN=1时,允许定时器工作,TEN=0时,禁止定时器工作。其余不常用,设为0即可。 TSCR2: TOI是定时器溢出中断允许位。这个在输入捕捉中没用到,设为0即可。 TCRE是定时器计数寄存器复位允许位。用在输出比较中,允许输出比较寄存器7的事件来复位定时器计数寄存器。这里设为0即可。 PR2~PR0是定时器分频因子选择位。不同的组合可以设定不同的定时器时钟:

TIOS是输入捕捉和输出比较选择寄存器,在这里设定IOC0~IOC7是用于输入捕捉还是用于输出比较。 里面的8位对应着IOC0~IOC7八个通道,相应位位1,则设为输出比较。相应位设为0,则为输入捕捉。 TCTL3和TCTL4是用来设定输入捕捉极性的寄存器,在这里可以设为上升沿、下降沿、上升沿或下降沿触发输入捕捉。 其中EDGxB和EDGxA一起来设相应通道输入捕捉极性,对应的功能如下:

STM32输入捕获简介

STM32输入捕获简介 输入捕获模式可以用来测量脉冲宽度或者测量频率。STM32的定时器,除了TIM6和TIM7,其他定时器都有输入捕获功能。STM32的输入捕获,简单的说就是通过检测TIMx_CHx上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存(TIMx_CCRx)里面,完成一次捕获。同时还可以配置捕获时是否触发中断/DMA 等. 例如:我们用到TIM5_CH1来捕获高电平脉宽,也就是要先设置输入捕获为上升沿检测,记录发生上升沿的时候TIM5_CNT的值。然后配置捕获信号为下降沿捕获,当下降沿到来时,发生捕获,并记录此时的TIM5_CNT值。这样,前后两次TIM5_CNT之差,就是高电平的脉宽,同时TIM5的计数频率我们是知道的,从而可以计算出高电平脉宽的准确时间。 首先TIMx_ARR和TIMx_PSC,这两个寄存器用来设自动重装载值和TIMx的时钟分频。 再来看看捕获/比较模式寄存器1:TIMx_CCMR1,这个寄存器在输入捕获的时候,非常有用;TIMx_CCMR1明显是针对2个通道的配置,低八位[7:0]用于捕获/比较通道1的控制,而高八位[15:8]则用于捕获/比较通道2的控制,因为TIMx还有CCMR2这个寄存器,所以可以知道CCMR2是用来控制通道3和通道4(详见《STM32参考手册》290页,14.4.8节)。 这里用到TIM5的捕获/比较通道1,我们重点介绍TIMx_CMMR1的[7:0]位(其实高8位配置类似)。 再来看看捕获/比较使能寄存器:TIMx_CCER; 接下来我们再看看DMA/中断使能寄存器:TIMx_DIER,我们需要用到中断来处理捕获数据,所以必须开启通道1的捕获比较中断,即CC1IE设置为1。 控制寄存器:TIMx_CR1,我们只用到了它的最低位,也就是用来使能定时器的; 最后再来看看捕获/比较寄存器1:TIMx_CCR1,该寄存器用来存储捕获发生时,TIMx_CNT的值,我们从TIMx_CCR1就可以读出通道1捕获发生时刻的TIMx_CNT值,通过两次捕获(一次上升沿捕获,一次下降沿捕获)的差值,就可以计算出高电平脉冲的宽度。 使能捕获和更新中断(设置TIM5的DIER寄存器) 因为我们要捕获的是高电平信号的脉宽,所以,第一次捕获是上升沿,第二次捕获时下降沿,必须在捕获上升沿之后,设置捕获边沿为下降沿,同时,如果脉宽比较长,那么定时器就会溢出,对溢出必须做处理,否则结果就不准了。这两件事,我们都在中断里面做,所以必须开启捕获中断和更新中断。 1void init_tim2_cam(u16 psc, u16 arr, u8 way, u8 dir) 2 { 3 RCC->APB1ENR |= 1<<0; //使能定时器2时钟 4 RCC->APB2ENR |= 1<<2; //使能PortA 5 6switch (way) 7 { 8case1: 9 GPIOA->CRL &= 0xfffffff0; 10 GPIOA->CRL |= 0x00000008; 11break; 12case2:

stm32的定时器输入捕获与输出比较

stm32的定时器输入捕获与输出比较 (2015-09-28 09:26:24) 转载▼ 分类:stm32 标签: it 明确一点对比AD的构造,stm32有3个AD,每个AD有很多通道,使用哪个通道就配置成哪个通道,这里定时器也如此,有很多定时器TIMx,每个定时器有很多CHx(通道),可以配置为输入捕捉-------测量频率用,也可以配置为输出比较--------输出PWM使用 输入捕捉:可以用来捕获外部事件,并为其赋予时间标记以说明此事件的发生时刻。 外部事件发生的触发信号由单片机中对应的引脚输入(具体可以参考单片机的datasheet),也可以通过模拟比较器单元来实现。 时间标记可用来计算频率,占空比及信号的其他特征,以及为事件创建日志,主要是用来测量外部信号的频率。 输出比较:定时器中计数寄存器在初始化完后会自动的计数。从bottom计数到top。并且有不同的工作模式。 另外还有个比较寄存器。一旦计数寄存器在从bottom到top计数过程中与比较寄存器匹配则会产生比较中断(比较中断使能的情况下)。 然后根据不同的工作模式计数寄存器将清零或者计数到top值。

1、朋友,可以解释一下输入捕获的工作原理不? 计数寄存器的初值,是自己写进去的吗? 我如果捕获上升沿,两个值相减,代表的时两个上升沿中间那段电平的时间。对不? timer1有五个通道(对应五个IO引脚),在同一时刻,只能捕获一个引脚的值,对不? 那输出比较的原理你可以帮我介绍一下不?

比较单元的值是人为设进去的吧? 上面这个总看不懂,好像不不止你说的那几种情况:“匹配了是io电平取反、变低、还是变高,就会产生不同的波形了” 设置输出就是置1,清除输出就是置0,切换输出就是将原来的电平取反,对不? 011:计数器向上计数达到最大值时将引脚置1,达到0时,引脚电平置0,,对不?

详解STM32定时器

1.STM32的Timer简介 STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。其中系统嘀嗒定时器是前文中所描述的SysTick,看门狗定时器以后再详细研究。今天主要是研究剩下的8个定时器。 其中TIM1和TIM8是能够产生3对PWM互补输出的高级登时其,常用于三相电机的驱动,时钟由APB2的输出产生。TIM2-TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。由于STM32的TIMER功能太复杂了,所以只能一点一点的学习。因此今天就从最简单的开始学习起,也就是TIM2-TIM5普通定时器的定时功能。 2.普通定时器TIM2-TIM5 2.1时钟来源 计数器时钟可以由下列时钟源提供: ·内部时钟(CK_INT) ·外部时钟模式1:外部输入脚(TIx) ·外部时钟模式2:外部触发输入(ETR) ·内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。 由于今天的学习是最基本的定时功能,所以采用内部时钟。TIM2-TIM5的时钟不是直接来自于APB1,而是来自于输入为APB1的一个倍频器。这个倍频器的作用是:当APB1的预分频系数为1时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当APB1的预分频系数为其他数值时(即预分频系数为2、4、8或16),这个倍频器起作用,定时器的时钟频率等于APB1的频率的2倍。APB1的分频在STM32_SYSTICK的学习笔记中有详细描述。通过倍频器给定时器时钟的好处是:APB1不但要给TIM2-TIM5提供时钟,还要为其他的外设提供时钟;设置这个倍频器可以保证在其他外设使用较低时钟频率时,TIM2-TIM5仍然可以得到较高的时钟频率。 2.2计数器模式

STM32通用定时器_15-1-6

通用定时器的相关配置 1、预装入(Preload) 预装入实际上是设置TIMx_ARR寄存器有没有缓冲,根据“The auto-reload register is preloaded。Writing to or reading from the auto-reload register accesses the preload register。”可知: 1)如果预装入允许,则对自动重装寄存器的读写是对预装入寄存器的存取,自动重装寄存器的值在更新事件后更新; 2)如果预装入不允许,则对自动重装寄存器的读写是直接修改其本身,自动重装寄存器的值立刻更新; 3)设置方式:TIMx_CR1 →ARPE(1) 2、更新事件(UEV) 1)产生条件:①定时器溢出 ②TIMx_CR1→ UDIS = 0 ③或者:软件产生,TIMx_EGR→ UG = 1 2)更新事件产生后,所有寄存器都被“清零”,注意预分频器计数 器也被清零(但是预分频系数不变)。若在中心对称模式下或DIR=0(向上计数)则计数器被清零;若DIR=1(向下计数)则计数器取TIMx_ARR的值。 3)注意URS(复位为0)位的选择,如下:

如果是软件产生更新,则URS→1,这样就不会产生更新请求 和DMA请求。 4)更新标志位(UIF)根据URS的选择置位。 5)可以通过软件来失能更新事件: 3、计数器(Counter) 计数器由预分频器的输出时钟(CK_CNT)驱动,TIMx_CR1→CEN = 1 使能,注意:真正的计数使能信号(CNT_EN)在 CEN 置位后一个周期开始有效。 4、预分频器(Prescaler) 预分频器用来对时钟进行分频,分频值由TIMx_PSC决定,计数器的时钟频率CK_CNT= fCK_PSC / (PSC[15:0] + 1)。 根据“It can be changed on the fly as this control register

stm32定时器的区别

STM32高级定时器、通用定时器(TIMx) 、基本定时器(TIM6和TIM7) 区别? 高级定时器TIM1和TIM8、通用定时器(TIM2,TIM3,TIM4,TIM5) 、基本定时器(TIM6和TIM7) 区别? TIM1和TIM8主要特性TIM1和TIM8定时器的功能包括: ● 16位向上、向下、向上/下自动装载计数器 ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值 ● 多达4个独立通道:─ 输入捕获─ 输出比较─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出 ● 死区时间可编程的互补输出 ● 使用外部信号控制定时器和定时器互联的同步电路 ● 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器 ● 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态 ● 如下事件发生时产生中断/DMA:─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获─ 输出比较─ 刹车信号输入 ● 支持针对定位的增量(正交)编码器和霍尔传感器电路 ● 触发输入作为外部时钟或者按周期的电流管理 TIMx主要功能通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括: ● 16位向上、向下、向上/向下自动装载计数器 ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值 ● 4个独立通道:─ 输入捕获─ 输出比较─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出 ● 使用外部信号控制定时器和定时器互连的同步电路 ● 如下事件发生时产生中断/DMA:─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获─ 输出比较 ● 支持针对定位的增量(正交)编码器和霍尔传感器电路 ● 触发输入作为外部时钟或者按周期的电流管理 TIM6和TIM7的主要特性TIM6和TIM7定时器的主要功能包括: ● 16位自动重装载累加计数器 ● 16位可编程(可实时修改)预分频器,用于对输入的时钟按系数为1~65536之间的任意数值分频 ● 触发DAC的同步电路注:此项是TIM6/7独有功能. ● 在更新事件(计数器溢出)时产生中断/DMA请求 强大,高级定时器应该是用于电机控制方面的吧

16位输入边沿定时捕获

源程序清单见程序清单1,其中黄色背景红色字体为错误的代码。 该程序的功能是测量方波信号的频率,由串口输出显示。 基本思路是:利用Timer0的TimerB的16位PWM功能产生一个方波作为被测信号,利用Timer2的TimerA定时捕捉功能捕捉被测信号的相邻两个上升沿,利用两次捕捉时的计数值计算出被测信号的频率。 程序清单1 实验源程序(有误) #include "systemInit.h" #include "uartGetPut.h" #include #include #define PART_LM3S1138 #include // 在CCP1管脚产生1KHz方波,为Timer2的16位输入边沿定时捕获功能提供时钟源 voidpulseInit(void) { SysCtlPeriEnable(SYSCTL_PERIPH_TIMER0); // 使能TIMER0模块 SysCtlPeriEnable(CCP1_PERIPH); // 使能CCP1所在的GPIO端口 GPIOPinTypeTimer(CCP1_PORT, CCP1_PIN); // 配置相关管脚为Timer功能 TimerConfigure(TIMER0_BASE, TIMER_CFG_16_BIT_PAIR | // 配置TimerB为16位PWM TIMER_CFG_B_PWM); TimerLoadSet(TIMER0_BASE, TIMER_B, 6000); // 设置TimerB初值 TimerMatchSet(TIMER0_BASE, TIMER_B, 3000); // 设置TimerB匹配值 TimerEnable(TIMER0_BASE, TIMER_B); } // 定时器16位输入边沿定时捕获功能初始化 voidtimerInitCapTime(void) { SysCtlPeriEnable(SYSCTL_PERIPH_TIMER2); // 使能Timer模块

STM32通用定时器

STM32通用定时器 一、定时器的基础知识 三种STM32定时器区别 通用定时器功能特点描述: STM3 的通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定时器功能特点包括: 位于低速的APB1总线上(APB1) 16 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数 为 1~65535 之间的任意数值。 4 个独立通道(TIMx_CH1~4),这些通道可以用来作为: ①输入捕获 ②输出比较 ③ PWM 生成(边缘或中间对齐模式) ④单脉冲模式输出 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。 如下事件发生时产生中断/DMA(6个独立的IRQ/DMA请求生成器): ①更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ②触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ③输入捕获 ④输出比较 ⑤支持针对定位的增量(正交)编码器和霍尔传感器电路 ⑥触发输入作为外部时钟或者按周期的电流管理 STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。 STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。 定时器框图:

倍频得到),外部时钟引脚,可以通过查看数据手册。也可以是TIMx_CHn,此时主要是实现捕获功能; 框图中间的时基单元 框图下面左右两部分分别是捕获输入模式和比较输出模式的框图,两者用的是同一引脚,不能同时使用。

STM32学习笔记通用定时器PWM输出

STM32学习笔记(5):通用定时器PWM输出 2011年3月30日TIMER输出PWM 1.TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。 STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。 1.1PWM输出模式 STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下: 110:PWM模式1-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。 111:PWM模式2-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电平。 由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。 而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。 1.2PWM输出管脚 PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7 定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如

STM32定时时间的计算

STM32 定时器定时时间的计算 假设系统时钟是72Mhz,TIM1 是由PCLK2 (72MHz)得到,TIM2-7是由 PCLK1 得到关键是设定时钟预分频数,自动重装载寄存器周期的值/*每1秒发生一次更新事件(进入中断服务程序)。RCC_Configuration()的SystemInit()的 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2表明TIM3CLK为72MHz。因此,每次进入中断服务程序间隔时间为: ((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+7199)/72M)*(1+9999)=1秒。定时器的基本设置如下: 1、TIM_TimeBaseStructure.TIM_Prescaler = 7199;//时钟预分频数例如:时钟频率=72/(时钟预分频+1)。 2、TIM_TimeBaseStructure.TIM_Period = 9999; // 自动重装载寄存器周期的值(定时时间)累计 0xFFFF个频率后产生个更新或者中断(也是说定时时间到)。 3、TIM_TimeBaseStructure.TIM_CounterMode=TIM1_CounterMode_Up; //定时器模式向上计数。 4、 TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时间分割值。 5、 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//初始化定时器2。 6、 TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //打开中断溢出中断。 7、 TIM_Cmd(TIM2, ENABLE);//打开定时器或者: TIM_TimeBaseStructure.TIM_Prescaler = 35999;//分频35999,72M/ (35999+1)/2=1Hz 1秒中断溢出一次。 8、 TIM_TimeBaseStructure.TIM_Period = 2000; //计数值2000 ((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+35999)/72M)*(1+2000)=1秒。 9、注意使用不同定时器时,要注意对应的时钟频率。例如TIM2对应的是APB1,而TIM1对应的是APB2 通用定时器实现简单定时功能 以TIME3为例作为说明,简单定时器的配置如下: void TIM3_Config(void) { TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure; TIM_DeInit(TIM3); //复位TIM2定时器 /* TIM2 clock enable [TIM2定时器允许]*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* TIM2 configuration */ TIM_TimeBaseStructure.TIM_Period = 49; // 0.05s定时 TIM_TimeBaseStructure.TIM_Prescaler = 35999; // 分频36000 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分割TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数方向向上计数 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Clear TIM2 update pending flag[清除TIM2溢出中断标志] */

输入捕捉

6. avr定时器/计数器1 --TC1 --输入捕捉模式(捕获外部事件模式) T/C 的输入捕捉单元可用来捕获外部事件,并为其赋予时间标记以说明此时间的发生时刻。外部事件发生的触发信号由引脚ICP1 (PD6)输入,也可通过模拟比较器单元来实现。时间标记可用来计算频率、占空比及信号的其它特征,以及为事件创建日志。当引脚ICP1 上的逻辑电平( 事件) 发生了变化,或模拟比较器输出ACO 电平发生了变化,并且这个电平变化为边沿检测器所证实,输入捕捉即被激发:16 位的TCNT1 数据被拷贝到输入捕捉寄存器ICR1,同时输入捕捉标志位ICF1 置位。如果此时ICIE1 = 1,输入捕捉标志将产生输入捕捉中断。中断执行时ICF1 自动清零,或者也可通过软件在其对应的I/O 位置写入逻辑"1”清零。读取ICR1 时要先读低字节ICR1L,然后再读高字节ICR1H。读低字节时,高字节被复制到高字节临时寄存器TEMP。CPU 读取ICR1H 时将访问TEMP 寄存器。 操作步骤: 一、捕获输入端口初始化:捕获输入端ICP1(PD6)设为输入,DDRD&=(0< #include #define uchar unsigned char #define uint unsigned int #define beep_0 (PORTD=PORTD&0x7f) //PD7上的蜂鸣器发声 #define beep_1 (PORTD=PORTD|0x80) //PD7上的蜂鸣器不发声 uint count; /********以下是延时函数********/ void Delay_ms(uint xms) { int i,j; for(i=0;i

STM32的捕获模式应用

STM32捕获模式应用。。。。。 1、stm32脉冲方波捕获 脉冲方波长度捕获 a)目的:基础PWM输入也叫捕获,以及中断配合应用。使用前一章的输出管脚P B1(19脚),直接使用跳线连接输入的PA3(13脚),配置为TIM2_CH4,进行实验。 b)对于简单的PWM输入应用,暂时无需考虑TIM1的高级功能之区别,按照目前我的应用目标其实只需要采集高电平宽度,而不必知道周期,所以并不采用PWM 输入模式,而是普通脉宽捕获模式。 c)初始化函数定义: void TIM_Configuration(void); //定义TIM初始化函数 d)初始化函数调用: TIM_Configuration(); //TIM初始化函数调用 e)初始化函数,不同于前面模块,TIM的CAP初始化分为三部分——计时器基本初始化、通道初始化和时钟启动初始化: void TIM_Configuration(void)//TIM2的CAP初始化函数 { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定时器初始化结构 TIM_ICInitTypeDef TIM_ICInitStructure; //通道输入初始化结构 //TIM2输出初始化 TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //周期0~FFFF TIM_TimeBaseStructure.TIM_Prescaler = 5; //时钟分频 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式

STM32F103ve定时器时间算法

S TM32 定时器定时时间的计算 2010-11-18 14:12:18| 分类:资料引用| 标签:|字号大中小订阅 引用 mxpopstar 的STM32 定时器定时时间的计算 假设系统时钟是72Mhz,TIM1 是由PCLK2 (72MHz)得到,TIM2-7是由PCLK1 得到 关键是设定时钟预分频数,自动重装载寄存器周期的值 /*每1秒发生一次更新事件(进入中断服务程序)。 RCC_Configuration()的SystemInit()的 RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2表明 TIM3CLK为72MHz。因此,每次进入中断服务程序间隔时间为((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+7199)/72M)*(1 +9999)=1秒*/ 定时器的基本设置 1、TIM_TimeBaseStructure.TIM_Prescaler = 7199;//时钟预分频数例如:时钟频率=72/(时钟预分频+1)

2、TIM_TimeBaseStructure.TIM_Period = 9999; // 自动重装载寄存器周期的值(定时时间) 累计0xFFFF个频率后产生个更新或者中断(也是说定时时间到) 3、TIM_TimeBaseStructure.TIM_CounterMode = TIM1_CounterMode_Up; //定时器 模式向上计数 4、TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时间分割值 5、TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//初始化定时器2 6、TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //打开中断溢出中断 7、TIM_Cmd(TIM2, ENABLE);//打开定时器 或者: TIM_TimeBaseStructure.TIM_Prescaler = 35999;//分频35999 72M/ (35999+1)/2=1Hz 1秒中断溢出一次

STM32通用定时器学习

STM32通用定时器 STM32的定时器功能很强大,学习起来也很费劲儿. 其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册…}才搞明白的!所以接下来我以手册的顺序为主线,增加一些自己的理解,并通过11个例程对TIMER做个剖析。实验环境是STM103V100的实验板,MDK3.2 +Library2.东西都不怎么新,凑合用…… TIMER主要是由三部分组成: 1、时基单元。 2、输入捕获。 3、输出比较。 还有两种模式控制功能:从模式控制和主模式控制。 一、框图 让我们看下手册,一开始是定时器的框图,这里面几乎包含了所有定时器的信息,您要是能看明白,那么接下来就不用再看别的了… 为了方便的看图,我对里面出现的名词和符号做个注解: TIMx_ETR:TIMER外部触发引脚 ETR:外部触发输入 ETRP:分频后的外部触发输入 ETRF:滤波后的外部触发输入 ITRx:内部触发x(由另外的定时器触发) TI1F_ED:TI1的边沿检测器。 TI1FP1/2:滤波后定时器1/2的输入 TRGI:触发输入 TRGO:触发输出 CK_PSC:应该叫分频器时钟输入 CK_CNT:定时器时钟。(定时周期的计算就靠它) TIMx_CHx:TIMER的输入脚 TIx:应该叫做定时器输入信号x ICx:输入比较x ICxPS:分频后的ICx OCx:输出捕获x OCxREF:输出参考信号 关于框图还有以下几点要注意: 1、影子寄存器。 有阴影的寄存器,表示在物理上这个寄存器对应2个寄存器,一个是程序员可以写入或读出的寄存器,称为preload register(预 装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的 寄存器,称为shadow register(影子寄存器);(详细请参考版主博客 https://www.doczj.com/doc/5215417259.html,/STM32/401461/message.aspx) 2、输入滤波机制 在ETR何TIx输入端有个输入滤波器,它的作用是以采样频率 Fdts来采样N次进行滤波的。(具体也请参考版主博客 https://www.doczj.com/doc/5215417259.html,/STM32/263170/message.aspx) 3、输入引脚和输出引脚是相同的。 二、时基单元 时基单元有三个部分:CNT、PSC、ARR。CNT的计数方式分三种:向上、

MSP430定时器A捕捉脉实例

MSP430定时器A捕捉脉实例[调试通过,很好用] 微控论坛原创主贴作者:fangth Microcontrol CODE /***************************************************************** //功能:利用定时器A的捕捉能测量脉冲信号的脉宽 // // // MSP430F449 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | P1.5/ACLK|---+ // | | | // | P2.0/TA2|<--+ // | | // | | //说明:ACLK要进行8分频(4K),并将其作为外部的要捕获的脉冲; //MCLK=SMCLK=8M; *****************************************************************/ #include int pwm_start,pwm_end,pwm_wide=0; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR = 0x20; // P1.5 输出 P1SEL = 0x20; // P1.5输出ACLK P2SEL|=BIT0; //P2.0 CCI2A SCFI0 |= FN_4; SCFQCTL = 121; // (121+1) ×32768 *2= 7.99Mhz FLL_CTL0=DCOPLUS+OSCCAP1; //MCLK=SMCLK=8M FLL_CTL1 |= FLL_DIV_8; //ACLK要进行8分频,ACLK=4K TACCTL2 =CAP+CM_3+CCIS_0+SCS+CCIE; //捕获模式,上升和下降都捕获,选择CCI2A,同步,捕获中断开 //Capture input select: 0 - CCI2A

相关主题
文本预览
相关文档 最新文档