主题中讨论的其他器件:EK-TM4C129EXL、 TM4C1294NCPDT
尊敬的先生:
如何在两个或多个 PWM 发生器之间生成"延迟时间"、如下图所示?
4个 PWM 周期全部为100kHz、占空比为10%、"延迟时间"分别为2.5uS / 5uS / 7.5uS。
我已经尝试了函数"PWMPulseWidthSet()",但它无法正常工作!

This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
尊敬的先生:
如何在两个或多个 PWM 发生器之间生成"延迟时间"、如下图所示?
4个 PWM 周期全部为100kHz、占空比为10%、"延迟时间"分别为2.5uS / 5uS / 7.5uS。
我已经尝试了函数"PWMPulseWidthSet()",但它无法正常工作!

您好!
让我分享一个有关如何为两个 PWM 创建相移 PWM 的想法。 如果需要、可以扩展到更多 PWM。
PWM 生成将基于 PWM 递减计数模式、但我想您应该也能使它在递增/递减计数器模式下工作。 在递减计数模式中、有四个事件会影响 PWM 信号:零、装载、匹配 A 递减和匹配 B 递减。
在第一个 PWM 上、您将使用两个事件。 例如、假设您将 PWM 周期设置为100。 然后、您将为 "load"设置事件 A。 当发生"load"事件时、您将将 PWM 引脚设置为高电平。 当比较匹配为90时、您还将设置第二个事件。 当匹配发生时、 您将在90时清除 PWM 引脚。 这将创建一个10%占空比 PWM。
对于第二个 PWM、您可以使用另一个 PWM_GEN 模块。 对于此 PWM、您可以将比较匹配 A 设置为 PWM 引脚80、将另一个比较匹配 B 设置为70以清除 PWM。
3.确保两个 PWM 彼此同步。
如果您看看这两个 PWM、您应该会看到第一个 PWM 设置为100、清除为90、第二个 PWM 设置为80、清除为70。 两个 PWM 之间存在10相移。
您好、Charles、
感谢您的回复!
我已经尝试过以下代码、但无法正常工作。
没有相关 API (我不确定)? 因此我正在尝试[HWREG (PWM0_0_GENA_R)/ HWREG (PWM0_0_GENB_R) / HWREG (PWM0_0_CMPA_R)/ HWREG (PWM0_0_CMPB_R) ]以创建事件 A/B;
可以帮助我查看我的代码吗? 谢谢!
//
// PWM_8ch.c
//
空配置 PWM (空)
{
uint32_t ui32PWMClockRate;
//必须启用 PWM 外设才能使用。
MAP_SysCtlPeripheralEnable (CH0_CH1_CH2_CH3_PWM_Periph);
//启用用于 PWM 输出的 GPIO 端口。
MAP_SysCtlPeripheralEnable (CH0_CH1_GPIO_Periph);
//为此引脚配置 PWM 功能。
MAP_GPIOPinTypePWM (CH0_CH1_GPIO_base、CH0A_GPIO_PIN | CH0B_GPIO_PIN | CH1A_GPIO_PIN | CH1B_GPIO_PIN);
MAP_GPIOPinConfigure (CH0A_PWM_MOUDLE_PIN);
MAP_GPIOPinConfigure (CH0B_PWM_MOUDLE_PIN);
MAP_GPIOPinConfigure (CH1A_PWM_MOUDLE_PIN);
MAP_GPIOPinConfigure (CH1B_PWM_MOUDLE_PIN);
//将 PWM 时钟设置为 SYSCLK /4。
MAP_PWMClockSet (CH0_CH1_CH2_CH3_PWM_base、PWM_SYSCLK_DIV_4);
//使用局部变量来存储 PWM 时钟速率,即120MHz/4 = 30MHz。 该变量将用于设置 PWM 发生器周期。
ui32PWMClockRate = g_ui32SysClock / 4;
//将 PWM0 / PWM1 / PWM2 / PWM3配置为通过同步进行倒计数。
MAP_PWMGenConfigure (CH0_CH1_CH2_CH3_PWM_base、CH0_PWM_GEN、PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
MAP_PWMGenConfigure (CH0_CH1_CH2_CH3_PWM_base、CH1_PWM_GEN、PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
//将 PWM 周期设置为100KHz。 要计算适当的参数、请使用以下公式:n =(1 / f)* PWMClk。
//其中 N 是函数参数、f 是所需的频率、PWMClk 是基于系统时钟的 PWM 时钟频率。
MAP_PWMGenPeriodSet (CH0_CH1_CH2_CH3_PWM_base、CH0_PWM_GEN、(ui32PWMClockRate / 100000));
MAP_PWMGenPeriodSet (CH0_CH1_CH2_CH3_PWM_base、CH1_PWM_GEN、(ui32PWMClockRate / 100000));
//计数器与 PWM0LOAD 驱动器 pwmA 高电平匹配,计数器与比较器 B 驱动器 pwmA 低电平匹配
HWREG (PWM0_0_GENA_R)= 0x80C;
//计数器与 PWM0LOAD 驱动器 pwmB 为高电平匹配,计数器与比较器 B 驱动器 pwmB 为低电平匹配
HWREG (PWM0_0_GENB_R)= 0x80C;
//将 PWM CH0A/CH0B 的 PWM1CMPA 设置为0%
HWREG (PWM0_0_CMPA_R)= 0;
//将 PWM CH0A/CH0B 的 PWM1CMPA 设置为10%
HWREG (PWM0_0_CMPB_R)= MAP_PWMGenPeriodGet (CH0_CH1_CH2_CH3_PWM_base、CH1_PWM_GEN)- (MAP_PWMGenPeriodGet (CH0_CH1_CH2_CH3_PWM_base、CH1_PWM_GEN)/ 10)
//计数器与比较器 A 的驱动 pwmA 高匹配,计数器与比较器 B 的驱动 pwmA 低匹配
HWREG (PWM0_1_GENA_R)= 0x8C0;
//计数器与比较器 A 驱动 pwmB 为高电平匹配,计数器与比较器 B 驱动 pwmB 为低电平匹配
HWREG (PWM0_1_GENB_R)= 0x8C0;
//将 PWM CH1A/CH1B 的 PWM1CMPA 设置为25%
HWREG (PWM0_1_CMPA_R)= MAP_PWMGenPeriodGet (CH0_CH1_CH2_CH3_PWM_base、CH1_PWM_GEN)* 3 / 4;
//将 PWM CH1A/CH1B 的 PWM1CMPA 设置为35%
HWREG (PWM0_1_CMPB_R)=(MAP_PWMGenPeriodGet (CH0_CH1_CH2_CH3_PWM_base、CH1_PWM_GEN)* 3 / 4)-(MAP_PWMGenPeriodGet (CH0_CH1_CH2_CH3_PWM_base、CH1_GEN 1)-(MAP_PWMGen_PWM_base、CH10_PWM_GEN)
//启用 PWM 输出位0 (PF0)/位1 (PF1)/位2 (PF2)/位3 (PF3)输出信号。
MAP_PWMOutputState (CH0_CH1_CH2_CH3_PWM_BASE、CH0A_PWM_OUT_BIT | CH0B_PWM_OUT_BIT | CH1A_PWM_OUT_BIT | CH1B_PWM_OUT_BIT);
//启用 PWM 发生器模块。
MAP_PWMGenEnable (CH0_CH1_CH2_CH3_PWM_base、CH0_PWM_GEN);
MAP_PWMGenEnable (CH0_CH1_CH2_CH3_PWM_base、CH1_PWM_GEN);
}
int main (空)
{
//从 PLL 以120MHz 运行。
//注意:SYSCTL_CFG_VCO_240是 TivaWare 2.2.x 和中提供的新设置
//之后更好地反映由于 SYSCTL_22而导致的实际 VCO 速度。
G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_240)、120000000);
ConfigurePWM();
//在生成 PWM 信号时永久循环。
while (1)
{
}
}
//
// pwm_8ch.h
//
#ifndef PWM_8ch_H_
#define PWM_8CH_H_
#define CH0_CH1_CH2_CH3_PWM_Periph SYSCTL_Periph_PWM0
#define CH0_CH1_CH2_CH3_PWM_base PWM0_BASE
#define CH0A_PWM_MOUDLE_PIN GPIO_PF0_M0PWM0
#define CH0B_PWM_MOUDLE_PIN GPIO_PF1_M0PWM1
#define CH1A_PWM_MOUDLE_PIN GPIO_PF2_M0PWM2
#define CH1B_PWM_MOUDLE_PIN GPIO_PF3_M0PWM3
#define CH2A_PWM_MOUDLE_PIN GPIO_PG0_M0PWM4
#define CH2B_PWM_MOUDLE_PIN GPIO_PG1_M0PWM5
#define CH3A_PWM_MOUDLE_PIN GPIO_PK4_M0PWM6
#define CH3B_PWM_MOUDLE_PIN GPIO_PK5_M0PWM7
#define CH0_PWM_GEN PWM_GEN_0
#define CH1_PWM_GEN PWM_GEN_1
#define CH2_PWM_GEN PWM_GEN_2
#define CH3_PWM_GEN PWM_GEN_3
#define CH0A_PWM_OUT PWM_OUT_0
#define CH0B_PWM_OUT PWM_OUT_1
#define CH1A_PWM_OUT PWM_OUT_2
#define CH1B_PWM_OUT PWM_OUT_3
#define CH2A_PWM_OUT PWM_OUT_4
#define CH2B_PWM_OUT PWM_OUT_5
#define CH3A_PWM_OUT PWM_OUT_6
#define CH3V_PWM_OUT PWM_OUT_7
#define CH0A_PWM_OUT_BIT PWM_OUT_0_BIT
#define CH0B_PWM_OUT_BIT PWM_OUT_1_BIT
#define CH1A_PWM_OUT_BIT PWM_OUT_2_BIT
#define CH1B_PWM_OUT_BIT PWM_OUT_3_BIT
#define CH2A_PWM_OUT_BIT PWM_OUT_4_BIT
#define CH2B_PWM_OUT_BIT PWM_OUT_5_BIT
#define CH3A_PWM_OUT_BIT PWM_OUT_6_BIT
#define CH3V_PWM_OUT_BIT PWM_OUT_7_BIT
#define CH0_CH1_GPIO_Periph SYSCTL_Periph_GPIOF
#define CH0_CH1_GPIO_base GPIO_PORTF_BASE
#define CH2_GPIO_Periph SYSCTL_Periph_GPIOG
#define CH2_GPIO_base GPIO_PORTG_base
#define CH3_GPIO_Periph SYSCTL_Periph_GPIOK
#define CH3_GPIO_base GPIO_PORTK_base
#define CH0A_GPIO_PIN GPIO_PIN_0
#define CH0B_GPIO_PIN GPIO_PIN_1
#define CH1A_GPIO_PIN GPIO_PIN_2
#define CH1B_GPIO_PIN GPIO_PIN_3
#define CH2A_GPIO_PIN GPIO_PIN_0
#define CH2B_GPIO_PIN GPIO_PIN_1
#define CH3A_GPIO_PIN GPIO_PIN_4
#define CH3B_GPIO_PIN GPIO_PIN_5
#endif /* PWM_8ch_H_*/
您好、Charles、
感谢您的提醒。
我做了另一个实验、只需使用评估板示例 C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c129exl\pwm_invert 进行轻微修改即可。
替代 MAP_PWMGenConfigure (PWM0_BASE、PWM_GEN_1、PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
对于 MAP_PWMGenConfigure (PWM0_BASE、PWM_GEN_1、PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
替代 HWREG (PWM0_1_GENA_R)= 0x8C0;
HWREG (PWM0_1_CMPA_R)= 1000;
HWREG (PWM0_1_CMPB_R)= 500;
对于 MAP_PWMPulseWidthSet (PWM0_BASE、PWM_OUT_2、MAP_PWMGenPeriodGet (PWM0_BASE、PWM_GEN_1)/ 4);
主要目的是如何创建事件 A/B、但仍然没有 PWM 输出。
我是否应该为程序/属性设置其他任何内容?
P.S.:我已包括以下内容:
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "inc/tm4c1294ncpdt.h"
您好 Howard、
您能否显示 PWM GENA、CMPA 和 CMPB 寄存器的 CCS 寄存器窗口内容?
出于某种原因、如果我运行您拥有的以下三行代码、我将会遇到故障。
HWREG (PWM0_1_GENA_R)= 0x8C0;
HWREG (PWM0_1_CMPA_R)= 1000;
HWREG (PWM0_1_CMPB_R)= 500;
如果我用下面的代码替换、那么它可以正常工作。 我可以在示波器上看到波形。
#define PWM0_1_GENA *(volatile UINT32_t *) 0x400280A0)
#define PWM0_1_CMPA *(volatile UINT32_t *) 0x40028098)
#define PWM0_1_CMPB *(volatile UINT32_t *) 0x4002809C)
PWM0_1_GENA = 0x8C0;
PWM0_1_CMPA = 1000;
PWM0_1_CMPB = 500;
编辑时间:2021年9月9日上午11:03am:下面也可以使用。
#define PWM0_1_GENA 0x400280A0
#define PWM0_1_CMPA 0x40028098
#define PWM0_1_CMPB 0x4002809C
HWREG (PWM0_1_GENA)= 0x8C0;
HWREG (PWM0_1_CMPA)= 1000;
HWREG (PWM0_1_CMPB)= 500;
我想我遇到的故障是由于 HWREG 上的宏扩展。 请参阅下面的 HWREG 定义。
#define HWREG (x)\
(*((volatile uint32_t *)(x)))
PWM0_1_GENA_R 在 tm4c1294ncpdt.h 文件中定义如下。
#define PWM0_1_GENA_R (*((volatile uint32_t *) 0x400280A0)
当你用 x 替代 PWM0_1_GENA_R 时、宏扩展到
(*((volatile uint32_t *)(*(volatile uint32_t *) 0x400280A0)))) 这是错误的。
您好 Howard、
我认为正确的方法如下:
#include #include "inc/hw_pwm.h"
HWREG (PWM0_BASE + PWM_O_1_GENA)= 0x8C0;//正确。
以下内容也将起作用:
#include "inc/tm4c1294ncpdt.h"
PWM0_1_GENA_R = 0x8C0;//这是正常的。
以下错误:
#include "inc/tm4c1294ncpdt.h"
HWREG (PWM0_1_GENA_R)= 0x8C0;//这是错误的。