您的位置 首页 动态

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

明确一点对比AD的构造,stm32有3个AD,每个AD有很多通道,使用哪个通道就配置成哪个通道,这里定时器也如此,有很多定时器TIMx,每个定时器有

清晰一点比照AD的结构,stm32有3个AD,每个AD有许多通道,运用哪个通道就装备成哪个通道,这儿守时器也如此,有许多守时器TIMx,每个守时器有许多CHx(通道),能够装备为输入捕捉——-丈量频率用,也能够装备为输出比较——–输出PWM运用

输入捕捉:能够用来捕获外部事情,并为其赋予时刻符号以阐明此事情的发生时刻。

外部事情发生的触发信号由单片机中对应的引脚输入(详细能够参阅单片机的datasheet),也能够经过模仿比较器单元来完成。

时刻符号可用来核算频率,占空比及信号的其他特征,以及为事情创立日志,首要是用来丈量外部信号的频率。

输出比较:守时器中计数寄存器在初始化完后会主动的计数。从bottom计数到top。而且有不同的作业形式。

别的还有个比较寄存器。一旦计数寄存器在从bottom到top计数进程中与比较寄存器匹配则会发生比较中止(比较中止使能的状况下)。

然后依据不同的作业形式计数寄存器将清零或许计数到top值。

1、朋友,能够解释一下输入捕获的作业原理不?

很简单,当你设置的捕获开端的时分,cpu会将计数寄存器的值仿制到捕获比较寄存器中并开端计数,当再次捕捉到电平变化时,这是计数寄存器中的值减去方才仿制的值便是这段电平的持续时刻,你能够设置上升沿捕获、下降沿捕获、或许上升沿下降沿都捕获。它没多大用途,最常用来测频率。

计数寄存器的初值,是自己写进去的吗?

是的,不过默许不要写入

我假如捕获上升沿,两个值相减,代表的时两个上升沿中心那段电平的时刻。对不?

是的

timer1有五个通道(对应五个IO引脚),在同一时刻,只能捕获一个引脚的值,对不?

那是必定的,通道很像ADC通道,是能够进行切换的。

那输出比较的原理你能够帮我介绍一下不?

这儿有两个单元:一个计数器单元和一个比较单元,比较单元便是个双缓冲寄存器,比较单元的值是能够依据不同的形式设置的,与此一起,计数器在不断的计数,并不断的与比较寄存器中的值进行比较,当计数器的值与比较寄存器的值持平的时分一个比较匹配就发生了,依据自己的设置,匹配了是io电平取反、变低、仍是变高,就会发生不同的波形了。

比较单元的值是人为设进去的吧?

是的,可是他要依据你的操控寄存器的装备,来初始化你的比较匹配寄存器。

上面这个总看不懂,如同不不止你说的那几种状况:“匹配了是io电平取反、变低、仍是变高,就会发生不同的波形了”

便是比较匹配了你要IO电平怎样办?是清0仍是置1?仍是怎样样?这样才干发生波形啊要不然你要比较单元有什么用呢?

设置输出便是置1,铲除输出便是置0,切换输出便是将本来的电平取反,对不?

是的你了解的很快

011:计数器向上计数到达最大值时将引脚置1,到达0时,引脚电平置0,,对不?

守时器1的输出比较形式怎样用。运用这个功用输出一个1KHZ,占空比为10%的程序怎样写啊?求高人点拨

1、陪守时器1的功用为特别功用,不是一般IO在PERCFG这儿
2、P1SEL引脚挑选
3、P1DIR设为输出
4、T3CC0设置周期
5、T3CC1设置占空比
6、T3CCTL0 设置通道0
7、T3CCTL1 设置通道1
8、T3CTL设为模形式
9、用T3CTL翻开即可

************以下是用守时器做频率源,用守时器丈量该频率的应用程序!!!***********

调试STM32的守时器好几天了,也算是对STM32的守时器有了点清楚的认识了。我需求丈量4路信号的频率然后经过DMA将信号的频率传输到存储器区域,手册说的很了解每个守时器有4个独立通道。然后我就想能不能将这4路信号都连接到一个守时器的4个通道上去。理论上应该是行的通的。刚开端俺运用的是 TIM2的123通道,TIM4的2通道来进行频率的丈量。因为没有频率发生器,所以我用tim3作为信号源,用TIM2,TIM4来进行丈量就ok了(刚好4个通道了)。

  请看一开端的程序,以TIM2的1,3通道为比如(2通道设置方法相同):

  TIM_ICInitStructure.TIM_ICMode =TIM_ICMode_ICAP; //装备为输入捕获形式

  TIM_ICInitStructure.TIM_Channel =TIM_Channel_1; //挑选通道1

  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; //滤波

  TIM_ICInit(TIM2, &TIM_ICInitStructure); //TIM2通道1装备结束

  TIM_ICInitStructure.TIM_ICMode = TIM_ICMode_ICAP; //装备为输入捕获形式

  TIM_ICInitStructure.TIM_Channel =TIM_Channel_3; //挑选通道3

  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; //滤波

  TIM_ICInit(TIM2, &TIM_%&&&&&%InitStructure); //TIM2通道3装备结束

  以上是输入捕获装备

  还需求做的作业便是(参阅stm32参阅手册的TIM的结构框图):

  

  TIM_SelectInputTrigger(TIM2,TIM_TS_TI1FP1); //参阅TIM结构图挑选滤波后的TI1输入作为触发源,触发下面程序的复位

  

  TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset); //复位形式-选中的触发输入(TRGI)的上升沿初始化计数器,而且发生一个更新线号

  

  TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);

  //主从形式挑选

  这样咱们就能够很轻松的就得到了连接在TIM2的通道1上的信号的频率,可是3通道的频率的值永远都是跳动的禁绝,测试了半响也没有找到根本原因,请看TIM的结构框图的一部分

  赤色箭头所指,这才找到原因,触发的信号源只有这四种,而通道3上的计数器的值不行能在接受到信号的上升沿时分,有复位这个动作,找到原因了。这便是3 通道上的数据不断跳动的原因,要想得到信号的频率也是有方法的,能够取接连两次捕捉的值之差,这个值便是信号的周期,自己依据实际状况去算频率吧。

  有以上能够得到:

  stm32的TIM2的四个通道能够一起装备成输入捕捉形式,可是核算CH3,CH4信号的频率进程有点繁琐(取前后捕捉的差值),可是他的CH1,和CH2能够轻松得到:

  通道1

  

  TIM_SelectInputTrigger(TIM2,TIM_TS_TI1FP1); //参阅TIM结构图挑选滤波后的TI1输入作为触发源,触发下面程序的复位

  

  TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset); //复位形式-选中的触发输入(TRGI)的上升沿初始化计数器,而且发生一个更新线号

  TIMx->CRR1的值即为信号的周期

  通道2:

  TIM_SelectInputTrigger(TIM2,TIM_TS_TI2FP2); //参阅TIM结构图挑选滤波后的TI1输入作为触发源,触发下面程序的复位

  

  TIM_SelectSlaveMode(TIM2,TIM_SlaveMode_Reset); //复位形式-选中的触发输入(TRGI)的上升沿初始化计数器,而且发生一个更新线号

  TIMx->CRR2的值即为信号的周期

STM32的守时器外设功用强大得超出了想像力,STM32一共有8个都为16位的守时器。其间TIM6、TIM7是根本守时器;TIM2、TIM3、TIM4、TIM5是通用守时器;TIM1和TIM8是高档守时器。这些守时器使STM32具有守时、信号的频率丈量、信号的PWM丈量、PWM输出、三相6步电机操控及编码器接口等功用,都是专门为工控范畴量身订做的。
根本守时器:具有最根本的守时功用,下面是它的结构:

咱们来看看它的发动代码:
void TIM2_Configuration(void)
{ 根本守时器TIM2的守时装备的结构体(包括守时器装备的一切元素例如:TIM_Period= 计数值)
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
设置TIM2_CLK为72MHZ(即TIM2外设挂在APB1上,把它的时钟翻开。)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 ,ENABLE);
设置计数值位1000
TIM_TimeBaseStructure.TIM_Period=1000;
将TIM2_CLK为72MHZ除以72 = 1MHZ为守时器的计数频率
TIM_TimeBaseStructure.TIM_Prescaler= 71;
这个TIM_ClockDivision是设置时钟切割,这儿不切割仍是1MHZ的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
设置为向上计数模式;(计数形式有向上,向下,中心对齐1,中心对齐2,中心对齐3)
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
将装备好的设置放进stm32f10x-tim.c的库文件中
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
铲除标志位
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
使能TIM2中止
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
使能TIM2外设
TIM_Cmd(TIM2,ENABLE);
}
通用守时器:就比根本守时器杂乱得多了。除了根本的守时,它首要用在丈量输入脉冲的频率、脉冲宽与输出PWM脉冲的场合,还具有编码器的接口。

咱们来详细说明:怎么生成PWM脉冲
通用守时器能够运用GPIO引脚进行脉冲输出,在装备为比较输出、PWM输出功用时,捕获/比较寄存器TIMx_CCR被用作比较功用,下面把它简称为比较寄存器。
这儿直接举例阐明守时器的PWM输出作业进程:若装备脉冲计数器TIMx_CNT为向上计数,而重载寄存器TIMx_ARR(相当于库函数写法的TIM_Period的值N)被装备为N,即TIMx_CNT的当时计数值数值X在TIMxCLK时钟源的驱动下不断累加,当TIMx_CNT的数值X大于N时,会重置TIMx_CNT数值为0从头计数。
而在TIMxCNT计数的一起,TIMxCNT的计数值X会与比较寄存器TIMx_CCR预先存储了的数值A进行比较,当脉冲计数器TIMx_CNT的数值X小于比较寄存器TIMx_CCR的值A时,输出高电平(或低电平),相反地,当脉冲计数器的数值X大于或等于比较寄存器的值A时,输出低电平(或高电平)。
如此循环,得到的输出脉冲周期就为重载寄存器TIMx_ARR存储的数值(N+1)乘以触发脉冲的时钟周期,其脉冲宽度则为比较寄存器TIMx_CCR的值A乘以触发脉冲的时钟周期,即输出PWM的占空比为A/(N+1)。
假如不想看的能够直接看我标示的赤色字体,就大体能够了解。
下面咱们来编写详细代码和说明:
void TIM3_GPIO_Config(void)
{装备TIM3复用输出PWM的IO
GPIO_InitTypeDefGPIO_InitStructure;
翻开TIM3的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
翻开GPIOA和GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOB, ENABLE);
装备PA6.PA7的作业形式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6 |GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
装备PB0.PB1的作业形式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void TIM3_Mode_Config(void)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//初始化TIM3的时刻基数单位
TIM_OCInitTypeDefTIM_OCInitStructure;//初始化TIM3的外设

u16 CCR1_Val= 500;
u16 CCR2_Val= 375;
u16 CCR3_Val= 250;
u16 CCR4_Val= 125;//PWM信号电平跳变值(即计数到这个数值今后都是低电平之前都是高电平)

TIM3的时刻基数单位设置(如计数停止值:999,从0开端;计数方法:向上计数)
TIM_TimeBaseStructure.TIM_Period= 999;
TIM_TimeBaseStructure.TIM_Prescaler= 0;
TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1 ;
TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM3的外设的设置
TIM_OCInitStructure.TIM_OCMode= TIM_OCMode_PWM1; //TIM脉冲宽度调制形式1
TIM_OCInitStructure.TIM_OutputState= TIM_OutputState_Enable;//这个暂时不知道,stm32固件库里没有搜到。应该是守时器输出声明使能的意思
TIM_OCInitStructure.TIM_Pulse =CCR1_Val;//设置了待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity= TIM_OCPolarity_High; //TIM输出比较极性高
TIM_OC1Init(TIM3,&TIM_OCInitStructure);

TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能或许失能TIMx在CCR1上的预装载寄存器
下面3路PWM输出和上面的相同不再说明
TIM_OCInitStructure.TIM_OutputState= TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse =CCR2_Val;
TIM_OC2Init(TIM3,&TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);

TIM_OCInitStructure.TIM_OutputState= TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse =CCR3_Val;
TIM_OC3Init(TIM3,&TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);

TIM_OCInitStructure.TIM_OutputState= TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse =CCR4_Val;
TIM_OC4Init(TIM3,&TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);

TIM_ARRPreloadConfig(TIM3,ENABLE); //使能TIM3重载寄存器ARR

TIM_Cmd(TIM3,ENABLE);//使能TIM3
}
太累了边看边写都这个点了2014年7月27日0:24:13在自己床上写的。下面是看看咱们程序到达的4路PWM的作用:

能够看到显着占空比不同的4路pwm波。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/dongtai/263181.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部