产生PWM的方式有很多,这里尝试使用TC275的GPT12模块,来产生具有固定频率和可变占空比的PWM信号。
GPT12就是General Purpose Timer Unit通用定时器模块,它包含5个16位定时器,被分给GPT1和GPT2。
这里使用GPT1(T2、T3、T4),有四种模式:定时器模式、计数器模式、门控制定时器模式、增量接口模式。
每个定时器都是由一个单独的控制寄存器TxCON控制。

GPT12模块的配置过程

  1. 使能GPT12模块
  2. 通过预分频器BPS1的值配置GPT1模块的频率
  3. 通过预分频器T3I的值配置T3的频率
  4. 配置定时器T3的模式、方向和启动值
  5. 配置两个辅助定时器(定时器模式、重载输入模式、重载值)

    GPT12模块配置的相关函数

    10GPT12_PWM_Generation - 图1
    代码如下:

    1. /* Enable the GPT12 module */
    2. IfxGpt12_enableModule(&MODULE_GPT120);
    3. /* Set GPT1 block prescaler to divide the module frequency */
    4. IfxGpt12_setGpt1BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt1BlockPrescaler_32);
    5. /* Set the GPT12 timer T3 in timer mode */
    6. IfxGpt12_T3_setMode(&MODULE_GPT120, IfxGpt12_Mode_timer);
    7. /* Set the Timer T3 direction */
    8. IfxGpt12_T3_setTimerDirection(&MODULE_GPT120, IfxGpt12_TimerDirection_down);
    9. /* Set timer T3 input prescaler to divide the timer frequency */
    10. IfxGpt12_T3_setTimerPrescaler(&MODULE_GPT120, IfxGpt12_TimerInputPrescaler_32);

    重新加载值的计算:

    根据给定的频率和占空比,计算重载值。(同样在initGpt12PWM()中完成这个任务)
    首先,通过IfxGpt12_getModuleFrequency() 获得GPT12的基础频率:

    1. float32 moduleFreq = IfxGpt12_getModuleFrequency(&MODULE_GPT120);

    然后,计算定时器的基础频率:
    image.png

    1. float32 fTimer = (moduleFreq / (GPT1_BLOCK_PRESCALER * TIMER_T3_INPUT_PRESCALER));
    1. #define GPT1_BLOCK_PRESCALER 32 /* GPT1 block prescaler value */
    2. #define TIMER_T3_INPUT_PRESCALER 32 /* Timer input prescaler value */

    然后,计算dutyUpTime和dutyDownTime时间:
    image.png
    代码如下:

    1. /* Calculate dutyUpTime and dutyDownTime for reloading timer T3 */
    2. float32 moduleFreq = IfxGpt12_getModuleFrequency(&MODULE_GPT120);
    3. float32 fTimer = (moduleFreq / (GPT1_BLOCK_PRESCALER * TIMER_T3_INPUT_PRESCALER));
    4. uint16 dutyUpTime = (fTimer * (PWM_DUTY_CYCLE / 100.0f)) / PWM_FREQUENCY;
    5. uint16 dutyDownTime = (fTimer * (1 - (PWM_DUTY_CYCLE / 100.0f))) / PWM_FREQUENCY;
    6. /* Set timer T3 value */
    7. IfxGpt12_T3_setTimerValue(&MODULE_GPT120, dutyDownTime);

    配置定时器T2和T4,使能定时器T3的重载值:

    10GPT12_PWM_Generation - 图4
    代码如下:

    1. /* Timer T2: reloads the value dutyDownTime in timer T3 */
    2. /* Set the timer T2 in reload mode */
    3. IfxGpt12_T2_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload);
    4. /* Set the T2 input parameter: Negative transition (falling edge) of T3 toggle latch T3OTL */
    5. IfxGpt12_T2_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_fallingEdgeTxOTL);
    6. /* Set timer T2 value (the value that is reloaded in T3 on negative transition) */
    7. IfxGpt12_T2_setTimerValue(&MODULE_GPT120, dutyDownTime);
    8. /* Timer T4: reloads the value dutyUpTime in timer T3 */
    9. /* Set timer T4 in reload mode */
    10. IfxGpt12_T4_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload);
    11. /* Set the T4 input parameter: Positive transition (rising edge) of T3 toggle latch T3OTL */
    12. IfxGpt12_T4_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_risingEdgeTxOTL);
    13. /* Set timer T4 value (the value that is reloaded in T3 on positive transition) */
    14. IfxGpt12_T4_setTimerValue(&MODULE_GPT120, dutyUpTime);

    GPT12中断配置

    指针参数:使用一个定时器T3服务请求的地址、中断提供者、中断优先级。

    1. /* Configure the GPT12 interrupt */
    2. volatile Ifx_SRC_SRCR *src = IfxGpt12_T3_getSrc(&MODULE_GPT120); /* Get interrupt address */
    3. IfxSrc_init(src, ISR_PROVIDER_GPT12_TIMER, ISR_PRIORITY_GPT12_TIMER); /* Initialize the service request */
    4. IfxSrc_enable(src);

    启动定时器T3

    1. IfxGpt12_T3_run(&MODULE_GPT120, IfxGpt12_TimerRun_start); /* Start the timer T3 */

    完整代码

    ```c /*/ /——————————————————————————-Includes———————————————————————————/ /*/

    include “GPT12_PWM_Generation.h”

    include “Ifx_Types.h”

    include “IfxGpt12.h”

    include “IfxPort.h”

/*/ /———————————————————————————Macros———————————————————————————-/ /*/

define ISR_PRIORITY_GPT12_TIMER 6 / Define the GPT12 Timer interrupt priority /

define ISR_PROVIDER_GPT12_TIMER IfxSrc_Tos_cpu0 / Interrupt provider /

define PWM_FREQUENCY 2.0f / Frequency of the PWM signal in Hz /

define PWM_DUTY_CYCLE 50 / Duty cycle of the PWM signal in percentage /

define LED &MODULE_P00, 5 / LED which toggles in the Interrupt Service Routine /

define GPT1_BLOCK_PRESCALER 32 / GPT1 block prescaler value /

define TIMER_T3_INPUT_PRESCALER 32 / Timer input prescaler value /

/*/ /——————————————————————Function Implementations———————————————————————-/ /*/ / Macro to define Interrupt Service Routine / IFX_INTERRUPT(interruptGpt12, 0, ISR_PRIORITY_GPT12_TIMER);

/ Interrupt Service Routine of the GPT12 / void interruptGpt12(void) { / Toggle the state of the LED / IfxPort_togglePin(LED); }

/ Function to initialize the GPT12 module and the LED / void initGpt12PWM(void) { / Enable the GPT12 module / IfxGpt12_enableModule(&MODULE_GPT120); / Set GPT1 block prescaler to divide the module frequency / IfxGpt12_setGpt1BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt1BlockPrescaler_32); / Set the GPT12 timer T3 in timer mode / IfxGpt12_T3_setMode(&MODULE_GPT120, IfxGpt12_Mode_timer); / Set the Timer T3 direction / IfxGpt12_T3_setTimerDirection(&MODULE_GPT120, IfxGpt12_TimerDirection_down); / Set timer T3 input prescaler to divide the timer frequency / IfxGpt12_T3_setTimerPrescaler(&MODULE_GPT120, IfxGpt12_TimerInputPrescaler_32);

  1. /* Calculate dutyUpTime and dutyDownTime for reloading timer T3 */
  2. float32 moduleFreq = IfxGpt12_getModuleFrequency(&MODULE_GPT120);
  3. float32 fTimer = (moduleFreq / (GPT1_BLOCK_PRESCALER * TIMER_T3_INPUT_PRESCALER));
  4. uint16 dutyUpTime = (fTimer * (PWM_DUTY_CYCLE / 100.0f)) / PWM_FREQUENCY;
  5. uint16 dutyDownTime = (fTimer * (1 - (PWM_DUTY_CYCLE / 100.0f))) / PWM_FREQUENCY;
  6. /* Set timer T3 value */
  7. IfxGpt12_T3_setTimerValue(&MODULE_GPT120, dutyDownTime);
  8. /* Timer T2: reloads the value dutyDownTime in timer T3 */
  9. /* Set the timer T2 in reload mode */
  10. IfxGpt12_T2_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload);
  11. /* Set the T2 input parameter: Negative transition (falling edge) of T3 toggle latch T3OTL */
  12. IfxGpt12_T2_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_fallingEdgeTxOTL);
  13. /* Set timer T2 value (the value that is reloaded in T3 on negative transition) */
  14. IfxGpt12_T2_setTimerValue(&MODULE_GPT120, dutyDownTime);
  15. /* Timer T4: reloads the value dutyUpTime in timer T3 */
  16. /* Set timer T4 in reload mode */
  17. IfxGpt12_T4_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload);
  18. /* Set the T4 input parameter: Positive transition (rising edge) of T3 toggle latch T3OTL */
  19. IfxGpt12_T4_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_risingEdgeTxOTL);
  20. /* Set timer T4 value (the value that is reloaded in T3 on positive transition) */
  21. IfxGpt12_T4_setTimerValue(&MODULE_GPT120, dutyUpTime);
  22. /* Configure the GPT12 interrupt */
  23. volatile Ifx_SRC_SRCR *src = IfxGpt12_T3_getSrc(&MODULE_GPT120); /* Get interrupt address */
  24. IfxSrc_init(src, ISR_PROVIDER_GPT12_TIMER, ISR_PRIORITY_GPT12_TIMER); /* Initialize the service request */
  25. IfxSrc_enable(src); /* Enable GPT12 interrupt */
  26. /* Initialize the LED */
  27. IfxPort_setPinModeOutput(LED, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);

}

/ Function to start the GPT12 timer / void runGpt12PWM(void) { IfxGpt12_T3_run(&MODULE_GPT120, IfxGpt12_TimerRun_start); / Start the timer T3 / }

```