0

我无法在运行 uC/OS-III 的 NXP LPC1857 上获得 LED 的 PWM 信号平稳运行。只有当我禁用以 1ms 运行的操作系统系统时,经常发生的闪烁才会停止。

我已经用 4 个匹配寄存器设置了我的计时器,一个用于每种颜色(红色、绿色、蓝色),一个用于整个周期。前三个匹配输出正在清除每种颜色的物理输出引脚。最后一个周期匹配产生一个中断来设置下一个周期的所有三种颜色输出。

我试图通过在中断周围添加以下代码来在 timer0 中断期间禁用来自操作系统的中断:

void TIMER0_IRQHandler(void)
{
    CPU_SR_ALLOC();
    OS_CRITICAL_ENTER();
    OSIntEnter();
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_RED))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_RED);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_RED);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_GREEN))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_GREEN);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_GREEN);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_BLUE))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_BLUE);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_BLUE);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_MATCH))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_MATCH);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_RED);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_GREEN);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_BLUE);
    }
    OS_CRITICAL_EXIT();
    OSIntExit();
}

有谁知道为什么 systick 会导致 PWM 信号闪烁?

4

2 回答 2

0

您不应该使用 OS_CRITICAL_ENTER() 和 OS_CRITICAL_EXIT()。相反,您应该使用 CPU_CRITICAL() 和 CPU_CRITICAL_EXIT() 来在临界区禁用中断。

此外,此 ISR 不会发出任何任务信号,因此您不需要调用 OSIntEnter() 和 OSIntExit()。我相信您的代码应该是:

void TIMER0_IRQHandler(void)
{
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_RED))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_RED);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_RED);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_GREEN))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_GREEN);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_GREEN);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_BLUE))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_BLUE);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_BLUE);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_MATCH))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_MATCH);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_RED);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_GREEN);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_BLUE);
    }
}

于 2016-04-29T13:56:04.767 回答
0

终于找到了一个解决方案,虽然我不完全明白为什么:P。

在从我自己的任务中完全剥离操作系统后,除了 PWM 任务,问题仍然存在。所以我又回到了定时器代码。

为了消除闪烁,我唯一需要添加的是在收到周期中断后重置计时器:

老的:

if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_MATCH))
{
    Chip_TIMER_ClearMatch(PWM_TIMER, PWM_MATCH);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_RED);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_GREEN);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_BLUE);
}

新的:

if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_MATCH))
{
    Chip_TIMER_ClearMatch(PWM_TIMER, PWM_MATCH);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_RED);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_GREEN);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_BLUE);
    Chip_TIMER_Reset(PWM_TIMER);
}

有人可以解释为什么这个重置是必要的吗?

我希望以下行会解决这个问题(在我的初始化例程中):

Chip_TIMER_ResetOnMatchEnable(PWM_TIMER, PWM_MATCH);
于 2016-06-18T13:28:42.900 回答