赞
踩
目录
以下以F103为例。
高级定时器:TIM1、TIM8
时钟源选择:
- 内部时钟(CK_INT)。(来自APB2)
- 外部时钟模式1:外部输入引脚
- 外部时钟模式2:外部触发输入ETR
- 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器。如可以配置一个定时器Timer1作为另一个定时器Timer2的预分频器。
通用定时器:TIM2~5
时钟源选择同高级定时器。(但CK_INT来自APB1。APB1默认倍频,即72Mhz。)
基本定时器:TIM6、TIM7
时钟仅由内部时钟(CK_INT)提供。(APB1。APB1默认倍频,即72Mhz。)
(仅包含分频、计时、中断、DMA请求、触发DAC的同步电路)
定时器溢出时间:
Tout= ((arr+1)*(psc+1))/Tclk
Tclk为时钟频率
定时器代码示例:
- void Tim6_Init(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //使能TIM6时钟
- //Tout= ((arr+1)*(psc+1))/Tclk
- TIM_TimeBaseStructure.TIM_Period = 300-1;//周期300us
- TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//一次1us
- TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //采样分频
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
-
- TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE); //使能TIM6中断
- TIM_Cmd(TIM6, ENABLE); //使能定时器6
- //中断优先级分组
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
-
- NVIC_InitStructure.NVIC_IRQChannel =TIM6_IRQn;//TIM6中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);//中断初始化
- }
- void TIM6_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
- {
- TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清除更新中断标志位
-
- GPIOE->ODR^=GPIO_Pin_5;//将PB0电平反向
- }
- }
然后在需要的地方用下方代码启用定时器。定时器启用后会不停计时,中断后自动装载。
TIM_Cmd(TIM6, ENABLE);
高级定时器和通用定时器均可重映射,基本定时器不可重映射。
部分重映射:外设的所有默认引脚的部分引脚修改位置。
完全重映射:外设的所有默认引脚均修改位置。
如下图:
补充:io口和引脚区别
io口是指如GPIOA这样的引脚组
引脚指芯片外接的针脚
基本定时器没有主从模式。
可用以下宏一劳永逸,由于是宏,不会多占代码空间,不会多占运行资源。
- #define GetInternalTrigger(S,M) \
- (S == TIM1 ? (M == TIM5 ? TIM_TS_ITR0 : (M == TIM2 ? TIM_TS_ITR1 : (M == TIM3 ? TIM_TS_ITR2 :(M == TIM4 ? TIM_TS_ITR3 : (u16)-1)))): \
- (S == TIM8 ? (M == TIM1 ? TIM_TS_ITR0 : (M == TIM2 ? TIM_TS_ITR1 : (M == TIM4 ? TIM_TS_ITR2 :(M == TIM5 ? TIM_TS_ITR3 : (u16)-1)))): \
- (S == TIM2 ? (M == TIM1 ? TIM_TS_ITR0 : (M == TIM8 ? TIM_TS_ITR1 : (M == TIM3 ? TIM_TS_ITR2 :(M == TIM4 ? TIM_TS_ITR3 : (u16)-1)))): \
- (S == TIM3 ? (M == TIM1 ? TIM_TS_ITR0 : (M == TIM2 ? TIM_TS_ITR1 : (M == TIM5 ? TIM_TS_ITR2 :(M == TIM4 ? TIM_TS_ITR3 : (u16)-1)))): \
- (S == TIM4 ? (M == TIM1 ? TIM_TS_ITR0 : (M == TIM2 ? TIM_TS_ITR1 : (M == TIM3 ? TIM_TS_ITR2 :(M == TIM8 ? TIM_TS_ITR3 : (u16)-1)))): \
- (S == TIM5 ? (M == TIM2 ? TIM_TS_ITR0 : (M == TIM3 ? TIM_TS_ITR1 : (M == TIM4 ? TIM_TS_ITR2 :(M == TIM8 ? TIM_TS_ITR3 : (u16)-1)))): \
- (u16)-1))))))
-
- /*使用时, TIM_ITRxExternalClockConfig(TIM1,GetInternalTrigger(TIM1,TIM4));即可*/
每个高级定时器或部分通用定时器都可以产生4对中间信号,分别是TI1FP1 与TI1FP2,TI2FP1 与TI2FP2,TI3FP3 与TI3FP4,TI4FP3 与TI4FP4,即每个输入通道可以生产1对信号。这四对信号可以统一写为:TIxFPy,其中 x代表滤波和边沿检测器前的输入通道号,y代表经过滤波和边沿检测器后将要接入或者说要映射到的捕捉通道号。
TI1FP1,来自于通道TI1,经过滤波器后将接到捕捉比较通道IC1;
TI1FP2,来自于通道TI1,经过滤波器后将接到捕捉比较通道IC2;
TI2FP1,来自于通道TI2,经过滤波器后将接到捕捉比较通道IC1;
TI2FP2,来自于通道TI2,经过滤波器后将接到捕捉比较通道IC2;
………………
以TI1FP1和TI2FP2为例,如上图,二者都来自同一TI1输入通道,经过输入滤波和边沿检测器后所产生的具有相同特征的信号,然后映射到不同的输入捕捉通道,本质上还是同一路信号。
解读上图(以“仅在TI1计数”为例):相对信号(TI2)作为参考,当TI2为高电平时,检测TI1FP1电平。若检测到TI1FP1上升沿,则定时器的计数器向下计数(自减),即反转;若下降沿,则向上计数(自增),即正转。
一个脉冲对应一个上升沿和一个下降沿,如果采用双相(AB两相)计数、双边沿计数的话,会采集到4倍脉冲。此时脉冲数等于计数器得到的值/4,即下面的M0(脉冲数).
STM32定时器部分,有个PWM输入模式的应用介绍。专门介绍如何利用PWM输入模式测量某一路外部输入信号的频率和占空比的话题。这里正是利用TI1FP1与TI1FP2来自于同一通道TI1且TI1FP1可以作为从模式触发源的特点来完成的。通过该实例不难理解TI1FP1与TI1FP2的实质就是一个东西。【在不做过滤和反相处理的前提下,TI1=TIF1P1=TI1FP2】
注:PWM输入模式同时且仅使用了TI1和TI2,只有TI1FP1和TI2FP2接到了从模式控制器。
STM32的部分定时器(103的非基本定时器应该都有)中还集成了正交编码控制器,这个应用与TI1FP1和TI2PF2有关。即:要使用STM32内部正交编码功能,只能使用TI1和TI2两个输入通道。
如上图,没有编码器接口。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。