利用STM32通用定时器实现输出两路占空比和频率可调的互补PWM

发布者:科技火箭最新更新时间:2018-12-25 来源: eefocus关键字:STM32  通用定时器  占空比  PWM 手机看文章 扫描二维码
随时随地手机看文章

MCU:STM32F334C8T6


PWM即脉宽调制,可以用来驱动电机,驱动全桥电路等,用过STM32的知道,用它的定时器可以很容易实现PWM输出,使用高级定时器的TIMx_CHy和TIMx_CHyN可以轻易实现互补PWM(complementary PWM)波形的输出。


高级定时器资源有限,本文利用通用定时器(General-purpose timers)实现互补PWM输出,在高级定时器资源不够时不失为一个好方法。


STM32的定时器PWM有两种模式:PWM mode 1和PWM mode 2


工作原理:

PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNT


In downcounting, channel 1 is inactive (OC1REF=‘0’) as long as TIMx_CNT>TIMx_CCR1 else active (OC1REF=’1’).


 PWM mode 2 - In upcounting, channel 1 is inactive as long as TIMx_CNT


In downcounting, channel 1 is active as long as TIMx_CNT>TIMx_CCR1 else inactive.


官方手册对channel 1 的说明,其他channel类似,考虑向上计数模式


方法一:

假设高电平为有效电平,即高电平为active,使用定时器3


PWM mode 1:TIM3_CNT


PWM mode 2:TIM3_CNT


可以看出,无论是mode1还是mode2,电平翻转都是在计数器TIM3_CNT中的值达到TIM3_CCR1 中的值(次数可以控制占空比,见下文)的时候


据此,可以将TIM的两个通道(如TIM3_CH1和TIM3_CH2)分别配置为mode1和mode2,那么即可输出两路互补互补PWM,此为方法一


方法二:

方法一中假设高电平为active状态,事实上active状态也可以是低电平,在这种情况下,考虑同一种模式(mode1)


acive high:TIM3_CNT


active low:TIM3_CNT


于是,同种模式下,分别将两个通道的有效电平配置为高和低,也可以实现互补PWM输出,此为方法二


在向下计数模式中原理类似,不再说明


频率和占空比的调节:


上面提到了两个寄存器:CNT和CCR1,(channel x 对应CRx)CNT中是计时器当前的计数值,CCR1中是用来比较的值,当CNT达到CCR1的值时,将发生电平转变另一个寄存器ARR,自动装载寄存器,存储的是自动装载的值,向上计数中当CNT递加达到ARR的值时将被复位,从0从新开始,而向下计数时,当CNT到达0时,ARR中的值将被自动装载到CNT重新开始递减,也就是说ARR中的值是计数周期(中心对其计数模式此处不考虑)


假设我们需要的频率为freq,占空比dutycycle,定时器使用系统频率SYSCLK,有如下关系:


ARR = SYSCLK/freq,dutycycle=CCR1/ARR


可见,通过更改ARR实现频率可调,更改CCR1实现占空比可调


部分代码:

uint16_t period=0,pulsewidth=0;


GPIO_InitTypeDef  GPIO_InitStruct;

TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;

TIM_OCInitTypeDef  TIM_OCInitStruct;

 

period = 72*1000000/(100*1000);//计数周期,系统频率72M,PWM输出频率100k

pulsewidth = 45*period/100;  //脉宽,占空比45%

 

//开启外设时钟

//配置GPIO

 

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_Period = period - 1;//ARR

//填充TIM_TimeBaseInitStruct其他参数

TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStruct);

//OCInit结构体初始化,填充完所有参数

TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;

TIM_OCInitStruct.TIM_Pulse = pulsewidth; //CCR1

TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;

//TIM_OC1Init()开启通道1

 

//OC2 方法1 : 修改Mode

TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2;

TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;

/***********************************

//OC2 方法2 : 修改 Polarity

TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;

***********************************/

//TIM_OC2Init()开启通道2

 

//最后打开时钟

TIM_Cmd(TIM3, ENABLE);



附图为亲自测试效果,两种方法效果相同


测试基于STM32F334C8T6,频率100k,占空比45%,互补波占空比55%


关键字:STM32  通用定时器  占空比  PWM 引用地址:利用STM32通用定时器实现输出两路占空比和频率可调的互补PWM

上一篇:使用STM32F103实验和总结PWM相关知识
下一篇:STM32 PWM快速开关端口电平问题

推荐阅读最新更新时间:2024-03-16 16:21

stm32内存结构
这个是板载的SRAM,属于外部的SRAM,起始地址是0x68000000,为什么这个地址我也没懂。 这个是核内部的SRAM,分为两个部分:普通内存,起始地址0x20000000,共128KB,这部分的内存任何外设都可以访问,CCM内存,起始地址是0x10000000,共64KB,但是只能由CPU访问。 在内存管理的实验中,我们主要是用了malloc和free两个函数来进行内存的申请和释放。在使用了malloc申请内存之后,返回的值是在申请之后的首地址。同时,在申请了地址之后,并且将指针指向该地址时,使用过一次之后就要将该申请free掉,不然会造成所谓的“内存泄露”。时间长了会影响内存的使用。 我使用的是原子哥的
[单片机]
<font color='red'>stm32</font>内存结构
入坑STM32后,我们应该如何学习?
01 前言 在STM32之前,都是老大头51,带着它的“小弟们” MSP430、AVR、PIC在单片机界呼风唤雨。 那个时候,市场上遍布8位机,大学教材用51入门,个人、企业学单片机基本上也都在用51。 虽然AVR也有一些8位机市场,但与stc带领下的51单片机是完全不能相比的。 当然,这个时候也有16位机的msp430,其他厂家单片机还有pic,高端嵌入式处理器等市场有arm7、arm9等。 这个时期的单片机市场是百花齐放、百家争鸣,但总体来说,还是势均力敌、一片祥和的。 那么,这个局势是从什么时候开始打破的呢?这还得从物联网的崛起说起。 02 原因 当时,物联网(Internet of Things,IoT)逐步进入人们的
[单片机]
入坑<font color='red'>STM32</font>后,我们应该如何学习?
stm32 adc计算
用STM32自带的ADC读取引脚电压值,读回来的数据怎么转换成单位为V的数值??? V(ADC) = Value(ADC) * V(ref)/4096 (stm32的ADC是12位的,所以ad字的最大值是4096) 其中V(ADC)为算出的电压值;Value(ADC)为采集的AD值;V(ref)为参考电压,一般为3.3V。 比如你STM32的参考电压为3.3v,采集的AD值为1024,那么转换为电压V(ADC) = 1024×3.3/4096 = 0.825V
[单片机]
STM32HAL库学习笔记--硬件I2C读写AT24C512
一、CubeMx配置 开启I2C1,其余参数默认 在旧版本的CubeMx中,HAL库实现的I2C初始化带有一些BUG,比如需要在I2C引脚复用GPIO配置前加上I2C的时钟使能,不过这些BUG在新版本的CubeMx中似乎得到了解决,直接使用其生成的初始化程序和HAL库的I2C接口就可以实现成功的读写操作 二、读AT24C512DataSheet AT24Cxx系列芯片内存大小各异,页数和每页字节数也不同,要根据数据手册来确定该型号芯片的内存结构(Memory Organization) 由DS可知AT24C512的内存一共有 512 Pages x 128 Bytes = 65536 Bytes = 512 kbits
[单片机]
STM32HAL库学习笔记--硬件I2C读写AT24C512
基于STM32的keil4 MDK 软件仿真输出IO口的波形图
这是一个STM32的PA6和PA7口输出PWM波形的仿真步骤,其它情况类似 每一步我都做了截图,大家照着一步步来,有些参数根据自己的情况稍微改下就好,肯定可以出波形的!请大家放心参考
[单片机]
基于<font color='red'>STM32</font>的keil4 MDK 软件仿真输出IO口的波形图
STM32的 位寻址(地址映射)
STM32的寄存器的分布情况: STM比较特色的就是 位带操作: 如下解释: (寄存器的地址是固定好的,我们想要进行位操作的话 就需要用到地址映射,将位带区寄存器的 各位 映射到 位带别名区的地址。) 通过 位带别名区 的 4个字节(32个位)用来存放 位带区的 位地址。 如将 0x2200 0000 映射到 0x2000 000 的第一个位! 具体的映射C程序是这样的: 算法公式: (addr & 0xF0000000)+0x2000000+((addr &0xFFFFF) 5)+(bitnum 2) addr & 0xF0000000: 取0x40
[单片机]
软件实现多路PWM的输出
单片机应用于舞台灯光、民用照明的调光、电机转速、温度控制等众多领域时需要用到PWM占空比进行调节。市场上,集成了硬件PWM模块的单片机型号如PIC16F628A、STC12C2052等。使用硬件PWM时仅需进行一些特殊功能寄存器的设置,使用方便。但硬件PWM输出路数往往较少,如果要增PWM的输出路数则会使产品成本上升,较难适应于价格敏感的产品上。如:PIC16F628A、STC12C2052仅具有两路PWM输出。舞台光通常要到用三路PWM信号调光(三路分别控制红、绿、蓝三基色进行组合搭配出不同色彩)。因此软件实现PWM是较为合理的选择。 在舞台灯光厂做了这么久,虽然明白软件PWM的原理,但就是弄不清它们的关系,一直写不出比较好的软件
[单片机]
多模高频PWM控制器UCC39421/2及其应用
摘要:UCC39421/2是高效多模式高频PWM控制器。文章简要介绍了UCC39421/2的功能特点,详细论述了UCC39421/2的构成原理及引脚功能,给出了UCC9421/2控制器的应用方法及应用电路。 关键词:多模高频 PWM控制 DC/DC变换 UCC39421/2 1 UCC39421/2的功能特点 UCC39421/2是一种高效低功率DC/DC转换器。它在很宽的工作电源下具有很高的效率,并可提供编程上电复位功能,该芯片带有独立的低压检测比较器,同时具有脉冲调制、限流和低电流关断(5μA)功能,可广泛应用于蜂窝电话、录呼机、PDAs以及其它手持设备中。 UCC39421/2具有以下特点: *采用高效升压单端初
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved