Enhance Timer PWM

该示例通过使用ENHTIM,实现输出周期为100us、占空比为50%的 PWM 波形。

在示例中可以通过配置宏 ENHTIM_PWM_MANUAL_MODEENHTIM_PWM_AUTO_MODE 来选择输出的PWM波形占空比是否可变。

如果选用 ENHTIM_PWM_MANUAL_MODE ,可以输出周期100us,占空比为50%的PWM波形。

如果选用 ENHTIM_PWM_AUTO_MODE ,可以输出周期为2.5us,占空比可调节的波形。

环境需求

该示例支持以下开发套件:

开发套件

Hardware Platforms

Board Name

RTL87x2G HDK

RTL87x2G EVB

更多信息请参考快速入门

硬件连线

连接P0_0和P0_1至逻辑分析仪。

配置选项

该示例可配置的宏如下:

  1. ENHTIM_PWM_AUTO_MODE :配置该宏可选择输出模式为自动模式。在自动模式下,可以预先设定输出PWM波形的占空比,即输出占空比可变的PWM。

  2. ENHTIM_PWM_MANUAL_MODE :配置该宏可选择输出模式为用户自定义手动模式。在手动模式下,可输出固定占空比的PWM。

编译和下载

该示例的工程路径如下:

Project file: samples\peripheral\enhtimer\enhtim_pwm\proj\rtl87x2g\mdk

Project file: samples\peripheral\enhtimer\enhtim_pwm\proj\rtl87x2g\gcc

请按照以下步骤操作构建并运行该示例:

  1. 打开工程文件。

  2. 按照 快速入门编译APP Image 给出的步骤构建目标文件。

  3. 编译成功后,在路径 mdk\bingcc\bin 下会生成 app bin app_MP_xxx.bin 文件。

  4. 按照 快速入门MP Tool 给出的步骤将app bin烧录至EVB内。

  5. 按下复位按键,开始运行。

测试验证

  1. 通过逻辑分析仪看P0_0和P0_1输出的PWM波形。

    1. 如果选择输出的PWM模式为 ENHTIM_PWM_MANUAL_MODE ,P0_0输出周期为100us,占空比为50%的PWM波,P0_1输出与P0_0反相的相同周期和占空比的PWM波。

      这里应该是enhtim输出pwm的图片

      Manual模式下PWM的输出波形

    2. 如果选择输出的PWM模式为 ENHTIM_PWM_AUTO_MODE ,P0_0输出周期为2.5us的PWM波,其中占空比依次从100%到0%,变化8次。在变化8次占空比后,后续的PWM输出波形会维持最后一次设置的占空比。P0_1输出与P0_0反相的相同周期和占空比的PWM波。

      这里应该是enhtim输出pwm的图片

      Auto模式下PWM的输出波形

代码介绍

该章节分为以下几个部分:

  1. 源码路径

  2. 初始化函数将在 初始化 章节介绍。

源码路径

  • 工程路径: sdk\samples\peripheral\enhtimer\enhtim_pwm\proj

  • 源码路径: sdk\samples\peripheral\enhtimer\enhtim_pwm\src

该工程的工程文件代码结构如下:

└── Project: input_interrupt
    └── secure_only_app
        └── Device                   includes startup code
            ├── startup_rtl.c
            └── system_rtl.c
        ├── CMSIS                    includes CMSIS header files
        ├── CMSE Library             Non-secure callable lib
        ├── Lib                      includes all binary symbol files that user application is built on
            └── rtl87x2g_io.lib
        ├── Peripheral               includes all peripheral drivers and module code used by the application
            ├── rtl_rcc.c
            ├── rtl_pinmux.c
            └── rtl_enh_tim.c
        └── APP                      includes the ble_peripheral user application implementation
            ├── main_ns.c
            └── io_enhtimer_pwm.c

初始化

初始化流程包括了 board_enhance_pwm_initenhance_timer_init


board_enhance_pwm_init 中包含了PAD与PINMUX设置。

  1. 配置PAD:设置引脚、PINMUX模式、PowerOn、无内部上拉。

  2. 配置PINMUX:分配引脚分别为PWM_P、PWN_N功能。


enhance_timer_init 包含了对ENHTIM外设的初始化。

  1. 使能PCC时钟。

  2. 设置 ENHTIM_ClockDiv 为1分频。

  3. 如果选择输出的PWM模式为 ENHTIM_PWM_AUTO_MODE

    1. 设置 ENHTIM_PWMOutputEn 为ENABLE,开启ENHTIM的PWM功能。

    2. 设置 ENHTIM_PWMStartPolarityENHTIM_PWM_START_WITH_HIGH ,即PWM初始输出电平为高。

    3. 设置 ENHTIM_MaxCount 为100,即PWM的输出周期为2.5us。

    4. 如果需要改变PWM输出的占空比,可以调用 ENHTIM_WriteCCFIFO() 函数进行更改,最多支持连续更改8次。

  4. 如果选择输出的PWM模式为 ENHTIM_PWM_MANUAL_MODE

    1. 设置 ENHTIM_PWMOutputEn 为ENABLE,开启ENHTIM的PWM功能。

    2. 设置 ENHTIM_PWMStartPolarityENHTIM_PWM_START_WITH_HIGH ,即PWM初始输出电平为高。

    3. 设置 ENHTIM_MaxCount 为4000,即PWM的输出周期100us。

    4. 设置 ENHTIM_CCValue 为2000,即PWM的占空比为50% (2000/4000)。

  5. 设置 ENHTIM_PWMDeadZoneClockSourceENHTIM_PWM_DZCLKSRCE_32K ,即PWM死区的时钟源为32k。

  6. 设置 ENHTIM_PWMDeadZoneEn 为ENABLE,即开启PWM的死区功能。

  7. 设置 ENHTIM_PWMStopStatePENHTIM_PWM_STOP_AT_HIGH ,即PWM_P输出的初始电平为高。

  8. 设置 ENHTIM_PWMStopStateNENHTIM_PWM_STOP_AT_LOW ,即PWM_N的初始电平为低。

  9. 设置 ENHTIM_DeadZoneSize 为0x0。

  RCC_PeriphClockCmd(APBPeriph_ENHTIMER, APBPeriph_ENHTIMER_CLOCK, ENABLE);
  ...
  ENHTIM_InitStruct.ENHTIM_ClockDiv = ENHTIM_CLOCK_DIVIDER_1;

#if ENHTIM_PWM_AUTO_MODE
  ENHTIM_InitStruct.ENHTIM_Mode               = ENHTIM_MODE_PWM_AUTO;
  ENHTIM_InitStruct.ENHTIM_PWMOutputEn        = ENABLE;
  ENHTIM_InitStruct.ENHTIM_PWMStartPolarity   = ENHTIM_PWM_START_WITH_HIGH;
  ENHTIM_InitStruct.ENHTIM_MaxCount           = 100;
#endif

#if ENHTIM_PWM_MANUAL_MODE
  ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_MODE_PWM_MANUAL;
  ENHTIM_InitStruct.ENHTIM_PWMOutputEn = ENABLE;
  ENHTIM_InitStruct.ENHTIM_PWMStartPolarity = ENHTIM_PWM_START_WITH_HIGH;
  ENHTIM_InitStruct.ENHTIM_MaxCount = 4000;
  ENHTIM_InitStruct.ENHTIM_CCValue = 2000;
#endif

  ENHTIM_InitStruct.ENHTIM_PWMDeadZoneClockSource = ENHTIM_PWM_DZCLKSRCE_32K;
  ENHTIM_InitStruct.ENHTIM_PWMDeadZoneEn = ENABLE;
  ENHTIM_InitStruct.ENHTIM_PWMStopStateP = ENHTIM_PWM_STOP_AT_HIGH;
  ENHTIM_InitStruct.ENHTIM_PWMStopStateN = ENHTIM_PWM_STOP_AT_LOW;
  ENHTIM_InitStruct.ENHTIM_DeadZoneSize = 0x0;

  ENHTIM_Init(Enhance_Timer, &ENHTIM_InitStruct);

#if ENHTIM_PWM_AUTO_MODE
  /* After the waveform is transformed 8 times,
  the PWM maintains the last change and continues to output */
  ENHTIM_WriteCCFIFO(Enhance_Timer, 0); //Output high level with a duty cycle of 100%
  ENHTIM_WriteCCFIFO(Enhance_Timer, 20); //Output high level with a duty cycle of 80%
  ENHTIM_WriteCCFIFO(Enhance_Timer, 40); //Output high level with a duty cycle of 60%
  ENHTIM_WriteCCFIFO(Enhance_Timer, 50); //Output high level with a duty cycle of 50%
  ENHTIM_WriteCCFIFO(Enhance_Timer, 70); //Output high level with a duty cycle of 30%
  ENHTIM_WriteCCFIFO(Enhance_Timer, 80); //Output high level with a duty cycle of 20%
  ENHTIM_WriteCCFIFO(Enhance_Timer, 90); //Output high level with a duty cycle of 10%
  ENHTIM_WriteCCFIFO(Enhance_Timer, 100); //Output low level with a duty cycle of 100%
#endif

  ENHTIM_Cmd(Enhance_Timer, ENABLE);