STM32F103单片机定时器自带互补PWM波形输出功能,利用定时器输出比较模式,不仅可以输出互补的 PWM波,还可以设置输出方波的起始相位和死区时间。
下面就总结一下如何实现PWM互补输出。
void TIM1_PWM_DeadtimeInit( u16 arr, u16 psc, u16 ccr1, u16 ccr2, u16 deadtime )
{
GPIO_InitTypeDef GPIO_InitSturcture;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE );
RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );
//TIM1 互补PWM CH1->PA8 CH2->PA9 CH1N->PB13 CH2N->PB14
GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitSturcture );
GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_InitSturcture );
//定时器设置
TIM_TimeBaseInitStructure.TIM_Period = arr;
TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_ClockDivision = 0x00;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure );
//通道1 捕获比较模式设置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //翻转,当 TIMx_CCR1=TIMx_CNT时,翻转OC1REF的电平
TIM_OCInitStructure.TIM_Pulse = ccr1; //100
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //CCER的CC1P,输入/捕获输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //CER的CC1N,输入/捕获输出使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //OIS1位
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; //CR2的OIS1N位,当MOE位0时,输出空闲状态位OIS1N.
TIM_OC1Init( TIM1, &TIM_OCInitStructure );
//通道2 设置
TIM_OCInitStructure.TIM_Pulse = ccr2; //316
TIM_OC2Init( TIM1, &TIM_OCInitStructure );
//刹车和死区设置
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; //OSSR:运行模式下“关闭状态”选择
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; //OSSI:空闲模式下“关闭状态”选择
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; //锁定设 置,级别为1
TIM_BDTRInitStructure.TIM_DeadTime = deadtime; //死区延时时间
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; //禁止刹车输 入
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; //刹车输入极性
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //自动输出使能
TIM_BDTRConfig( TIM1, &TIM_BDTRInitStructure );
TIM_CtrlPWMOutputs( TIM1, ENABLE );
TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Enable );
TIM_OC2PreloadConfig( TIM1, TIM_OCPreload_Enable );
TIM_ARRPreloadConfig( TIM1, ENABLE );
TIM_Cmd( TIM1, ENABLE );
}
首先初始化IO口,这里使用的是定时器1的通道1和通道2。
PA8为定时器1通道1输出口,PB13为定时器1通道1互补输出口。
PA9为定时器1通道2输出口, PB14为定时器1通道2互补输出口。
下来初始化定时器,参数arr设置输出PWM波频率,psc设置定时器时钟分频系数。定时器初始化之后,设置定时器工作模式为输出比较模式,其中参数 ccr1 设置通道1的输出方波起始相位,参数cc2设置通道2输出方波起始相位。参数 deadtime 设置互补PWM波形的死区时间。初始化结束后启动定时器。
关于输出比较模式的详细说明参考STM32输出比较模式和PWM模式 比较这篇文章。
下面看主函数设置
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "pwm_ch_chn.h"
// LED0 PA8 LED1 PD2
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
LED0 = 1;
LED1 = 1;
delay_ms(500);
LED0 = 0;
LED1 = 0;
// Tout=(719+1)*(0+1)/72M=10us 72M/720=0.1M=100K
TIM1_PWM_DeadtimeInit(719,0,0,0,72);//50KHz
while(1)
{
}
}
主函数中设置自动装载值为 720,分频系数为0,那么输出方波频率为 72MHz / 720 = 0.1MHz,也就是输出波形频率为100K,由于此处用的是定时器的输出比较模式,所以输出频率为计算值的一半,所以实际输出方波频率为50KHz。ccr1值设置为0,也就是定时器1通道1的输出波形起始相位为0,ccr2的值为0,所以起始相位也为0。死区时间设置为72,为周期数的1/10,也就是2us。
下面看一下输出波形
黄色为 TIM1_CH1波形,绿色为TIM1_CH1N波形,这两个波形是通道1互补波形。
蓝色为 TIM1_CH2波形,粉色为TIM1_CH2N波形,这两个波形是通道2互补波形。
黄色和蓝色波形起始相位相同。
原波形和互补波形死区时间为1us,刚才计算的死区时间是2us,这里为什么是1us?因为死区时间是上升沿时间差+下降沿时间差,是两个对称的区间。这里只测了一个区间,所以为总时间的一半。
下来同时改变ccr1和ccr2的初始值,看看输出波形相位有没有发生变化。
TIM1_PWM_DeadtimeInit(719,0,72,144,72);//50KHz
输出波形为
蓝色波形下降沿比黄色波形下降沿滞后了一点,说明起始相位已经发生了改变。
放大波形后可以看到,下降沿滞后的时间为1us,和死区时间相同。
上一篇:STM32不同型号单片机keil工程移植说明
下一篇:STM32输出比较模式和PWM模式 比较
推荐阅读最新更新时间:2024-11-13 15:32
设计资源 培训 开发板 精华推荐
- TC78S121FNG 多通道步进电机驱动器评估板
- SPC584B-DIS:eQFP64封装MCU SPC58 探索套件
- 感测输出电流应用电路
- EVAL-ADM1184EBZ,评估套件演示了 ADM1184 在多电源系统中作为四路电压监视器的操作
- 基于ACEPACK 2电源模块的工业驱动系统套件
- LTC4301L 的典型应用 - 具有低电压电平转换的热插拔 2 线总线缓冲器
- LT6654BMPS6-3.3、16 位 ADC 电压基准的典型应用
- RDR-710 - 12 W 双输出开放式电源,适用于使用 InnoSwitch3-TN 的设备
- 使用 Analog Devices 的 LTC1143LCS-ADJ 的参考设计
- RDR-802 - 60 W USB PD 3.0,采用 3.3 V-21 V PPS 电源,使用 InnoSwitch3-Pro 和 Weltrend WT6635P 控制器
- ST工业峰会巡演2023 已开启,北京、上海 报名进行中!
- 全球首款Cortex-M23内核物联网芯片SAML10和SAM L11系列 闯关获取SAML10/SAML11法宝,拆除电子界安全危机,赢好礼!
- 下载赢好礼!30张京东卡等你拿!
- 你有原创我有奖,等值现金奖励最高到500
- 更好的供电方式:使用更小、更轻的电源模块加速车辆电气化
- 带你零起点入门STM32(专为嵌入式应用而开发的内核)
- 技术直播:TI 60G毫米波传感器概述和应用介绍,种草封装了天线的智能传感器IWR6843
- 有奖直播:5G和边缘计算发展和技术应用
- Littelfuse【智能家居的电路保护方案】在线研讨会 11月22日10点 强势登场!预报名、参与研讨会赢好礼!