STM32 时钟分割TIM_ClockDivision配置及使用详细说明

以STM32F4为例说明

TIM_ClockDivision:时钟分割,配置寄存器是TIM1->CR1

共有3种分割参数,这里CK_INT是指选择的时钟时基见图1-紫红色

CK_INT是用户选择的内部时钟,比如通用定时器=84MHz(当预分频系数为0时),那么CK_INT=84MHz,若预分频系数不为0,则按照相关计算得出CK_INT大小;那么tDTS就可以对应计算了

是用到定时器输入相关的功能才使用到的配置,如:

  1. 外部触发输入,见图1-红色框,涉及到的寄存器TIM1->SMCR
  2. 输入捕获功能,见图1-蓝色框,涉及到的寄存器TIM1->CCMR1
  3. 死区时间设定,见图1-绿色框,涉及到的寄存器TIM1->BDTR

图1

那我们看一下这3个寄存器,有关的配置

 

我们由上可知,这三个功能或寄存器都涉及到了tDTS(或者fDTS=1/tDTS)

这样我们就清楚了时钟分割的用处了,就在这3个方面

1.外部触发输入:这个实际用得少,就不说了

2.输入捕获:一般是测量一个信号的频率、占空比、脉宽等

这里以BLDC中捕获Hall信号来说明

BLDC中有6步驱动,每一步需要换相,而幻想的依据就是Hall信号发生跳变,在有感BLDC中使用输入捕获来检测HALL信号(当然有的会使用IO高低电平读取或采用外部中断来检测HALL信号)

配置参数:

//定时器相关

TIM_TimeBaseStructure.TIM_Prescaler =84-1;//时钟频率为1MHZ

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;

  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分割

      TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

//输入捕获相关

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge; //

  // listen to T1, the  HallSensorEvent

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;

  // Div:1, every edge

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

TIM_ICInitStructure.TIM_ICFilter = 15;//滤波器位值=15

  TIM_ICInit(TIM4, &TIM_ICInitStructure);

其它的相关配置,这里就不贴出来了

我们看到以上配置中有2个配置:配置分割系数,滤波器数值

(1)不分割就是说明CK_INT=84/84=1MHz,那么fTDS=1MHZ,tTDS=1us;

(2)滤波器数值=15,这要回到对应的寄存器中TIM1->CCMR1中,即IC1F[3:0]=1111b(2进制),可以到考到采样频率fSAMPLING=fTDS/32=1MHz/32=31.25KHz

根据奈奎斯特采样定律可知(至少2倍采样信号频率),被采样的频率最大为31.25KHz/2=15.625KHz,如果大于这个频率信号将不能被正常识别;

另外有一个N什么意思呢,手册中说:数字滤波器由事件计数器组成,每 N 个事件才视为一个有效边沿;

其实是指读取的电平信号持续多长时间才认为是有效电平信号,看下图

这里计数频率是1MHz,即t=1us,N=8即说明采集到高电平信号持续8us才能认为是有效高电平

设定分割频率,根据滤波系数决定的采样频率和N事件有利于滤除高频干扰信号

3.死区时间设定:这个以BLDC中高级定时器3路互补通道输出PWM为例

死区设定是防止半桥上下MOS同时导通,造成MOS烧坏,如下图1,因为MOS导通和关断是有时间限制的,虽然MCU输出的互补信号在高低电平上没有重叠,但是由于中间电路的延时和MOS本身特性导致最后驱动MOS的信号有开关重叠,如下图2

图1

图2

这样我们可以再定时器中配置互补信号输出的时序实现死区时间,不过这个时间一般200ns-2us,不能再大,有些电机应用中对这个要求更高,那要用死区补偿来优化

配置程序如下

  TIM_TimeBaseStructure.TIM_Prescaler = 0;

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;//中央对齐模式1

  TIM_TimeBaseStructure.TIM_Period = 5250;//设置周期

  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2;//2倍分割

  TIM_TimeBaseStructure.TIM_RepetitionCounter = REP_COUNTER;//重复计数器值

  TIM_BDTRInitStructure.TIM_DeadTime =(168*800)/1000/2;//800ns死区时间

其他下相关配置这里就不贴出来了

F4的高级定时器=168MHz,这里预分频系数=0,说明不变;分割系数=2,找到寄存器TIM1->CR1可知tTDS=2*tCK_INT,那么找到死区配置寄存器TIM1->BDTR,计算对应死区时间,这里设定死区时间=800ns

上面配置TIM_DeadTime =(168*800)/1000/2=67;

即DTG[7:0]=67=010 00011b(2进制)找到对应公式,符合第一条计算公式:DTG[7:5]=0xx=>…

DT=DTG[7:0]*tdtg, 其中DTG[7:0]=67,tdtg=2*tDTS,即tdtg=2*tCK_INT,

DT=67*2*(1/168000000)s=797ns

到这里就说完了TIM_ClockDivision分割系数在实际中的应用

  • 54
    点赞
  • 182
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
#include "remote.h" #include "delay.h" #include "usart.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK战舰STM32开发板 //红外遥控解码驱动 代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //修改日期:2012/9/12 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2009-2019 //All rights reserved ////////////////////////////////////////////////////////////////////////////////// u8 g_IR_RecFlag = 0; //红外接收到标志 //红外遥控初始化 //设置IO以及定时器4的输入捕获 void Remote_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能PORTB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //TIM4 时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PB9 输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //上拉输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO;_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_9); //初始化GPIOB.9 TIM_TimeBaseStructure.TIM_Period = 10000; //设定计数器自动重装值 最大10ms溢出 TIM_TimeBaseStructure.TIM_Prescaler =(35-1); //预分频器,1M的计数频率,1us加1. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM4, &TIM;_TimeBaseStructure); //根据指定的参数初始化TIMx TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; // 选择输入端 IC4映射到TI4上 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; //上升沿捕获..改为下降沿捕获 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 TIM_ICInitStructure.TIM_ICFilter = 0x03;//IC4F=0011 配置输入滤波器 8个定时器时钟周期滤波 TIM_ICInit(TIM4, &TIM;_ICInitStructure);//初始化定时器输入捕获通道 TIM_Cmd(TIM4,ENABLE ); //使能定时器4 NVIC_InitStructure.NV
#include "counter.h" #include "stdio.h" #include "usart.h" /*********************************************************************************************** //上升沿捕获 ************************************************************************************************/ TIM_ICInitTypeDef TIM3_ICInitStructure; void TIM3_counter_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM5时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PA7 清除之前设置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //PA7 浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_7); //PA7 下拉 //初始化定时器5 TIM5 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM5输入捕获参数 TIM3_ICInitStructure.TIM_Channel = TIM_Channel_2; // 选择输入端 IC1映射到TI1上 TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获 TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上 TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 TIM3_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 配置输入滤波器 不滤波 TIM_ICInit(TIM3, &TIM3_ICInitStructure);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值