测试环境: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波(带死区)的更多相关文章

  1. stm32电机控制之控制两路直流电机

    小车使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制,这里电机使用PWM驱动,速度控制框图如下: 由以上框图可知,STM32通过定时器模块输出PWM波来控制两个直流电机的转动 ...

  2. stm32电机控制之控制两路直流电机!看完你会了吗

    手头上有一个差分驱动的小车,使用两个直流电机驱动,要实现小车的在给定速度下运动,完成直线行驶,转向,加速,刹车等复杂运动. 使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制, ...

  3. 高级定时器TIM1&TIM8

                                               高级定时器 初识stm32高级定时器:      (1)高级控制定时器(TIM1 和 TIM8)和通用定时器在基本 ...

  4. 基于STM32F767两路互补SPWM波(HAL库)

    SPWM波指的是占空比呈正弦规律变化的PWM波,生成方式是在定时器中断中调整PWM波的占空比. 对于互补的两路SPWM波,一路为低电平 ‘0’ 时,另一路为高电平 ‘1’,即两路是互补的. 对于STM ...

  5. Stm32高级定时器(四)

    Stm32高级定时器(四) 1 编码器接口模式 1.1 编码器原理 什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向.根 ...

  6. Stm32高级定时器(三)

    Stm32高级定时器(三) 1 互补输出和死区插入 1.1 死区:某个处于相对无效状态的时间或空间 本来OCX信号与OCXREF时序同相同步,OCXN信号与OCXREF时序反相同步.但为了安全考虑,以 ...

  7. Stm32高级定时器(二)

    Stm32高级定时器(二) 1 主从模式:主?从? 谈论主从,可知至少有两个以上的触发或者驱动信号,stm32内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...

  8. Stm32高级定时器(一)

    Stm32高级定时器(一) 1 定时器的用途 2 高级定时器框图 3 时基单元 4 通道 1 定时器的用途 已知一个波形求另一个未知波形(信号长度和占空比) 已知波形的信号长度和占空比产生一个相应的波 ...

  9. 【stm32】用TIM1产生6路ADC,用CCR4触发ADC1的注入通道采样

    这几天一直在使用STM32来写sensorless BLDC的驱动框架,那么必须会用到TIM1的CCR1/CCR2/CCR3产生的六路互补PWM,以及用CCR4来产生一个中断,用来在PWM-ON的时候 ...

随机推荐

  1. IOS设备设计完整指南

    作为初学者,常常不知如何下手设计,IOS应用UI设计中碰到的种种基础小问题,在此都将一一得到解答.这份完整的设计指南将带你快速上手,为IOS设计出优雅的应用吧. 关于此设计指南 此设计指南描述的是如何 ...

  2. Android硬件编解码与软件编解码

           最近做了一个android项目用到编解码功能.大概需求是:通过摄像头拍摄一段视频,然后抽帧,生成一个短视频,以及倒序视频,刚开始直接用 H.264 编码格式,没有使用MP4容器封装.做了 ...

  3. [翻译]【目录】编写高性能 .NET 代码

    本篇是 Writing High-Performance .NET Code 的目录索引,翻译内容不定时更新,目录也会同步修改. 性能测量及工具 选择什么来衡量 平均数vs百分比 工具介绍 Visua ...

  4. 箱型图boxplot函数的使用

    主要参数: medlwd:设置中位线宽度 whiskcol:设置虚线颜色 staplecol:设置顶端颜色 outcol:离群值颜色 相应的具体位置: outline=FALSE:去除离群值 outp ...

  5. java2 - 语言基础

    一.结构流程图制作工具 xmind 的使用 二.Java 基础数据类型 回答以下问题: java 基本数据类型有几种? 整数类型是哪几种? 浮点数类型是哪几种? 字符类型关键字? 布尔类型关键字? 为 ...

  6. c# 委托(Func、Action)

    以前自己写委托都用 delegate, 最近看组里的大佬们都用 Func , 以及 Action 来实现, 代码简洁了不少, 但是看得我晕晕乎乎. 花点时间研究一下,记录一下,以便后期的查阅. 1.F ...

  7. (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]]一行js代码的原理分析

    再说这行代码之前,咱们先来预习一下知识. 我们都知道计算机操作系统分为32位或者64位.那么这个32位或64位指的是什么意思呢?其实,要想解释它并不难,其实这就是计算机处理数据的机制,32位表示计算机 ...

  8. (2018干货系列一)最新Java学习路线整合

    怎么学Java Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征. 话不多说,直接上干货: ...

  9. jQuery手机发送验证码倒计时代码

    <!DOCTYPE> <html> <head> <meta charset="UTF-8"> <script type=&q ...

  10. Vue项目搭建及原理一

    一. Vue简介 Vue简介 Vue是近两年来比较火的一个前端框架(渐进式框架),与reactjs和angularjs三国鼎立,根据不完全统计,包括饿了么.稀土掘金.苏宁易购.美团.天猫.荔枝FM.房 ...