如何在没有任何定时器复位的情况下在 LPC11CXX 系列微控制器上设置 PWM 输出
How to setup PWM output on an LPC11CXX series microcontroller without any timer resets
背景:我有一个正在开发的 LPC11C24 微控制器,它使用一个 32 位定时器读取一个引脚上的 PWM 输入并控制其他 2 个引脚上的 PWM 输出。由于输入和输出在同一个定时器上,我没有对定时器寄存器 (TC) 进行任何复位。特别是对于输出,我正在尝试对其进行设置,以便匹配寄存器将随着信号应为高电平或信号为低电平的时间连续递增。
例子:如果我有一个10000个ticks的周期,我的占空比是50%,每次我得到一个中断,我想给MR0加5000,准备下一次中断。
初始化:
IOCON_R_PIO1_1_bit.FUNC = 0;
IOCON_R_PIO1_1_bit.MODE = 0;
GPIO1DIR_bit.P1_1 = 1;
LPC_TMR32B1->MCR |= (1<<0); /* Interrupt when MR0 matches TC */
LPC_TMR32B1->MR0 = 0; /* zero the match value */
ISR:
/* If interrupt was from MR0 */
if(LPC_TMR32B1->IR & (1<<0))
{
/* Clear the interrrupt */
LPC_TMR32B1->IR = (1<<0);
if(GPIO1DATA_bit.P1_1 == 1)
{
LPC_TMR32B1->MR0 = LPC_TMR32B1->TC;
LPC_TMR32B1->MR0 += OutputChan0MatchPeriodFalling;
GPIO1DATA_bit.P1_1 = 0;
}
else if(GPIO1DATA_bit.P1_1 == 0)
{
LPC_TMR32B1->MR0 = LPC_TMR32B1->TC;
LPC_TMR32B1->MR0 += OutputChan0MatchPeriodRising;
GPIO1DATA_bit.P1_1 = 1;
}
}
当我探测这个引脚时,我没有得到任何输出,所以我不确定我做错了什么。我遇到的另一个问题是,除了当我从一些外部代码(基本上只是设置 MR0 = TC)提供新的占空比时,我没有得到中断。我认为这是因为 TC 领先于 MR0,但我不确定如何防止这种情况发生。太感谢了!如果我可以提供任何其他信息,请告诉我。
我明白了。这里有 2 处错误。
I/O 配置不正确。看了文档,发现GPIO需要设置function为1。 0 为保留函数。
IOCON_R_PIO1_1_bit.FUNC = 1;
第二个错误是我需要暂停计时器来处理 ISR。
/* If interrupt was from MR0 */
if(LPC_TMR32B1->IR & (1<<0))
{
/* Pause timer */
LPC_TMR32B1->TCR = 0;
/* Clear interrupt */
LPC_TMR32B1->IR = (1<<0);
if(GPIO1DATA_bit.P1_1 == 1)
{
LPC_TMR32B1->MR0 = LPC_TMR32B1->TC + OutputChan0MatchPeriodFalling;
GPIO1DATA_bit.P1_1 = 0;
}
else if(GPIO1DATA_bit.P1_1 == 0)
{
LPC_TMR32B1->MR0 = LPC_TMR32B1->TC + OutputChan0MatchPeriodRising;
GPIO1DATA_bit.P1_1 = 1;
}
/* Restart timer */
LPC_TMR32B1->TCR = 1;
}
背景:我有一个正在开发的 LPC11C24 微控制器,它使用一个 32 位定时器读取一个引脚上的 PWM 输入并控制其他 2 个引脚上的 PWM 输出。由于输入和输出在同一个定时器上,我没有对定时器寄存器 (TC) 进行任何复位。特别是对于输出,我正在尝试对其进行设置,以便匹配寄存器将随着信号应为高电平或信号为低电平的时间连续递增。
例子:如果我有一个10000个ticks的周期,我的占空比是50%,每次我得到一个中断,我想给MR0加5000,准备下一次中断。
初始化:
IOCON_R_PIO1_1_bit.FUNC = 0;
IOCON_R_PIO1_1_bit.MODE = 0;
GPIO1DIR_bit.P1_1 = 1;
LPC_TMR32B1->MCR |= (1<<0); /* Interrupt when MR0 matches TC */
LPC_TMR32B1->MR0 = 0; /* zero the match value */
ISR:
/* If interrupt was from MR0 */
if(LPC_TMR32B1->IR & (1<<0))
{
/* Clear the interrrupt */
LPC_TMR32B1->IR = (1<<0);
if(GPIO1DATA_bit.P1_1 == 1)
{
LPC_TMR32B1->MR0 = LPC_TMR32B1->TC;
LPC_TMR32B1->MR0 += OutputChan0MatchPeriodFalling;
GPIO1DATA_bit.P1_1 = 0;
}
else if(GPIO1DATA_bit.P1_1 == 0)
{
LPC_TMR32B1->MR0 = LPC_TMR32B1->TC;
LPC_TMR32B1->MR0 += OutputChan0MatchPeriodRising;
GPIO1DATA_bit.P1_1 = 1;
}
}
当我探测这个引脚时,我没有得到任何输出,所以我不确定我做错了什么。我遇到的另一个问题是,除了当我从一些外部代码(基本上只是设置 MR0 = TC)提供新的占空比时,我没有得到中断。我认为这是因为 TC 领先于 MR0,但我不确定如何防止这种情况发生。太感谢了!如果我可以提供任何其他信息,请告诉我。
我明白了。这里有 2 处错误。
I/O 配置不正确。看了文档,发现GPIO需要设置function为1。 0 为保留函数。
IOCON_R_PIO1_1_bit.FUNC = 1;
第二个错误是我需要暂停计时器来处理 ISR。
/* If interrupt was from MR0 */
if(LPC_TMR32B1->IR & (1<<0))
{
/* Pause timer */
LPC_TMR32B1->TCR = 0;
/* Clear interrupt */
LPC_TMR32B1->IR = (1<<0);
if(GPIO1DATA_bit.P1_1 == 1)
{
LPC_TMR32B1->MR0 = LPC_TMR32B1->TC + OutputChan0MatchPeriodFalling;
GPIO1DATA_bit.P1_1 = 0;
}
else if(GPIO1DATA_bit.P1_1 == 0)
{
LPC_TMR32B1->MR0 = LPC_TMR32B1->TC + OutputChan0MatchPeriodRising;
GPIO1DATA_bit.P1_1 = 1;
}
/* Restart timer */
LPC_TMR32B1->TCR = 1;
}