今天和大家分享极海半导体定时器的另外一个功能PWM输出功能。一:PWM知识的分享
PWM(Pulse Width Modulation 脉宽调制)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。它是一种对模拟信号电平进行数字编码的方法。是指在一定时间内波形的高电平(即 1 状态)所占用的时间比例。通过高分辨率计数器的使用,方波占空比被调制用来对一个模拟信号的电平进行编码。PWM 信号任然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有,要么完全无。比如我们的电压输出是 5V的,那么经过改变 PWM 的占空比,可以达到在一定时间内输出 3.3V 或者 1.3V 的效果。
PWM是脉冲宽度调制,具有两个非常重要的参数:频率和占空比。
频率:PWM的频率是整个周期的倒数。
占空比:占空比是指一个周期内高电平所占的比例。
这里我们查看一下极海半导体官方的手册得知:极海G32A1465开发板有以下几种PWM输出模式;
EPWM(边沿对齐 PWM 模式)
以下任一情况将选择边沿对齐 PWM 模式:
QDMEN=0
DECMENx=0MCMx=0CHCMx=0CMSEL=0
CHMSEL3=1
(MOD-INITV+ 0x0001)确定边沿对齐 PWM 的周期,(CHV-INITV)确定脉冲宽度(占空比)。
若在通道(n)匹配且 CFGTMR 计数器等于 CHV时,也就是在脉冲宽度结束时,CHIEN 被设置为 1,则会触发通道(n)中断,同时置位CHEV**。
因为所有 PWM 信号的前沿都与周期的开始对齐,这对于所有通道都是相同的,,因此该类型的 PWM 信号被称为边沿对齐。
下图为在边沿对齐 PWM 模式下,当 CHMSEL1=1和 CHMSELO=0 时的周期和脉冲宽度。
CPWM(中心对齐 PWM 模式)
以下任一情况将选择中心对齐 PWM 模式:
QDMEN=0
DECMENx=0
MCMx=0
CHCMx=0
CMSEL=1
2*(CHV - INITV)确定中心对齐 PWM 脉冲宽度(占空比),2*(MOD-INITV)确定中心对齐 PWM 周期。为了不产生不明确的结果,必须将 MOD 的范围保持在0x0001~0x7FFF之间。
在中心对齐 PWM 模式中,CFGTMR 计数器向上计数直到达到 MOD,然后CFGTMR 计数器向下计数直到达到 INITV。当 CFGTMR 计数器开始向上计数,即脉冲宽度结束时和当 CFGTMR 计数器开始向下计数,即脉冲宽度开始时,如果设置 CHEV** 位且 CHIEN 被设置为 1,则在 CFGTMR 计数器等于 CHV 时会触发通道(n)中断。
因为所有通道的脉冲宽度中心都与 INITV 的值对齐,因此该类型的PWM 信号被称为中心对齐。
当使用中心对齐计数模式时,CFGTMR的其他通道模式将无法使用。因此当CMSEL=1 时,必须使用中心对齐 PWM 模式来配置和控制 CFGTMR 通道。
下图为在中心对齐 PWM 模式下,当 CHMSELO=0 和 CHMSEL1=1 时的周期和脉冲宽度。
三:极海半导体PWM输出学习调试
基本的软件编写流程如下:
3.1:使能定时器和相关IO口时钟。2:初始IO口为复用功能输出。3:初始化定时器:4:Prescaler,Period等:5:使能定时器,设置PWM开始输出功能
/* Initialize CFGTMR */
CFGTMR_Init(CFGTMR0_INSTANCE, &g_cfgtmr0InitConfig, &cfgtmr0State);
/* Initialize CFGTMR PWM */
CFGTMR_InitPWM(CFGTMR0_INSTANCE, &g_cfgtmr0PWMInitConfig);
3.2:按键控制 PWM输出的参数,修改频率
if (BTN_GetState(BUTTON_KEY1) == 0U)
{
frequencyHZ += 10000U;
if (frequencyHZ > 100000)
{
frequencyHZ = 10000U;
}
CFGTMR_UpdatePwmPeriod(CFGTMR0_INSTANCE, CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE, frequencyHZ, true);
CFGTMR_UpdatePwmChannel(
CFGTMR0_INSTANCE,
g_cfgtmr0PWMIndependentChannelsConfig[0].hwChannelId,
CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
dutyCycle,
0U,
true);
printf("CFGTMR PWM output frequency %dKHz.\r\n", frequencyHZ / 1000);
while (BTN_GetState(BUTTON_KEY1) == 0U);
}
3.3:按键控制 PWM输出的参数,修改占空比
if (BTN_GetState(BUTTON_KEY2) == 0U)
{
dutyCycle += 0x1000U;
if (dutyCycle > CFGTMR_MAX_DUTY_CYCLE)
{
dutyCycle = 0x2000U;
}
CFGTMR_UpdatePwmChannel(
CFGTMR0_INSTANCE,
g_cfgtmr0PWMIndependentChannelsConfig[0].hwChannelId,
CFGTMR_PWM_UPDATE_IN_DUTY_CYCLE,
dutyCycle,
0U,
true);
printf("CFGTMR PWM output duty cycle %0.2f%%.\r\n", ((float)dutyCycle / CFGTMR_MAX_DUTY_CYCLE) * 100);
while (BTN_GetState(BUTTON_KEY2) == 0U);
}
试验效果如下图:
|