STM32高级定时器TIM1产生两路互补的PWM波(带死区)
测试环境:Keil 5.20.0.0 STM32F103RBT6 固件库版本:STM32F10x_StdPeriph_Lib_V3.5.0(2011)

本文使用TIM1的通道1,通道2,产生两路1khz,死区时间1us的互补PWM波。
所使用的IO口:由下图知,我们使用引脚为PA9,PA10,互补输出使用PB14,PB15

部分代码如下:
/* 配置TIM1复用输出PWM时用到的I/O */
static void TIM1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure; /* TIM1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* GPIOA and GPIOB clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); }
初始化IO
初始化定时器功能配置
u16 CCR2_Val = ;
u16 CCR3_Val = ;//占空比,周期为1000 /*配置TIM1输出的PWM信号的模式,如周期、极性、占空比 */
void TIM1_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_BDTRInitTypeDef TIM1_BDTRInitStruct;
TIM_OCInitTypeDef TIM_OCInitStructure; /* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = -; //计数周期,向上记到此数,计数值清零
TIM_TimeBaseStructure.TIM_Prescaler = -;//定时器分频系数,Ftimer = 72M/(TIM_Prescaler+1) = 1ms
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//与死区时间分频有关
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /****** 配置BDTR寄存器,配置死区时间****************/
/*
定时器时钟 72M TIM_ClockDivision = TIM_CKD_DIV1时, Tdts = 13.89ns
0 - 1.764us 用算法一
1.778us - 3.505us 用算法二
3.556us - 7.000us 用算法三
7.1117us - 14us 用算法四
需要更长时间,使用TIM_ClockDivision分频
*/
TIM1_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Disable;
TIM1_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Disable;
TIM1_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM1_BDTRInitStruct.TIM_DeadTime = ; //死区时间 72:1us 172:3us 205:5us
TIM_BDTRConfig(TIM1,&TIM1_BDTRInitStruct); // TIM1->BDTR |= 72; //设置死区 注:上面那种方法也可以,这种快且简单 /* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//PWM2模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//比较互补输出使能
TIM_OCInitStructure.TIM_Pulse = CCR2_Val; //比较值,即占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//互补输出极性
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//指定空闲状态下的TIM输出比较的引脚状态。
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//指定空闲状态下的TIM互补输出比较的引脚状态。
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //初始化通道二比较输出
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //配置通道二,自动重装载使能 /* PWM1 Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
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_OCIdleState_Reset;
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1, ENABLE);//重载装载值 ENABLE 立即生效,DISABLE 下一个比较周期生效 /* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);//使能定时器1 TIM_CtrlPWMOutputs(TIM1, ENABLE);//使能PWM外围输出
}
int main(void)
{
TIM1_GPIO_Config();
TIM1_Mode_Config();
while()
{
TIM1->CCR2 = CCR2_Val;
TIM1->CCR3 = CCR3_Val;
CCR2_Val+=;
CCR3_Val+=;
if(CCR2_Val>) CCR2_Val = ;
if(CCR3_Val>) CCR3_Val = ;
Delay_mS();
}
}
main函数
关于死区时间计算:
先贴几张关于TIM时钟的图:
第一张图:关于死区时间分频因子。(代码见,初始化定时器功能配置代码部分第14行所示)

第二张图:死区时间计算


定时器1时钟挂在APB2总线上,时钟为72M 当TIM_ClockDivision = TIM_CKD_DIV1时, Tdts = 1/72M = 13.89ns
0 - 1.764us 用算法一
1.778us - 3.505us 用算法二
3.556us - 7.000us 用算法三
7.1117us - 14us 用算法四
需要更长时间,使用TIM_ClockDivision分频后(可2分,4分频),设置死区时间。
测试数据:
实验现象:产生了两路死区时间为1us的互补PWM信号,其频率都是1kHz,占空比在10% - 90%不断变化,通道三比通道二变化要快。
死区时间(以通道二为例):(黄:PA10 绿:PB15)

通道二抓拍波形 (黄:PA10 绿:PB15)

通道三抓拍波形 (黄:PA9 绿:PB14)

通道二和通道三 (黄:PA9 绿:PA10)

STM32高级定时器TIM1产生两路互补的PWM波(带死区)的更多相关文章
- stm32电机控制之控制两路直流电机
小车使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制,这里电机使用PWM驱动,速度控制框图如下: 由以上框图可知,STM32通过定时器模块输出PWM波来控制两个直流电机的转动 ...
- stm32电机控制之控制两路直流电机!看完你会了吗
手头上有一个差分驱动的小车,使用两个直流电机驱动,要实现小车的在给定速度下运动,完成直线行驶,转向,加速,刹车等复杂运动. 使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制, ...
- 高级定时器TIM1&TIM8
高级定时器 初识stm32高级定时器: (1)高级控制定时器(TIM1 和 TIM8)和通用定时器在基本 ...
- 基于STM32F767两路互补SPWM波(HAL库)
SPWM波指的是占空比呈正弦规律变化的PWM波,生成方式是在定时器中断中调整PWM波的占空比. 对于互补的两路SPWM波,一路为低电平 ‘0’ 时,另一路为高电平 ‘1’,即两路是互补的. 对于STM ...
- Stm32高级定时器(四)
Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...
- Stm32高级定时器(三)
Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...
- Stm32高级定时器(二)
Stm32高级定时器(二) 1 主从模式:主?从? 谈论主从,可知至少有两个以上的触发或者驱动信号,stm32内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...
- Stm32高级定时器(一)
Stm32高级定时器(一) 1 定时器的用途 2 高级定时器框图 3 时基单元 4 通道 1 定时器的用途 已知一个波形求另一个未知波形(信号长度和占空比) 已知波形的信号长度和占空比产生一个相应的波 ...
- 【stm32】用TIM1产生6路ADC,用CCR4触发ADC1的注入通道采样
这几天一直在使用STM32来写sensorless BLDC的驱动框架,那么必须会用到TIM1的CCR1/CCR2/CCR3产生的六路互补PWM,以及用CCR4来产生一个中断,用来在PWM-ON的时候 ...
随机推荐
- Docker Centos6 下建立 Docker 桥接网络
cd /etc/sysconfig/network-scripts/; cp ifcfg-eth0 ifcfg-br0 vi ifcfg-eth0 //增加BRIDGE=br0,删除IPADDR,N ...
- Invoke 与 BeginInvoke 应用场景
1.委托中 Invoke , BeginInvoke 特点 Invoke : 同步调用 , 委托在当前线程执行 BeginInvoke : 异步调用 , 通常使用线程池资源执行委托. 2. UI ...
- 对TCP三次握手四次分手还不清楚的速度进,超简单解析,明白了就很好记!
关于TCP三次握手四次分手,之前看资料解释的都很笼统,很多地方都不是很明白,所以很难记,前几天看的一个博客豁然开朗,可惜现在找不到了.现在把之前的疑惑总结起来,方便一下大家. 先上个TCP三次握手和四 ...
- kvm的安装使用技巧
KVM参考网址 http://www.server110.com/kvm/201403/8321.html http://www.2cto.com/os/201511/451650.html http ...
- Visual Studio 2017 Enterprise 发布 15.3.2 版,附离线安装包下载。
Visual Studio 2017 Enterprise 更新至 15.3.2 ,本安装包使用微软原版安装文件,配合layout指令全量下载后制作,内置中文语言包,包含 Visual Studio ...
- RAC节点两边存储名字不一致导致的故障及相关延伸
起因:一个客户的实际故障,该故障非常典型,其他客户类似的环境也非常多,所以很值得梳理并记录下来. 环境:Oracle 11.2.0.4 RAC(2 nodes)+ RHEL 6.6 共享存储:EMC ...
- Spring Boot 2.0(二):Spring Boot 2.0尝鲜-动态 Banner
Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner,今天我们就先拿这个来尝尝鲜. 配置依赖 使用 Spring Boot 2.0 首先需要将项目依赖包替换为刚刚发 ...
- SpringMVC实现返回不同视图
在spring mvc中应该怎么实现可以返回不同结果呢,其实就是配置多个视图解析器,最常用的就是freemaker视图解析器,有时候要又要同时又jsp,html,那么应该怎么配置呢? 具体配置如下 & ...
- nyoj28 大数阶乘 亿进制优化
思路:刚开始用的十进制模拟手算加法,超时了.然后想到刘汝佳大哥书上面用的亿进制能够加速大数运算,果然180ms过掉了. 亿进制与十进制相同,只不过是把八位看做一位,例如6464654654165,看成 ...
- WebApi 参数绑定方法
WebAPI 2参数绑定方法 简单类型参数 Example 1: Sending a simple parameter in the Url 01 02 03 04 05 06 07 08 09 ...