产生PWM的方式有很多,这里尝试使用TC275的GPT12模块,来产生具有固定频率和可变占空比的PWM信号。
GPT12就是General Purpose Timer Unit通用定时器模块,它包含5个16位定时器,被分给GPT1和GPT2。
这里使用GPT1(T2、T3、T4),有四种模式:定时器模式、计数器模式、门控制定时器模式、增量接口模式。
每个定时器都是由一个单独的控制寄存器TxCON控制。
GPT12模块的配置过程
- 使能GPT12模块
- 通过预分频器BPS1的值配置GPT1模块的频率
- 通过预分频器T3I的值配置T3的频率
- 配置定时器T3的模式、方向和启动值
- 配置两个辅助定时器(定时器模式、重载输入模式、重载值)
GPT12模块配置的相关函数
代码如下:
/* 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);
重新加载值的计算:
根据给定的频率和占空比,计算重载值。(同样在initGpt12PWM()中完成这个任务)
首先,通过IfxGpt12_getModuleFrequency() 获得GPT12的基础频率:
float32 moduleFreq = IfxGpt12_getModuleFrequency(&MODULE_GPT120);
然后,计算定时器的基础频率:
float32 fTimer = (moduleFreq / (GPT1_BLOCK_PRESCALER * TIMER_T3_INPUT_PRESCALER));
#define GPT1_BLOCK_PRESCALER 32 /* GPT1 block prescaler value */
#define TIMER_T3_INPUT_PRESCALER 32 /* Timer input prescaler value */
然后,计算dutyUpTime和dutyDownTime时间:
代码如下:
/* Calculate dutyUpTime and dutyDownTime for reloading timer T3 */
float32 moduleFreq = IfxGpt12_getModuleFrequency(&MODULE_GPT120);
float32 fTimer = (moduleFreq / (GPT1_BLOCK_PRESCALER * TIMER_T3_INPUT_PRESCALER));
uint16 dutyUpTime = (fTimer * (PWM_DUTY_CYCLE / 100.0f)) / PWM_FREQUENCY;
uint16 dutyDownTime = (fTimer * (1 - (PWM_DUTY_CYCLE / 100.0f))) / PWM_FREQUENCY;
/* Set timer T3 value */
IfxGpt12_T3_setTimerValue(&MODULE_GPT120, dutyDownTime);
配置定时器T2和T4,使能定时器T3的重载值:
代码如下:
/* Timer T2: reloads the value dutyDownTime in timer T3 */
/* Set the timer T2 in reload mode */
IfxGpt12_T2_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload);
/* Set the T2 input parameter: Negative transition (falling edge) of T3 toggle latch T3OTL */
IfxGpt12_T2_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_fallingEdgeTxOTL);
/* Set timer T2 value (the value that is reloaded in T3 on negative transition) */
IfxGpt12_T2_setTimerValue(&MODULE_GPT120, dutyDownTime);
/* Timer T4: reloads the value dutyUpTime in timer T3 */
/* Set timer T4 in reload mode */
IfxGpt12_T4_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload);
/* Set the T4 input parameter: Positive transition (rising edge) of T3 toggle latch T3OTL */
IfxGpt12_T4_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_risingEdgeTxOTL);
/* Set timer T4 value (the value that is reloaded in T3 on positive transition) */
IfxGpt12_T4_setTimerValue(&MODULE_GPT120, dutyUpTime);
GPT12中断配置
指针参数:使用一个定时器T3服务请求的地址、中断提供者、中断优先级。
/* Configure the GPT12 interrupt */
volatile Ifx_SRC_SRCR *src = IfxGpt12_T3_getSrc(&MODULE_GPT120); /* Get interrupt address */
IfxSrc_init(src, ISR_PROVIDER_GPT12_TIMER, ISR_PRIORITY_GPT12_TIMER); /* Initialize the service request */
IfxSrc_enable(src);
启动定时器T3
IfxGpt12_T3_run(&MODULE_GPT120, IfxGpt12_TimerRun_start); /* Start the timer T3 */
完整代码
/*********************************************************************************************************************/
/*-----------------------------------------------------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);
/* Calculate dutyUpTime and dutyDownTime for reloading timer T3 */
float32 moduleFreq = IfxGpt12_getModuleFrequency(&MODULE_GPT120);
float32 fTimer = (moduleFreq / (GPT1_BLOCK_PRESCALER * TIMER_T3_INPUT_PRESCALER));
uint16 dutyUpTime = (fTimer * (PWM_DUTY_CYCLE / 100.0f)) / PWM_FREQUENCY;
uint16 dutyDownTime = (fTimer * (1 - (PWM_DUTY_CYCLE / 100.0f))) / PWM_FREQUENCY;
/* Set timer T3 value */
IfxGpt12_T3_setTimerValue(&MODULE_GPT120, dutyDownTime);
/* Timer T2: reloads the value dutyDownTime in timer T3 */
/* Set the timer T2 in reload mode */
IfxGpt12_T2_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload);
/* Set the T2 input parameter: Negative transition (falling edge) of T3 toggle latch T3OTL */
IfxGpt12_T2_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_fallingEdgeTxOTL);
/* Set timer T2 value (the value that is reloaded in T3 on negative transition) */
IfxGpt12_T2_setTimerValue(&MODULE_GPT120, dutyDownTime);
/* Timer T4: reloads the value dutyUpTime in timer T3 */
/* Set timer T4 in reload mode */
IfxGpt12_T4_setMode(&MODULE_GPT120, IfxGpt12_Mode_reload);
/* Set the T4 input parameter: Positive transition (rising edge) of T3 toggle latch T3OTL */
IfxGpt12_T4_setReloadInputMode(&MODULE_GPT120, IfxGpt12_ReloadInputMode_risingEdgeTxOTL);
/* Set timer T4 value (the value that is reloaded in T3 on positive transition) */
IfxGpt12_T4_setTimerValue(&MODULE_GPT120, dutyUpTime);
/* Configure the GPT12 interrupt */
volatile Ifx_SRC_SRCR *src = IfxGpt12_T3_getSrc(&MODULE_GPT120); /* Get interrupt address */
IfxSrc_init(src, ISR_PROVIDER_GPT12_TIMER, ISR_PRIORITY_GPT12_TIMER); /* Initialize the service request */
IfxSrc_enable(src); /* Enable GPT12 interrupt */
/* Initialize the LED */
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 */
}