历史上的今天
今天是:2024年09月27日(星期五)
2019年09月27日 | STM32——TIM死区互补PWM波输出
2019-09-27 来源:eefocus
于pwm波的输出实验老早之前就学了,一直拖到现在才写,,,。由于之前接触过32的高级定时器所以是先从死区pwm波开始学的,后面才学的pwm波。其实会发出死区pwm波了也就会发pwm波了。在学习32的某个功能时要先去看32的数据参考手册了解它的功能然后看它有哪些寄存器,对你需要用到的寄存器深入了解,最后看库函数进行编程。
要发出死区pwm波就要用到32的高级定时器TIM1或TIM8,这两个定时器才有死区寄存器才能发出死区pwm波,对于它们的介绍网上资料有很多这里就不重复啰嗦了,但需要看几个重要的寄存器:
● 控制寄存器(TIMx_CRx)
● 模式控制寄存器(TIMx_SMCR)
● 状态寄存器(TIMx_SR)
● 计数器寄存器(TIMx_CNT)
● 预分频器寄存器(TIMx_PSC)
● 自动装载寄存器(TIMx_ARR)
● 重复次数寄存器(TIMx_RCR)
● 刹车和死区寄存器(TIMx_BDTR)
前面几个寄存器是在配置TIM1/TIM8是要用到的基本设置。自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在TIMx_CR1寄存器中的自动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被立即或在每次的更新事件UEV时传送到影子寄存器。当计数器达到溢出条件(向下计数时的下溢条件)并当TIMx_CR1寄存器中的UDIS位等于0时,产生更新事件。更新事件也可以由软件产生。计数器由预分频器的时钟输出CK_CNT驱动,仅当设置了计数器TIMx_CR1寄存器中的计数器使能位(CEN)时,CK_CNT才有效。(更多有关使能计数器的细节,请参见控制器的从模式描述)。注意,在设置了TIMx_CR寄存器的CEN位的一个时钟周期后,计数器开始计数。最后来看一下死区寄存器:它是用来设置两个互补pwm波的死区时间的


上面的位都是在配置死区寄存器要用到的基本配置,下面是它的死区时间配置位[7:0]

DT表示的是死区时间,分了有四种情况位[7:5]为0xx、10x、110、111(x表示0或1)。32的主频是72M,它每走一下的时间为1/72000000=13.89ns。表中64的由来是2^6,由此32是2的5次方。因为UTG是有8个位。
知道这些应该差不多了,接着就去看它的库函数吧,32定时器的库函数有两页之多,需仔细的看,死区寄存器的配置要注意两路波的极性,不能搞错了。
#include "pwm.h"
#include "sys.h"
//FUNCTION:TIM1初始化函数
//AUTHOR:BiggerPast
//DATE:20181010
void TIM1_Init(u16 arr,u16 psc,u16 dead_time)
{
float T_TDS=13.89;//13.89ns
u16 death_time;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure; //死区设置
//dead_time--->255,以下计算按死区寄存器UTG位而得
if(dead_time >=0 && dead_time <=1764)//公式1
death_time = dead_time/T_TDS;
else if(dead_time>=1778 && dead_time<=3529)//公式2
death_time=dead_time/(T_TDS*2)+64;
else if(dead_time>=3556 && dead_time<=7001)//公式3
death_time=dead_time/(T_TDS*8)+160;
else if(dead_time>=7112 && dead_time<=14001)//公式4
death_time=dead_time/(T_TDS*16) + 192;
else
death_time=death_time;
//IO口初始化
RCC->APB2ENR|=(1<<2)|(1<<3)|(1<<11);//使能PA PB TIM1时钟
GPIOA->CRH&=0XFFFFF000;//清除设置
GPIOB->CRH&=0X000FFFFF;
GPIOA->CRH|=0X0000000A;//PA8复用推挽输出 2M
GPIOB->CRH|=0X00A00000;//B13复用推挽输出 2M
//定时器配置
TIM_TimeBaseStructure.TIM_Period = arr;//在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = psc;//TIM1时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0;//时钟分频可为1,2,4
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;// 计数模式Up为向上计数,Down向下
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;//重复计数
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
//输出波形配置 CH1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//定时器模式为PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出比较使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//输出比较N使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//空闲输出极性高
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//空闲输出高
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;//空闲输出低
TIM_OCInitStructure.TIM_Pulse = duty;
TIM_OC1Init(TIM1,&TIM_OCInitStructure);
/*高级定时器死区配置*/
TIM_BDTRInitStructure.TIM_AutomaticOutput=TIM_AutomaticOutput_Enable;//MOE主输出使能
TIM_BDTRInitStructure.TIM_Break=TIM_Break_Disable;//刹车功能禁止
TIM_BDTRInitStructure.TIM_BreakPolarity=TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_DeadTime=death_time;//死区时间
TIM_BDTRInitStructure.TIM_LOCKLevel=TIM_LOCKLevel_OFF;//锁定关闭,寄存器无写保护
TIM_BDTRInitStructure.TIM_OSSRState=TIM_OSSRState_Disable;
TIM_BDTRInitStructure.TIM_OSSIState=TIM_OSSIState_Disable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
TIM_CtrlPWMOutputs(TIM1,ENABLE);//MOE主输出使能 高级定时器必须
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);//CH1预装载使能
TIM_ARRPreloadConfig(TIM1,ENABLE);//使能TIM1在ARR上的预装载寄存器
TIM_Cmd(TIM1,ENABLE);
}
总结:波形的输出端口有个映射的问题:映射就像是功能复制,把一个IO口的功能复制到另一个IO口,当一个IO口的功能重复时通过映射就可以实现一个IO口实现不同的功能了。需要特别注意,不然输出波形不正常!
上一篇:STM32之3路ADC同步转换
下一篇:STM32学习——矩阵键盘
史海拾趣
|
我用的是PIC单片机,MC45(GSM)模块。 硬件电路MC45的50脚直接插到单片机的50脚插槽上,我用到的MC45脚包括TXD0,RXD0,IGT。 我并不知道MC45的这几个脚如何与单片机的RXD0,TXD0,IGT相连。 我的问题是可不可以软件上实现单片机的RXD0和MC45的TXD ...… 查看全部问答> |
|
1、软件工程或计算机软件相关专业,本科以上学历,英语四级以上。 2、熟练掌握C++及MFC编程,有3年以上基于EVC系统的开发经验。 公司地址:北京市海淀区西三旗 如有意者,可将简历发送至:hj3850@163.com 亦可来电 ...… 查看全部问答> |
|
Lm3S811 PLL 设置倍频到 50Mhz 之后,为什么实际只有37.5Mhz 呢? Lm3S811 PLL 设置倍频到 50Mhz 之后,为什么实际只有37.5Mhz 呢? SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_6MHZ);//UART 初始化SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);SysCtlPeripheral ...… 查看全部问答> |
|
之前有了解过pt1000的测量电路,就是很不准确,求各位高人指点! file:///C:/Documents%20and%20Settings/Administrator/Application%20Data/Tencent/Users/372182098/QQ/WinTemp/GE/8C6B5CD2-B508-47B8-8B53-AEEBA13D57F7.jpg… 查看全部问答> |
|
求介绍一款支持G.711压缩标准的语音芯片,能将语音数字化! 最近做项目用到支持G.711标准的语音压缩芯片,并且要求录音时间不小于30S,我算了一下这个要求芯片的存储空间至少是64KB*30=1920KB,大于2M的就可以。因为小弟接触的比较少,在网上也没有搜到,故求大神帮助! … 查看全部问答> |
|
2015电子大赛题目已经出炉,分享一些资料给大家参考。祝各位取得好成绩!附件中所有电路均可以免费下载,具体可联系管理员:459888529,索要优惠码。 … 查看全部问答> |
|
【MicroPython】Micropython PM检测添加SD卡存储 继续添加功能,PM值检测出来了,同时RTC功能也有了,接下来添加一个SD卡模块,希望能够实时将检测到的数据保存下来,作为历史数据。 在Micropython的官方文档中有关于SD卡的例程和库文件,拿来分析一下,就可以根据例程修改为自己的代码使用。 本 ...… 查看全部问答> |




