一、概述
前面两篇博文已经讲述了 Ctimer 的 Match & Capture 用例,这里当然少不了作为 PWM 用例的介绍,所以也对应了该系列博文的详解二字,一定详细介绍,一般人我轻易不告诉他的。
在 PWM 模式下,三个匹配寄存器可以用来提供单侧控制 PWM 输出匹配输出引脚。
说到这里可能有人要抬杠,前面博文不是说有四个匹配寄存器吗,怎么这里就用三个匹配寄存器匹配三个引脚输出 PWM ?
别急,老是毛毛躁躁、挠头抓腮的,容易秃顶(哈哈哈),阅读到下面会详细介绍的。
图 1 :32 位计数器 /定时器框图
二、 Ctimer PWM 功能的配置和使用
- 基础配置
① 打开时钟和配置外围设备的基本操作
配置 Ctimer 的时钟,如图 2 ,3 所示 Ctimer 的时钟源选择,来到 Ctimer第三篇博文,这里已经是老生常谈了,不过这个图还是要给的,方便用户参考吧。
图 2 :Ctimer 的时钟源选择
图 3 :Ctimer 的时钟源配置
② 初始化 Ctimer 基础控制寄存器
数控寄存器(Count Control Register)选择 Ctimer 的模式,定时器或者计数器模式,然后进行预分频寄存器(Prescale Register)配置,
这个寄存器配置的是在时钟源的时钟周期内,预分频计时器 PC(Prescale Counter)要走 PR + 1个周期才给 Ctimer 的计数器(Timer Counter)进行累加操作,
同时 PC 清零 。这些寄存器的介绍如图 4 所示。
这里使用 SDK 例程获取默认配置一般使用 Ctimer 模式,也就是 TC 在每个 APB bus Clock 上升沿增加 1,
使用计数模式一般用于计算外部输入频率或者输入次数(可以在上下边沿或者上下边沿同时计数),这里不做多介绍,有兴趣的用户可以自己去拓展。
图 4 :Ctimer 基础控制寄存器介绍
- Ctimer PWM 功能的配置
① PWM功能的使用连接到外部引脚
使用引脚配置工具,如图 5 所示,配置 PWM 外部引脚输出。
之前说只能配置三个匹配寄存器到外部引脚,这里对该配置作一个描述介绍,每一个 Ctimer 的定时器有四个匹配寄存器,当使用 PWM 功能模式时,
需要一个匹配寄存器来配置作为 PWM 方波的周期,所以 NXP SDK 包例子默认第四个匹配寄存器配置 PWM 的周期,
所以用户只能使用三个匹配寄存器去配置 PWM 的外部引脚输出。
注意:如果需要使用第四个匹配寄存器所连接的外部引脚配置 PWM 输出,可以更改 Fsl_ctimer.c 的 PWM 配置 API 函数,但是不建议这样子做,除非必须。
图 5 :Ctimer PWM 功能外部引脚配置
② Ctimer PWM 功能的寄存器配置,如图 6 所示,PWM 用到的寄存器
IR 中断寄存器 : 主要是判断哪一个中断产生,有八个中断标志位
MCR 匹配控制寄存器 : 清除使用 PWM 通道的匹配寄存器 stop & reset 位至于 interrupt 位看用户需要设定,
设置 PWM 周期使用的匹配通道寄存器 reset 位。
MR 匹配值 : 用户自己设定,有 32 bit。这里需要设置两个,第一个是 PWM 通道的匹配寄存器值,作为占空比输出,
第二个是 PWM 周期的匹配寄存器值,作为 PWM 周期。
注意:PWM 达到通道的匹配值后,PWM 通道引脚输出为高电平,
若 PWM 通道匹配值大于 PWM 的周期匹配值,PWM 通道将保持输出低电平,也无法达到中断的条件,
如果此之前,PWM 通道已经输出为高电平了,那么在下一个周期将输出低电平。
若 PWM 通道匹配值等于 PWM 的周期匹配值,在定时器达到匹配值 PWM 输出通道输出低。
图 6 :Ctimer PWM 功能常用寄存器
- Ctimer PWM 功能完整配置例子
① 这里默认外部引脚配置完成,可以参照以上说明,使用中断,配置呼吸灯
② 这里示例 Ctimer 第二个定时计数器通道 1的配置
注意:这里调用改变占空比的 API 函数是 :CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent)
当参数 dutyCyclePercent 设置为 0 时,内部更改 PWM 通道匹配值大于周期匹配值,导致 PWM 信号被清除。
int main(void)
{
ctimer_config_t config;
uint32_t srcClock_Hz;
uint32_t timerClock;
/* Use 12 MHz clock for some of the Ctimers */
CLOCK_AttachClk(kFRO_HF_to_CTIMER2);
BOARD_InitPins();
BOARD_BootClockPLL100M();
/* Get the CTIMER2 clock */
srcClock_Hz = CLOCK_GetCTimerClkFreq(2U);
CTIMER_GetDefaultConfig(&config);
timerClock = srcClock_Hz / (config.prescale + 1);
CTIMER_Init(CTIMER, &config);
CTIMER_RegisterCallBack(CTIMER, &ctimer_callback[0], kCTIMER_SingleCallback);
/* config the PWM period match value and pulse width match value of 2Khz PWM signal */
g_pwmPeriod = (timerClock / 2000) - 1;
/* The dutyCycle ranges from 0 to 100 */
g_pulsePeriod = (g_pwmPeriod * (100 - dutyCycle)) / 100;
CTIMER_SetupPwmPeriod(CTIMER, CTIMER_MAT_OUT, g_pwmPeriod, g_pulsePeriod, true);
CTIMER_StartTimer(CTIMER);
while (1)
{
}
}
③ 中断服务函数的配置
void pwm_match_callback(uint32_t flags)
{
static uint32_t count = 0;
if ((flags & (1 << CTIMER_MAT_OUT)) && (++count > 50))
{
CTIMER_UpdatePwmDutycycle(CTIMER, CTIMER_MAT_OUT, dutyCycle);
if(decrement == 0)
{
dutyCycle ++;
if(dutyCycle == 101)
{
decrement = 1;
}
}
if(decrement == 1)
{
dutyCycle --;
if(dutyCycle == 1)
{
decrement = 0;
}
}
}
}
- 编译下载烧录
这里的现象就是 RGB 灯逐渐亮灭循环,这里给出一个波形图,如图 7 所示。
图 7 :Ctimer PWM 输出外部引脚波形
三、参考
- 提供修改后的 Ctimer_PWM.c 的参考代码
- 后续会慢慢深入介绍其他的外设,敬请期待
【LPC55 系列】LPC55S69 开发之 ADC 详解
【LPC55 系列】LPC55S69 开发之 Flash 详解
……
END 谢谢!!!
评论