stm32的定时器输入捕获与输出比较Word文档格式.docx
《stm32的定时器输入捕获与输出比较Word文档格式.docx》由会员分享,可在线阅读,更多相关《stm32的定时器输入捕获与输出比较Word文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
可以用来捕获外部事件,并为其赋予时间标记以说明此事件的发生时刻。
外部事件发生的触发信号由单片机中对应的引脚输入(具体可以参考单片机的datasheet),也可以通过模拟比较器单元来实现。
时间标记可用来计算频率,占空比及信号的其他特征,以及为事件创建日志,主要是用来测量外部信号的频率。
输出比较:
定时器中计数寄存器在初始化完后会自动的计数。
从bottom计数到top。
并且有不同的工作模式。
另外还有个比较寄存器。
一旦计数寄存器在从bottom到top计数过程中与比较寄存器匹配则会产生比较中断(比较中断使能的情况下)。
然后根据不同的工作模式计数寄存器将清零或者计数到top值。
1、朋友,可以解释一下输入捕获的工作原理不?
很简单,当你设置的捕获开始的时候,cpu会将计数寄存器的值复制到捕获比较寄存器中并开始计数,当再次捕捉到电平变化时,这是计数寄存器中的值减去刚才复制的值就是这段电平的持续时间,你可以设置上升沿捕获、下降沿捕获、或者上升沿下降沿都捕获。
它没多大用处,最常用来测频率。
计数寄存器的初值,是自己写进去的吗?
是的,不过默认不要写入
我如果捕获上升沿,两个值相减,代表的时两个上升沿中间那段电平的时间。
对不?
是的
timer1有五个通道(对应五个IO引脚),在同一时刻,只能捕获一个引脚的值,对不?
那是肯定的,通道很像ADC通道,是可以进行切换的。
那输出比较的原理你可以帮我介绍一下不?
这里有两个单元:
一个计数器单元和一个比较单元,比较单元就是个双缓冲寄存器,比较单元的值是可以根据不同的模式设置的,与此同时,计数器在不停的计数,并不停的与比较寄存器中的值进行比较,当计数器的值与比较寄存器的值相等的时候一个比较匹配就发生了,根据自己的设置,匹配了是io电平取反、变低、还是变高,就会产生不同的波形了。
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_ICFilter=0x0;
//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
TIMx->
CRR1的值即为信号的周期
通道2:
TIM_SelectInputTrigger(TIM2,TIM_TS_TI2FP2);
CRR2的值即为信号的周期
STM32的定时器外设功能强大得超出了想像力,STM32一共有8个都为16位的定时器。
其中TIM6、TIM7是基本定时器;
TIM2、TIM3、TIM4、TIM5是通用定时器;
TIM1和TIM8是高级定时器。
这些定时器使STM32具有定时、信号的频率测量、信号的PWM测量、PWM输出、三相6步电机控制及编码器接口等功能,都是专门为工控领域量身订做的。
基本定时器:
具备最基本的定时功能,下面是它的结构:
我们来看看它的启动代码:
voidTIM2_Configuration(void)
{
基本定时器TIM2的定时配置的结构体(包含定时器配置的所有元素例如:
TIM_Period=计数值)
TIM_TimeBaseInitTypeDef
TIM_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)。
如果不想看的可以直接看我标注的红色字体,