当前位置: 首页 > news >正文

16.【NXP 号令者RT1052】开发——实战-FlexPWM 输出

16.【NXP 号令者RT1052】开发——实战-FlexPWM 输出

我们之前介绍了如何使用 RT1052 的四定时器 QTMR4 的通道 3 来产生 PWM 输出。RT1052 内部有一个非常牛逼的 PWM 模块:eFlexPWM(也叫 FlexPWM),其功能非常多,本章我们将向大家介绍如何使用 FlexPWM2 的模块 3 来产生 PWM 输出。在本章中,我们将使用 FlexPWM2 的模块 3 产生 PWM 来控制 DS1 的亮度。

16.1 FlexPWM 简介

FlexPWM 全称是:Enhanced Flex Pulse Width Modulator,也叫 eFlexPWM,即增强型灵活的脉宽调制器。RT1052 内部有 4 个这种脉宽调制器(FlexPWM)模块,每个脉宽调制器模块有有 4 个子模块,每个子模块可以用于控制单个半桥功率计,且提供故障保护通道。脉宽调制器(FlexPWM)模块可以组成多种开关组合方式,可生成高度复杂的波形,它可以用于控制各种类型的电机,也是各种开关电源(SMPS)拓扑模型的理想控制器。
FlexPWM 脉宽调制器的主要特点如下:

  1. 每个脉宽调制器(FlexPWM)有 4 个子模块;
  2. 16 位精度,支持中央对齐、边沿对齐和非对称 PWM 输出;
  3. 分数 PWM 时钟生成器可生成高精度 PWM 周期和占空比;
  4. 可工作在互补输出模式或独立工作模式;
  5. 每个 PWM 输出双沿(上升沿/下降沿)可独立控制;
  6. 可与外部硬件或其他 PWM 子模块同步;
  7. 双缓冲 PWM 寄存器,可设置 1~16 的整数重载率或半周期重载;
  8. 支持 PWM 输出的双切换(周期和占空比);
  9. 故障输入可以指定连接控制多个 PWM 输出
  10. 独立的可编程 PWM 输出极性设置;
  11. 独立的死区时间设置;
  12. 增强 型双沿(上升沿/下降沿)捕获功能;

在这里插入图片描述
由图可知,FlexPWM 的每个子模块由 1 个预分频器、1 个 16 位计数器和 6 个 16 位比较器等部分组成,主要有 3 个输出信号:PWM_X、PWM_A 和 PWM_B,其中 PWM_A 和 PWM_B可以用来输出 PWM/做输入捕获,而 PWM_X 是一个辅助输出,可以独立的用作 PWM 信号,也可以用作输入捕获,我们一般使用 PWM_A 或 PWM_B 来输出 PWM 波形。

图中①处,是故障信号输入,来自模块总线,由 XBAR1 的输出通道来控制,要想正常输出 PWM,必须设置合适的故障状态,或者禁止故障检测功能,否则将无法正常输出 PWM!下图是 FlexPWM 子模块的输出逻辑:
在这里插入图片描述
图中 PWM23 和 PWM45 分别由 VAL2/VAL3 和 VAL4/VAL5 控制占空比,来自经过死区处理后的信号,本例程没用到死区控制,所以在这里对死区不做介绍。由图可知,PWM23和PWM45的输出处理路径是一样的,只是控制信号不同而已,我们以 PWM23 为例,介绍其具体的输出过程:
,用于选择输出到下一级的是 PWM23 还是 PWMAFS[0]的值,由 Disable PWM_A 信号控制,当该信号为 0 的时候,PWM23 输出到下一级,否则 PWMAFS[0]的值输出到下一级。很明显,要正常输出 PWM,必须 Disable PWM_A 信号必须为 0。PWMAFS[0]来自 SMx_OCTRL(x=0~3)寄存器。

,用于设置是否屏蔽 PWM 输出,当 MASKA=0 时,可以正常输出;当 MASKA=1 时,屏蔽 PWM 输出。MASKA 来自 PWMx_MASK(x=0~3)寄存器。

,用于设置输出有效信号极性。当 POLA=0 时,输出信号不反相;当 POLA=1 时,输出信号反相;POLA 来自 SMx_OCTRL(x=0~3)寄存器。

,用于控制 PWM 最终是否输出到 PWM_A,由 PWM_A_EN、PWMAFS[1]和 Disable PWM_A 三个信号共同控制。PWM_A_EN 由 PWMx_OUTEN(x=0~3)寄存器设置,PWMAFS[1]来自 SMx_OCTRL(x=0~3)寄存器。

,Disable PWM_A 来自故障保护单元,它由 FAULT0~3 和 Wait Mode、Debug Mode 和Stop Mode 等信号控制。我们待会重点介绍。

因此可知,PWM_A 要像正常输出来自 PWM23 的 PWM 信号,就必须设置好相应的控制位/信号:Disable PWM_A 必须为 0,MASKA 必须为 1,PWM_A_EN 必须为 1。对于 PWM_B的输出,同样也要设置类似的位/信号。

Disable PWM_A 信号来源如图:
在这里插入图片描述
由图可知 Disable PWM_A 主要来自两个方向:
1,故障输出(FAULT0~3);
2,MCU 工作模式(Wait/Debug/Stop)。正常工作时,我们只需要考虑故障输出,因此我们重点介绍下图中标注的①~⑥。
①,二或门,只要故障输出或 MCU 工作模式输出有效,则 Disable PWM_A 有效(=1)。

②,四或门,来自四个故障信号:FAULT0~FAULT3,只要任意一个故障信号有效(=1),则输出有效。

③,故障 0(FAULT0)屏蔽位(DISA0),用于设置是否屏蔽来自故障 0(FAULT0)的信号,如果我们不想让故障 0 控制我们的 PWM 输出,则可以设置该位为 0。DISA0 来自 SMx_DISMAP0(x=0~3),同样的 DISA1~DISA3 也是由该寄存器控制,分别控制 FAULT1~FAULT3 的屏蔽。注意:这些位默认都是 1 的!

④,故障输入 0 到 Disable PWM_A 输出组合路径屏蔽位,当 NOCOMB0 为 0 时,FAULT0 有两条路径可以输出到 Disable PMW_A:1,通过 NOCOMB0 与门;2,通过 FILT 过滤器;当 NOCOMB0 为1 时,则只能通过 FLIT 这条路径输出到 Disable PWM_A。NOCOMB0 来自 PWMx_FCTRL2(x=03)寄存器。同样的,NOCOMB13 也是来自该寄存器。

⑤,故障信号 0(FAULT0),来自 XBAR1 的输出。这些故障信号可以通过 XBAR1 映射到相关外部 IO 口,从而实现故障检测。具体的映射关系,详见《RT1050 参考手册》第 246 页,Table 3-6。

本章,我们通过 PWM2 的子模块 3 来产生 PWM 控制 DS1 的亮度,并不需要用到故障检测功能,所以,我们需要屏蔽故障(通过 SMx_DISMAP0 或 PWMx_FCTRL20 寄存器设置),或者设置故障值为正常(通过 XBAR1 设置)。一般我们通过设置 SMx_DISMAP0 寄存器(全 0)来屏蔽故障检测功能。

接下来,我们介绍一下 FlexPWM 子模块的时钟部分
在这里插入图片描述
此图比较简单,我们重点介绍图中标注的①~③,这三个部分。
①,时钟源选择器,由 CLK_SEL[1:0]位设置,我们一般选择 IPBus 时钟作为时钟源,IPBus时钟来自 IPG_CLK_ROOT(150Mhz)。CLK_SEL[1:0]来自 SMx_CTRL2(x=0~3)寄存器。

②,时钟预分频器,这是 8 位预分频器,但是只能设置固定的几个分频值,不能随意设置!其分频值可以是:1/2/4/8/16/32/64/128 等 7 个值,通过 PSRC[2:0]设置。PSRC[2:0]来自SMx_CTRL(x=0~3)寄存器。

③,时钟使能开关,由 RUN 位控制,如果 RUN 位为 1,则可以正常输出时钟;如果 RUN 位
为 0,则禁止输出时钟;RUN 位来自 PWMx_MCTRL(x=0~3)寄存器。
通过图中的①~③,我们就可以自由设置和选择子模块时钟,具体的设置,需要根据实际使用需求来确定。

经过以上学习,我们了解了 FlexPWM 的时钟设置、输出逻辑、故障管理和整体组成等,接下来,我们看看 FlexPWM 子模块产生 PWM 的具体过程,如图所示:

在这里插入图片描述
FlexPWM 子模块的计数器(CNT),只能工作在向上计数模式(图中类似三角波的波形),上图是 FlexPWM 子模块生成中央对齐 PWM 的时序图,因为计数方向是不可改变的,只能修改图中的③~⑨来实现中央对齐 PWM 的输出。事实上中央对齐、边沿对齐和非对称 PWM 的输出,都是通过修改这几个寄存器来实现的。注意:FlexPWM 是支持有符号操作的,如果 INIT 的值刚好和 VAL1 的值相反(值相同,符号相反),则表示是有符号模式,否则表示是无符号模式。
我们重点分析下图 17.1.5 的实现原理,为了方便说明,我们在图中标注了①~⑨。

①,PWM_A 波形,其波形是以 VAL0 的值中心对称的。PWM_A 波形由 VAL2 控制上升沿,由VAL3 控制下降沿,只要 VAL0-VAL2=VAL3-VAL0,则是中心对称模式。

②,PWM_B 波形,其波形也是以 VAL0 的值中心对称的。PWM_B 波形由 VAL4 控制上升沿,由VAL5 控制下降沿,只要 VAL0-VAL4=VAL5-VAL0,则是中心对称模式。

③,INIT 寄存器,用于设置 CNT 的初始值。这是一个有符号 16 位寄存器,它可以设置成负数或者正数,图 17.1.5 种设置的 INIT 值为 0XFF00,即-256,是负数。该寄存器用于在每个PWM 周期的启动时初始化 CNT 值(也就是 CNT 达到 VAL1 溢出后,都会将 INIT 的值重新赋值到CNT)。该寄存器和 VAL1 共同决定是否工作在有符号模式,只要这两个寄存器的值不刚好相反,则是工作在无符号模式,一般建议用无符号模式。

④,VAL0 寄存器,用于设置 CNT 的中间值。这是一个有符号 16 位寄存器,该寄存器的值介于 INIT 和 VAL1 之间,一般等于(VAL1-INIT)/2。

⑤,VAL1 寄存器,用于设置 CNT 计数器的最大值。这是一个有符号 16 位寄存器,该寄存器和 INIT 寄存器共同决定是否工作在有符号模式。

⑥,VAL2 寄存器,用于控制 PWM_A 的上升沿。这是一个有符号 16 位寄存器,通过它可以决定 PWM_A 波形高电平的起始时间。

⑦,VAL3 寄存器,用于控制 PWM_A 的下降沿。这是一个有符号 16 位寄存器,通过它可以决定PWM_A 波形高电平的结束时间。INIT、VAL1、VAL2 和 VAL3 共同决定了 PWM_A 的波形。

⑧,VAL4 寄存器,用于控制 PWM_B 的上升沿。这是一个有符号 16 位寄存器,通过它可以决定 PWM_B 波形高电平的起始时间。

⑨,VAL5 寄存器,用于控制 PWM_B 的下降沿。这是一个有符号 16 位寄存器,通过它可以决定 PWM_B 波形高电平的结束时间。INIT、VAL1、VAL4 和 VAL5 共同决定了 PWM_B 的波形。注意:INIT、VAL0~VAL5 等七个寄存器都是有缓冲的,我们写入这些寄存器的值并不会立即生效,必须设置 PWMx_MCTRL(x=0~3)寄存器的 LDOK 位,然后在下一个 PWM 周期开始的时候,会将写入这些寄存器的值加载到缓冲寄存器里面,然后设置的值才会生效。

上图 中是中央对齐模式的设置,如果我们调整 INIT 和 VAL0~VAL5 的值,则可以实现很多种不同模式的 PMW 波形输出。详见《RT1050 参考手册》第 1425 页 28.5.1 节。

本章,我们将使用 PWM2 子模块 3 的 PWM_B 输出来控制 DS1 的亮度,实现类似第 15 章的控制效果,即:DS1 不停的由暗变到亮,然后又从亮变到暗。

好的,我来帮你把这部分内容整理成 Markdown 格式,保持代码原样不动,仅仅排版清晰:


RT1052 FlexPWM2 配置步骤

1. 设置 GPIO3_IO03 复用功能

IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_FLEXPWM2_PWMB03,0);
IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_03_FLEXPWM2_PWMB03,0x10B0);

2. 使能 FlexPWM2 时钟

CLOCK_EnableClock(kCLOCK_Pwm2)

此函数会被 PWM_Init 调用,无需显式调用。


3. 初始化 FlexPWM2

status_t PWM_Init(PWM_Type *base, pwm_submodule_t subModule, const pwm_config_t *config)
  • base:指定 PWM,本例为 PWM2
  • subModule:子模块选择,本例为 kPWM_Module_3
  • config:配置结构体 pwm_config_t
示例配置
pwm_config_t pwm2sm3_config; //PWM2 模块 3 配置结构体
//初始化 PWM2 模块 3 的通道 B
PWM_GetDefaultConfig(&pwm2sm3_config); //先初始化为默认配置
pwm2sm3_config.clockSource = kPWM_BusClock; //时钟源为 IP BUS=150MHz
pwm2sm3_config.prescale = kPWM_Prescale_Divide_128; //设置 128 分频
pwm2sm3_config.reloadLogic = kPWM_ReloadPwmFullCycle; //全周期更新
pwm2sm3_config.pairOperation = kPWM_Independent; //PMWA PWMB 独立模式
PWM_Init(PWM2, kPWM_Module_3, &pwm2sm3_config); //初始化 PWM2 模块 3

4. 关闭故障检测功能

PWM2->SM[3].DISMAP[0] = 0; 

5. 配置 PWM2 的 PWMB 通道

status_t PWM_SetupPwm(PWM_Type * base,pwm_submodule_t subModule,const pwm_signal_param_t * chnlParams,uint8_t numOfChnls,pwm_mode_t mode,uint32_t pwmFreq_Hz,uint32_t srcClock_Hz)
示例配置:10KHz,50% 占空比
u32 sourceclock;
//设置 PWM2_PWMB 通道
sourceclock = CLOCK_GetFreq(kCLOCK_IpgClk);
//PWMB
pwm_ignal.pwmChannel = kPWM_PwmB; //PWM 通道 B
pwm_ignal.level = kPWM_HighTrue; //高电平有效
pwm_ignal.dutyCyclePercent = 50; //50%占空比
//设置 PWM2,中央对齐模式
PWM_SetupPwm(PWM2, //PWM2kPWM_Module_3, //PWM2 的子模块 3&pwm_ignal, //PWM 通道配置参数结构体1, //配置一个 PWM 通道kPWM_CenterAligned, //无符号中央对齐模式10000, //PWM 频率为 10KHzsourceclock); //PWM 时钟源为 150MHzPWM_SetPwmLdok(PWM2, kPWM_Control_Module_3, true); //设置 PWM 的 load ok 位

6. 开启 PWM2

PWM_StartTimer(PWM2, kPWM_Control_Module_3); //开启 PWM

7. 动态更新占空比

void PWM_UpdatePwmDutycycle(PWM_Type * base,pwm_submodule_t subModule,pwm_channels_t pwmSignal,pwm_mode_t currPwmMode,uint8_t dutyCyclePercent)
  • pwmSignal:选择通道 (kPWM_PwmB / kPWM_PwmA / kPWM_PwmX)
  • currPwmMode:当前 PWM 对齐模式
  • dutyCyclePercent:占空比百分比 (0~100)

16.2 硬件设计

本实验用到的硬件资源有:

  1. 指示灯 DS1
    本章将通过 PWM2 子模块 3 的 PWM_B 来控制 DS1 的亮度,DS1 是连接到 GPIO3_IO03(P303)上的,这个前面已经有介绍了。而 PWM2 子模块 3 的 PWM_B 的输出是可以连接在GPIO3_IO03(P303)上的,刚好和 DS1 是同一个脚,所以硬件不需要做任何变化,直接写代码即可。

16.3 软件设计

本章,我们依旧是在前一章的基础上修改代码,先打开之前的工程,在 HARDWARE 文件夹下新建 FLEXPWM 文件夹。然后打开 USER 文件夹下的工程,新建一个 flexpwm.c 的文件和flexpwm.h 的头文件,保存在 FLEXPWM 文件夹下,并将 FLEXPWM 文件夹加入头文件包含路径。

flexpwm.c

#include "flexpwm.h"
#include "lpuart.h"pwm_config_t pwm2sm3_config;    //PWM2模块3配置结构体//初始化FLEXPWM,PWM2的模块3的通道A和B
//通过PWM2的模块3在通道A和B上面产生2路PWM输出.
//即在GPIO3_IO02和GPIO3_IO03上面输出PWM.
//psc : 预分频器,0~7,表示2^psc分频.
//fre : 频率
//duty:占空比
void PWM2_SM3_PWMAB_Init(u16 psc,u32 fre,u8 duty)
{u32 sourceclock;pwm_signal_param_t pwm_ignal;pwm_clock_prescale_t pwm_prescale=(pwm_clock_prescale_t)psc; //分频//IO功能设置IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_03_FLEXPWM2_PWMB03,0);   IOMUXC_SetPinMux(IOMUXC_GPIO_SD_B1_02_FLEXPWM2_PWMA03,1);   //配置IO引脚GPIO_SD_B1_02和GPIO_SD_B1_03的功能//低转换速度,驱动能力为R0/6,速度为100Mhz,关闭开路功能,使能pull/keepr//选择keeper功能,下拉100K Ohm,关闭HystIOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_03_FLEXPWM2_PWMB03,0x10B0);IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B1_02_FLEXPWM2_PWMA03,0x10B0);//初始化PWM2 模块3的通道BPWM_GetDefaultConfig(&pwm2sm3_config);              //先初始化为默认配置pwm2sm3_config.clockSource=kPWM_BusClock;           //时钟源为IP BUS=IPG_CLK_ROOT=150MHzpwm2sm3_config.prescale=pwm_prescale;               //设置分频pwm2sm3_config.reloadLogic=kPWM_ReloadPwmFullCycle; //全周期更新pwm2sm3_config.pairOperation=kPWM_Independent;      //PMWA PWMB独立模式PWM_Init(PWM2,kPWM_Module_3,&pwm2sm3_config);       //初始化PWM2模块3//屏蔽故障检测功能PWM2->SM[3].DISMAP[0]=0;     //设置PWM2B通道sourceclock=CLOCK_GetFreq(kCLOCK_IpgClk);//PWMBpwm_ignal.pwmChannel=kPWM_PwmB;                     //PWM通道Bpwm_ignal.pwmChannel=kPWM_PwmA;                     //PWM通道Apwm_ignal.level=kPWM_HighTrue;                      //高电平有效pwm_ignal.dutyCyclePercent=duty;                    //占空比//设置PWM2,中央对齐模式PWM_SetupPwm(PWM2,kPWM_Module_3,&pwm_ignal,2,kPWM_CenterAligned,fre,sourceclock);//使用了两个通道PWM_SetPwmLdok(PWM2,kPWM_Control_Module_3,true);    //设置PWM的load ok位PWM_StartTimer(PWM2,kPWM_Control_Module_3);         //开启定时器}//更新PWM2占空比
//duty:占空比
void PWM2_SM3_DutySet(u8 duty) 
{PWM_UpdatePwmDutycycle(PWM2,kPWM_Module_3,kPWM_PwmA,kPWM_CenterAligned,duty); //更新PWMB占空比PWM_UpdatePwmDutycycle(PWM2,kPWM_Module_3,kPWM_PwmB,kPWM_CenterAligned,duty); //更新PWMB占空比PWM_SetPwmLdok(PWM2,kPWM_Control_Module_3,true);    //设置PWM的load ok位
}

此部分代码就二个函数:PWM2_SM3_PWMAB_Init 和 PWM2_SM3_DutySet,先来看一下函数 PWM2_SM3_PWMAB_Init,此函数有 3 个参数:
psc:用于设置预分频系数,取值范围:0~7,代表 1~128 分频。
fre:PWM 的频率,单位为 Hz,如要设置频率为 10KHz 的 PWM,此参数就设置为 10000。
duty:要设置的占空比(百分比),0~100 表示 0%~100%。函数 PWM2_SM3_DutySet 用来修改 PWM2 子模块 3 的 PWMB 通道的占空比,所以此函数只有一个参数:duty,此参数就是要设置的占空比(百分比),0~100 表示占空比 0%~100%。

flexpwm.h

#ifndef _FLEXPWM_H
#define _FLEXPWM_H
#include "sys.h"void PWM2_SM3_PWMAB_Init(u16 psc,u32 fre,u8 duty);	//PWM2 SM3 PWM输出初始化函数
void PWM2_SM3_DutySet(u8 duty);     //设置PWM2_SM3两个通道的占空比
#endif

main.c

#include "sys.h"
#include "lpuart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "wdog.h"
#include "rtwdog.h"
#include "gptimer.h"
#include "pitimer.h"
#include "qtimer.h"
#include "pwm.h"
#include "xbar.h"
#include "flexpwm.h"int main(void)
{u8 key=0;MPU_Memory_Protection();    //初始化MPURT1052_Clock_Init();	    //配置系统时钟DELAY_Init(600);		    //延时函数初始化LPUART1_Init(115200);       //初始化串口1RT1052_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);//优先级分组4
#ifdef LED_DEBUGu8 led0sta=1,led1sta=1;     //LED0,LED1的当前状态LED_Init();				    //初始化LED
#endif
#ifdef KEY_DEBUGKEY_Init();                 //初始化KEY
#endif
#ifdef LPUART_DEBUGu8 len;					//接收数据长度u16 times=0;            //延时计数器LED0(0);					//先点亮红灯 
#endif
#ifdef EXTIX_DEBUGEXTIX_Init();			    //初始化外部中断
#endif
#ifdef WDOG_DEBUGWDOG1_Init(3,2);		    //初始化看门狗1,2秒溢出,提前1秒进入中断,方便喂狗LED0(0);               	    //先点亮LED灯delay_ms(300);				//延时300ms再初始化看门狗,LED0的变化"可见"
#endif
#ifdef RTWDOG_DEBUGLED_Init();				    //初始化LED KEY_Init();                 //初始化KEYdelay_ms(100);         	    //延时100ms再初始化看门狗,LED0的变化"可见"MYRTWDOG_Init(1,0,32768,0);	//初始化RT看门狗,1秒溢出,非窗口模式LED0(0);               	    //先点亮LED灯
#endif
#ifdef GPT1_DEBUGLED_Init();				    //初始化LED  KEY_Init();                 //初始化按键GPT1_Int_Init(3750-1,10000); //设置GPT1 0.5秒钟产生一次中断
#endif
#ifdef PIT_DEBUGLED_Init();				    //初始化LED  PIT_CH0_Int_Init(75000000/2);	//设置PIT 0.5秒钟产生一次中断
#endif
#ifdef QTMR_DEBUGKEY_Init();                 //初始化按键LED_Init();				            //初始化LEDQTMR1_CH0_Int_Init(15,46875);	//设置QTMR1 0.04秒钟产生一次中断
#endif
#ifdef QTMR_PWM_DEBUGu8 dir=1; u16 led1pwmval=0;    gpio_pin_config_t led_config;LED_Init();				    //初始化LED  KEY_Init();                 //初始化按键//初始化PWM,定时器时钟为:150/64=2.34375Mhz,设置频率为5Khz,50%占空比QTMR4_CH3_PWM_Init(14,5000,0);//设置P103为输入模式,防止干扰PWMled_config.direction=kGPIO_DigitalInput;	//输出led_config.interruptMode=kGPIO_NoIntmode;	//不使用中断功能led_config.outputLogic=0;					//默认高电平,LED灯关闭GPIO_PinInit(GPIO1,3,&led_config); 	        //初始化GPIO1_3
#endif
#ifdef XBAR_DEBUGu8 dir=1; u16 led1pwmval=0;  //初始化PWM,定时器时钟为:150/64=2.34375Mhz,设置频率为5Khz,50%占空比QTMR4_CH3_PWM_Init(14,5000,50); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_03_XBAR1_INOUT17,0);	//GPIO_AD_B0_03配置为ALT1,即XBAR1_INOUT17XBARA1_Signal_Set(kXBARA1_InputQtimer4Tmr3Output,kXBARA1_OutputIomuxXbarInout17);   //QTMR4_CH3输出到XBARA1_INOUT17上面.//即:通过GPIO_AD_B0_03(GPIO1_IO03)输出QMR4_CH3的波形.
#endifu8 dir=1; u16 led1pwmval=0;  LED_Init();				    //初始化LED  KEY_Init();                 //初始化按键PWM2_SM3_PWMAB_Init(7,1000,50);    //初始化PWM2,128分频,1K频率,50%占空比while(1){delay_ms(10);	 if(dir)led1pwmval++;else led1pwmval--;	 if(led1pwmval>=100)dir=0;if(led1pwmval==0)dir=1;	 PWM2_SM3_DutySet(led1pwmval); 
#ifdef XBAR_DEBUGdelay_ms(10);	 if(dir)led1pwmval++;else led1pwmval--;	 if(led1pwmval>=100)dir=0;if(led1pwmval==0)dir=1;	 QTMER4CH3_PWM_DutySet(14,5000,led1pwmval);
#endif
#ifdef QTMR_PWM_DEBUGdelay_ms(10);	 if(dir)led1pwmval++;else led1pwmval--;	 if(led1pwmval>=100)dir=0;if(led1pwmval==0)dir=1;	 QTMER4CH3_PWM_DutySet(14,5000,led1pwmval);
#endif
#ifdef QTMR_DEBUGLED0_Toggle;delay_ms(1000);
#endif
#ifdef PIT_DEBUGLED0_Toggle;delay_ms(1000);
#endif
#ifdef GPT1_DEBUGLED0_Toggle;delay_ms(1000);
#endif
#ifdef RTWDOG_DEBUGkey=KEY_Scan(0);if(key==WKUP_PRES)		//如果按键按下,则喂狗.{RTWDOG_Feed();} delay_ms(10);
#endif
#ifdef WDOG_DEBUGLED0(1);				//关闭DS0,如不复位,DS0将一直处于关闭状态.delay_ms(100);
#endif
#ifdef EXTIX_DEBUGprintf("Int example driver!\r\n");delay_ms(1000);
#endif
#ifdef KEY_DEBUGkey=KEY_Scan(0); 		    //得到键值if(key){	switch(key){				 case WKUP_PRES:	//控制LED0,LED1互斥点亮led1sta=!led1sta;led0sta=!led1sta;break;case KEY2_PRES:	//控制LED0翻转led0sta=!led0sta;break;case KEY1_PRES:	//控制LED1翻转	 led1sta=!led1sta;break;case KEY0_PRES:	//同时控制LED0,LED1翻转 led0sta=!led0sta;led1sta=!led1sta;break;}LED0(led0sta);		//控制LED0状态LED1(led1sta);		//控制LED1状态}else delay_ms(10);
#endif // KEY_DEBUG
#ifdef LPUART_DEBUGif(LPUART_RX_STA&0x8000){					   len=LPUART_RX_STA&0x3fff;//得到此次接收到的数据长度printf("\r\n发送的消息为:\r\n");LPUART_WriteBlocking(LPUART1,LPUART_RX_BUF,len);//发送接收到的数据printf("\r\n\r\n");//插入换行LPUART_RX_STA=0;}else{times++;if(times%5000==0){printf("\r\nALIENTEK RT1052开发板 串口实验\r\n");}if(times%200==0)printf("请输入数据,以回车键结束\r\n");  if(times%30==0)LED0_Toggle;//闪烁LED,提示系统正在运行.delay_ms(10);   }
#endif // LPUART_DEBUG}
}

main 函数和之前的代码类似,通过 PWM2_SM3_PWMAB_Init 设置 PWM2 子模块 3 的相关参数,完成初始化设置,这里我们设置 PWM 频率为 1KHz,占空比为 50%。在死循环里面,我们通过 led1pwmval 的值来控制 DS1 的亮度。led1pwmval 的值从 0 变到300,然后又从 300 变到 0,如此循环,因此 DS1 的亮度也会跟着从暗变到亮,然后又从亮变到暗。至此,我们的软件设计就完成了。
在这里插入图片描述
在这里插入图片描述

总结

FlexPWM(eFlexPWM)是 RT1052 内部增强型的脉宽调制器模块,专门用于产生高精度、灵活的 PWM 波形。它支持中央对齐、边沿对齐和非对称输出,具备故障保护、死区控制、双缓冲寄存器、独立或互补输出等功能,可用于电机控制、开关电源等复杂应用场景。本章通过配置 FlexPWM2 子模块 3 的 PWMB 通道输出 PWM,动态调整占空比来控制 DS1 的亮度,实现 LED 从暗到亮再从亮到暗的循环变化。
OK!谢谢大家!

http://www.dtcms.com/a/606690.html

相关文章:

  • Datawhale coze-ai-assistant task2
  • NESTJS - RSA加解密
  • 自己服务器可以做网站如何做家教网站赚钱
  • 开发外贸网站开发企业官网的建设
  • 一、Rabbit MQ 初级
  • 单位网站建设费用神马搜索推广
  • 【MySQL】MySQL内置函数--日期函数字符串函数数学函数其他相关函数
  • 数据结构 力扣 练习
  • 2018年网站建设发言凯里网站开发
  • XML 和 JSON -----几种重要模式
  • 【读论文】基于LLM增强的全双工对话
  • 怎么做网站不被发现崇明网站开发
  • Java后端常用技术选型 |(二)工具类篇
  • FPGA教程系列-Vivado IP核BMG核
  • 【1.11】基于FPGA的costas环开发5——环路滤波器模块开发
  • 济南行知网站建设南京淄博网站建设工作室
  • 网站木马 代码网站建设新手
  • 汕头市国外网站建设公司百度关键词优化查询
  • 业务流低代码平台:从理念到实战
  • DebugView 学习笔记(8.9):什么是调试输出?为什么它是现场排障的“读心术”
  • RSS 语法:全面解析与优化指南
  • php能做手机网站吗口碑营销成功的案例
  • 【每日一面】BOM 是什么
  • 稀土抑烟剂在透明膜上的应用:安全与环保的双重保障
  • 郑州网站建设中心wordpress2016
  • 最新企业网站制作短链接网站
  • 建设部标准规范网站网页设计与制作教程考试试卷
  • 基于Python+OpenCV实现双目立体视觉的图像匹配与测距
  • duckdb使用详解
  • 【愚公系列】《MCP协议与AI Agent开发》010-MCP协议标准与规范体系(协议消息结构设计)