完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
看了一些网上讲死区时间计算的教程,觉得讲述的不是很清楚,所以在此用我自己理解的方式讲述一遍,如有错误,请读者赐教。
死区时间的设置:由寄存器“TIM1和TIM8刹车和死区寄存器TIMX_BDTR”中,位DTG[7:0]控制(中文数据手册可能出现错误,应当是DTG)。 官方数据手册的说明不容易看懂,举的例子与我的应用场合也不一致,我使用的是72MHz的晶振,讲一讲我的死区时间是怎么算出来的。 DT死区时间; TDTS为系统时钟周期时长; TDTG为系统周期时长乘以倍数,这个值用于计算最终死区时间,也叫作步长。 在72M的定时器时钟下,TDTS = 1/72M = 13.89ns。 这个计算比较复杂,主要思想就是把DTG的八位,掰成两半用。一半决定步长,另一半是与步长相乘的乘数,乘数可以自行设定,步长*乘数=死区时间。至于步长与乘数从哪里分开,看下表 [tr]项目情况1情况2情况3情况4[/tr]
接下来举例说明表格怎么用。 例如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); } |
||||
|
||||
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1602 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1536 浏览 1 评论
967 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
680 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1579 浏览 2 评论
1861浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
642浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
514浏览 3评论
528浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
501浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-19 20:27 , Processed in 0.878915 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号