STM32F103高级定时器死区时间的计算

发布者:xrmilk最新更新时间:2019-03-14 来源: eefocus关键字:STM32F103  高级定时器  死区时间 手机看文章 扫描二维码
随时随地手机看文章

看了一些网上讲死区时间计算的教程,觉得讲述的不是很清楚,所以在此用我自己理解的方式讲述一遍,如有错误,请读者赐教。


  死区时间的设置:由寄存器“TIM1和TIM8刹车和死区寄存器TIMX_BDTR”中,位DTG[7:0]控制(中文数据手册可能出现错误,应当是DTG)。


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


  官方数据手册的说明不容易看懂,举的例子与我的应用场合也不一致,我使用的是72MHz的晶振,讲一讲我的死区时间是怎么算出来的。

DT死区时间;

TDTS为系统时钟周期时长;

TDTG为系统周期时长乘以倍数,这个值用于计算最终死区时间,也叫作步长。

在72M的定时器时钟下,TDTS = 1/72M = 13.89ns。


  这个计算比较复杂,主要思想就是把DTG的八位,掰成两半用。一半决定步长,另一半是与步长相乘的乘数,乘数可以自行设定,步长*乘数=死区时间。至于步长与乘数从哪里分开,看下表


项目 情况1 情况2 情况3 情况4

步长位置 DTG[7] DTG[7:6] DTG[7:5] DTG[7:5]

步长值(二进制) 1 10 110 111

步长是周期几倍 1 2 8 16

乘数位置 DTG[6:0] DTG[5:0] DTG[4:0] DTG[4:0]

乘数最大值 127 64+63 63+31 32+31

乘数范围 0~127 64~127 32~63 34~63

等价几倍周期 0~127 128~254 256~504 512~1008

周期125ns时,死区范围ns 0~15875 16000~31750 32000~63000 64000~126000

周期13.89ns时,死区范围ns 0~1764 1778~3528 3556~7000 7112~14001

接下来举例说明表格怎么用。


  例如72MHz的晶振,需要14us的死区时间,那么属于情况4,DTG[7:5] = 0b111,DTG[4:0]=31=0b1111,所以DTG = 0xff。72MH晶振的情况下,最大只能14us的死区。


  还是72MHz的晶振,需要3us的死区时间,那么属于情况2,DTG[7:6] = 0b10,步长=27.78,需要的乘数 = 3000÷27.78-64=108-64=44=0b101100,DTG[7:0]=0b10101100=0xAC。


  实际的系统中,死区的时间一般由硬件的响应速度决定。我的系统使用的驱动电路设计参考之前的博客


  使用的电机型号是JGB37-3530B。经过测试,3us的死区时间可以使用。


  下边是电机初始化的函数,主要的功能是用STM32的高级定时器TIM1,输出嵌入死区的互补PWM。


  使用两个通道输出PWM,通道1 的引脚是PA8和PB13,通道2 的引脚是PA9和PB14。一个周期是1ms,频率是1KHz,3us的死区时间。默认通道1的占空比是50%,通道2的占空比是0%,让电机以49.7%(占空比减去死区)的速度正转。


void PWM_Configuration(void)

{

    GPIO_InitTypeDef    GPIO_InitStructure;

    TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;

    TIM_OCInitTypeDef TIM_OCInitStructure;

    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    //开启TIM和相应端口时钟

    //启动GPIO

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_GPIOB,ENABLE);

    //启动AFIO

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    //启动TIM1

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);


    //GPIO做相应设置,为AF输出             //PA8,PB13一组互补输出  A9,PB14一组互补输出

    //PA.8/9口设置为TIM1的OC1输出口

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //PB.13/14口设置为TIM1_CH1N和TIM1_CH2N输出口

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_SetBits(GPIOA, GPIO_Pin_8 | GPIO_Pin_9);

    GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14);


    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);    

    NVIC_InitStructure.NVIC_IRQChannel =  TIM1_UP_IRQn;    

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  

    NVIC_Init(&NVIC_InitStructure);


    //TIM1基本计数器设置(设置PWM频率)1KHz 

    TIM_BaseInitStructure.TIM_Period = 1000-1;      //1khz  好计算。按照1%的精确度,理论最大72000/100 = 720KHz

    TIM_BaseInitStructure.TIM_Prescaler = 72-1;

    TIM_BaseInitStructure.TIM_ClockDivision = 0;

    TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数

    TIM_BaseInitStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM1, &TIM_BaseInitStructure);

    //启用ARR的影子寄存器(直到产生更新事件才更改设置)

    TIM_ARRPreloadConfig(TIM1, ENABLE);


    //TIM1_OC1模块设置(设置1通道占空比)

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//TIM脉冲宽度调制模式1

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出通道使能

    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//互补输出

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//TIM输出比较极性高

    //TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;

    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;

    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

    TIM_OCInitStructure.TIM_Pulse = 500;//待装入捕获比较寄存器的脉冲值

    TIM_OC1Init(TIM1, &TIM_OCInitStructure);


    //启用CCR1寄存器的影子寄存器(直到产生更新事件才更改设置)

    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);


    

    //TIM1_OC2模块设置(设置2通道占空比)

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;

    TIM_OCInitStructure.TIM_Pulse = 0;

    TIM_OC2Init(TIM1, &TIM_OCInitStructure);

    //启用CCR2寄存器的影子寄存器(直到产生更新事件才更改设置)

    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);


    //OCx输出信号与参考信号相同,只是它的上升沿相对参考信号的上升沿有一个延迟

    //OCxN输出信号与参考信号相同,只是它的上升沿相对参考信号的下降沿有一个延迟


    //死区设置

    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;

    TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;

    TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_2;

    TIM_BDTRInitStructure.TIM_DeadTime = 0xAC; //这里调整死区大小为3us      

    TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;

    TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;

    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;

    TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);


    //TIM1_OC通道输出PWM

    TIM_CtrlPWMOutputs(TIM1, ENABLE);


    //TIM1开启

    TIM_Cmd(TIM1, ENABLE);

}



关键字:STM32F103  高级定时器  死区时间 引用地址:STM32F103高级定时器死区时间的计算

上一篇:STM32F4四路ADC采样问题探讨
下一篇:STM32定时器库函数讲解

推荐阅读最新更新时间:2024-03-16 16:25

STM32F103 硬件I2C主从机通信
官方例程并没有像网上大多数代码在IIC中断里面调用库函数来发,而是采用判断寄存器的值来处理数据的收发等,所以在阅读官方的的代码前最好准备stm32参考手册,主要就是SR1,SR2,这两个寄存器。 在官方例程里面默认是主机的读写,我做的是主机读取从机的内容。当然,简单改下就可以实现主机向从机写数据。 主机先使能中断和方向、地址。 之后就发送开始条件。 最后中断接收 下面从机初始化后,所有的数据接收、发送都在中断里面处理。从机发送 从机接收 最后通信成功 这是从机需要发送的数据。 哈哈哈。。。还有些函数需要再封装一下。 下一步就是在I2C总线上再挂几个单片机。 代码贴在这: https://down
[单片机]
<font color='red'>STM32F103</font> 硬件I2C主从机通信
基于使用STM32F103单片机,实现64Mbit单对单通信
简单的一种应用,ARM芯片作为master,flash为slaver,实现单对单通信。ARM主控芯片STM32F103,flash芯片为MACRONIX INTERNATIONAL的MX25L6465E,64Mbit。 SPI应该是嵌入式外围中最简单的一种应用了吧!一般SPI应用有两种方法:软件仿真,手动模拟产生时序和应用主控芯片的SPI控制器。 一般采用第二种方法比较好,比较稳定。应用主控芯片的SPI控制器,要点:正确的初始化SPI、操作SPI各寄存器和正确理解flash的时序。下面是过程,采用的是STM32F10X自带的库函数 1、初始化:void SpiFlashIniTIalzaTIon(void); 要知道硬件是
[单片机]
基于使用<font color='red'>STM32F103</font>单片机,实现64Mbit单对单通信
STM32F103RB 实作笔记(九)- PWM + SPI +MAX6675 整合试验
个人工作上的关系,需要做一款温度控制风扇速度的控制器,还需要能够看到温度和PWM的值。于是我用这个不熟悉的 STM32F103 试试,顺便把 PWM 和 SPI 也了解一番。 一开始当然也是跌跌撞撞,搞了很久才弄清楚。这篇笔记记录怎么做好的过程。 实验的过程是以正点原子 STM32F103 nano开发板和他附上的练习程式开始。 参考 NANO 的程式 依照正点原子的教材,跑了一下 nano 程式,执行了 OK!原来的程式里面 PWM 用 TIM3 的 channel_1 控制 PC6 的 LED 闪烁。SPI 是用 SPI2 控制 W25Q16 进行读写。 由于 PWM 和 SPI2 都被开发板占有,我选了另外一组 TI
[单片机]
<font color='red'>STM32F103</font>RB 实作笔记(九)- PWM + SPI +MAX6675 整合试验
基于PCI-9846H的死区时间引起的电压波形畸变的研究
  挑战   目前国内外基于电机模型建立的控制策略在电机的低速脉动、高速弱磁、稳定性和输出转矩一致性等方面还存在诸多问题。为了能更好的解决电机的低速转矩脉动的问题,本文建立了引入逆变器死区时间的电机模型,逆变器死区时间很短并且IGBT的开关过程还存在延时和滞后的问题,为了能够准确的捕捉死区时间引起的电压波形畸变,要求数据采集卡有很高的采样率,除此之外,为了使研究结果更加精确,需要板卡具有较高的信噪比以及有效位。综上所述,在死区时间引起的电压波形畸变的研究中,需要一块高采样率、高精度以及高信噪比的板卡以满足对信号捕捉的要求。   解决方案   首先对死区效应进行分析,针对仿真结果提出一种减小死区时间引起电压波形畸变的方法,通过应用具
[嵌入式]
STM32F103_GPIO输入输出快速初始化
main.c文件 #include sys.h #include delay.h #include gpio.h uint8_t GetCNState; int main(void) { delay_init(); //延时函数初始化 GPIO_Quick_Init(GPIOA_Pin0,GPIO_Mode_Out_PP,1); //初始化A0为推挽输出模式,开始电平为1 GPIO_Quick_Init(GPIOB_Pin1,GPIO_Mode_Out_PP,0); //初始化B1为推挽输出模式, 开始电平为0 GPIO_Quick_Init(GPIO
[单片机]
STM32F103ZET6的引脚分类和几个需要特殊注意的引脚总结
前言 本博文基于STM32F103ZET6编写; 如有不足之处,多多指教; 多功能引脚图 下图为STM32芯片引脚细节图 由图片可知,STM32大部分GPIO都有复用功能,所以在配置的时候要格外小心; 下图为**《STM32大容量手册》引脚功能分类图** 引脚分类(按照我自己理解给分的类) 第一类:非GPIO单功能引脚 电源引脚Vdd; 接地引脚Vss; 芯片掉电保持引脚VBAT; 外部晶振引脚OSC_IN和OSC_OUT; 空引脚NC; 复位引脚NRST; 参考电压引脚VREF+和VREF-; BOOT0引脚; 特点: 这列引脚往往在Pin name这栏中都是以本身的功能名命名; 第二类:GPIO单功能引脚
[单片机]
<font color='red'>STM32F103</font>ZET6的引脚分类和几个需要特殊注意的引脚总结
浅谈CC1101驱动在STM32F103的移植
本文主要是关于CC1101的相关介绍,并着重对CC1101驱动在STM32F103的移植进行了详尽的阐述。 浅谈CC1101驱动在STM32F103的移植 首先明确:CC1101是通过SPI与MCU进行通信的。根据从TI官方上获得CC1101驱动,直接先移植SPI部分,STM32F103提供了SPI1和SPI2两条SPI总线,可自行选择,对于SPI的移植,直接参考STM32开发板上关于通过SPI操作Flash示例代码,对于SPI的配置与TI提供的驱动代码里的SPI配置保持一致。SPI移植完成之后,接上CC1101射频模块,测试SPI是否能正常通信,主要通过向CC1101任意可读可写寄存器写一个任意值,然后再读出该寄存器里的值,
[单片机]
浅谈CC1101驱动在<font color='red'>STM32F103</font>的移植
学习stm32f103(二) 关于系统时钟
stm32中可以选择多种时钟源,可以参考stm32数据手册,这里手册中的时钟图 而在stm32f103系列的说明中,可知系统最高可以达到72M的主频,(f407等可以达到更高的主频),为了强大的性能,在不考虑功耗的前提下当然要选择72M作为我们系统的主频咯,关键是怎么来设置呢? 这里一般stm32外部有一颗8Mhz 的晶振作为芯片HSE时钟的输入,再配合PLL将HSE倍频到72M就ok了,具体怎么设置可以查看手册的相关寄存器,但这里就不劳神去看了,查看我们配置好的工程,在给的库中已经有相关的工作了。 打开starup_stm32f10x_md.s(不同芯片可能不同)文件,可以看见这是一个用来启动的汇编文件。 Reset
[单片机]
学习<font color='red'>stm32f103</font>(二) 关于系统时钟
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved