黄工无刷电机学习
直播中

王晾其

7年用户 983经验值
私信 关注
[问答]

如何利用PWM信号来控制3相桥式逆变器?

PWM 发生器模块具有什么特点?
如何利用PWM信号来控制3相桥式逆变器?

回帖(1)

李佳

2021-10-19 11:04:56
1、简述
脉冲宽度调制(PWM)是一种功能强大的对模拟信号电平进行数字编码的技术。使用高分辨率计数器产生一个方波,方波的占空比被调制成一个模拟信号的编码。典型应用包括开关电源和电机控制。
TM4C123GH6PM 微控制器包含两个 PWM 模块,每个模块有四个 PWM 发生器模块和一个控制模块组成,一共可以产生 16 个 PWM 输出。控制模块决定了 PWM 信号的极性,以及能够通过管脚的信号。每个 PWM 发生器模块产生两个 PWM 信号,这两个信号拥有相同的计时器和频率,我们可以编程对它们今次那个单独操作,也可以把它们作为能够插入死区延迟的一对互补信号。PWM发生器模块产生的输出信号称为 PWMA 和 PWMB,它们在被送到设备管脚之前由输出控制模块管理,之后MnPWM0 和 MnPWM1,或者是 MnPWM2 和 MnPWM3 信号使用。每个 TM4C123GH6PM 的 PWM 模块都提供了很大的灵活性,并且可以生成简单的 PWM 信号,比如简单电荷泵需要的 PWM 信号,也能够生成成对的带死区延迟插入的 PWM 信号,比如半 H
桥驱动需要的 PWM 信号。三台发生器模块也可以生成完整的六通道门的 PWM 信号来控制 3相桥式逆变器。
每个 PWM 发生器模块具有以下特点:
 一个故障条件处理输入端,能够快速提供低延迟关闭,防止损坏控制的电机,共两个输入端
 一个 16 位计数器
- 递减模式或递增/递减模式
- 输出频率由一个 16 位的负载值控制
- 负载值可以同步更新
- 在零和负载值时候产生输出信号
 两个 PWM 比较器
- 比较器的值可以同步更新
- 匹配时产生输出信号
 PWM 信号发生器
- 基于计数器和 PWM 比较器的输出信号要执行的操作生成 PWM 输出信号
- 产生两个独立的 PWM 信号
 死区发生器
- 产生两个可编程死区延迟的 PWM 信号,用于驱动半 H 桥
- 可以被旁路,使修改 PWM 输入信号不变
 可以启动 ADC 采样序列
控制模块决定了 PWM 信号的极性,以及能够通过管脚的信号。PWM 发生器模块的输出信
号被传递到设备管脚之前由输出控制模块管理。PWM 控制模块有以下选项:
 每个 PWM 信号都可以使能 PWM 输出
 每个 PWM 信号自主选择输出反转(极性控制)
 每个 PWM 信号自主选择故障处理
 PWM 发生器模块内定时器之间同步
 PWM 发生器模块之间的定时器/比较器更新同步
 可扩展的 PWM 发生器模块之间的定时器/比较器更新同步
 PWM 发生器模块中断状态总览
 可扩展的 PWM 故障处理,含多个故障信号,可编程极性设置和过滤
 PWM 发生器可独立操作或者和其它发生器同步

2、初始化配置
下面的例子演示了如何初始化设置 PWM 发生器 0 频率为 25KHz,MnPWM0 引脚信号占空比为 25%,MnPWM1 引脚信号占空比为 75%。此例假定系统时钟为 20MHz。
1. 通过写 0x00100000 到系统控制模块的 RCGC0 寄存器使能 PWM 时钟。
2. 通过系统控制模块中 RCGC2 寄存器使能相应 GPIO 模块的时钟。
3. 在 GPIO 模块中,使用 GPIOAFSEL 寄存器使能相应引脚的复用功能。
4. 配置 GPIOPCTL 寄存器中的 PWCn 域将 PWM 信号分配到合适的引脚上。
5. 配置系统控制模块运行模式时钟配置寄存器,使用 PWM 分频(USEPWMDIV)并设置分频器(PWMDIV)的除数因子为 2。
6. 配置 PWM 发生器为向下计数,参数立即更新模式。
 写 0x00000000 到 PWM0CTL 寄存器。
 写 0x0000008C 到 PWM0GENA 寄存器。
 写 0x0000080C 到 PWM0GENB 寄存器。
7. 设置周期时间。对于一个 25KHz 的频率,周期=1/25000,或 40 微秒。PWM 的时钟源为 10MHz;系统时钟为 PWM 时钟源频率的一半。因此,每 PWM 周期有 400 个时钟周期。使用这个值设置 PWM0LOAD 寄存器。在向下计数模式,设PWM0LOAD 寄存器中 LOAD 域为需要的周期长度减 1。
 写 0x0000018F 到 PWM0LOAD 寄存器。
8. 设置 MnPWM0 引脚的脉冲宽度为 25%占空比。
 写 0x0000012B 到 PWM0CMPA 寄存器。
9. 设置 MnPWM1 引脚的脉冲宽度为 75%占空比。
 写 0x00000063 到 PWM0CMPB 寄存器。
10. 启动 PWM 发生器 0 的定时器。
 写 0x00000001 到 PWM0CTL 寄存器。
11. 使能 PWM 输出。
 写 0x00000003 到 PWMENABLE 寄存器。

3、源代码

/**************************************************************************
*功能 :利用PWM的带死区翻转设置占空比
*作者 :MountXing
*时间 :2019-7-4
**************************************************************************/

#include
#include
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/pwm.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"

/**************************************************************************
*函数名 :InitConsole
*描述 :配置 UART 参数用于实验信息输出
*参数 :无
**************************************************************************/
void InitConsole(void)
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
  //UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
  GPIOPinConfigure(GPIO_PA0_U0RX);
  GPIOPinConfigure(GPIO_PA1_U0TX);
  GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
  UARTStdioConfig(0, 115200, 16000000);
}
/******************************************************************
* 函数名 :main
* 描述 :main 函数
* 参数: :无
******************************************************************/
int main(void)
{
  //设置系统时钟
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
  SYSCTL_XTAL_16MHZ);
  //设置 PWM 时钟为系统时钟的 1 分频
  SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
  //配置串口用于显示程序状态信息
  InitConsole();
  //显示相关配置信息
  UARTprintf("/***************************************n");
  UARTprintf(" *PWM实验n");
  UARTprintf(" *模式: PWM0n");
  UARTprintf(" *测量引脚: PD0n");
  UARTprintf(" *占空比: 25%%n");
  UARTprintf(" *反向占空比: 75%%n");
  UARTprintf(" *功能: PWM 输出每 5 秒改变一次.n");
  UARTprintf("/***************************************n");
  UARTprintf("PWM0 (PD0) -> 开始 = ");
  
  SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  
  GPIOPinConfigure(GPIO_PB6_M0PWM0);
  
  //配置引脚为 PWM 功能
  GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6);
  
  //配置 PWM 发生器
  PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
  
  //配置 PWM 周期
  PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 64000);
  
  //配置 PWM 占空比
  PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,PWMGenPeriodGet(PWM0_BASE, PWM_OUT_0) / 4);

//使能 PWM0 输出
  PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT, true);
  
  //使能 PWM 发生器模块
  PWMGenEnable(PWM0_BASE, PWM_GEN_0);
  
  while(1)
  { //打印 PWM 输出的极性
    UARTprintf("占空比=75%%n");
    //延迟 5s
    SysCtlDelay((SysCtlClockGet() * 5) / 3);
    //信号反转
    PWMOutputInvert(PWM0_BASE, PWM_OUT_0_BIT, true);

    UARTprintf("极性翻转=75%%n");
    SysCtlDelay((SysCtlClockGet() * 5) / 3);
    //恢复原来状态,信号不反转
    PWMOutputInvert(PWM0_BASE, PWM_OUT_0_BIT, false);
  }
}






举报

更多回帖

发帖
×
20
完善资料,
赚取积分