首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于脉宽调制干扰的uC/OS-III系统及外围timer0

用于脉宽调制干扰的uC/OS-III系统及外围timer0
EN

Stack Overflow用户
提问于 2016-04-23 21:16:01
回答 2查看 283关注 0票数 0

在运行uC/OS-III的NXP LPC1857上,我很难获得LED的脉宽调制信号。只有当我禁用运行在1ms的OS系统时,规则发生的闪烁才停止。

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

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

代码语言:javascript
复制
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();
}

有人知道为什么注射器会引起PWM信号的闪烁吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-18 13:28:42

最后找到了一个解决方案,虽然我不完全理解为什么:P。

在将操作系统从我自己的任务中完全剥离出来之后,除了PWM任务之外,问题仍然存在。所以我回过头来看计时码。

为了摆脱闪烁,我必须添加的唯一一件事是在收到句点中断后重新设置计时器:

旧:

代码语言:javascript
复制
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);
}

新的:

代码语言:javascript
复制
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);
}

有人能解释一下为什么这种重置是必要的吗?

我期望下面的行会处理这个问题(在我的初始化例程中):

代码语言:javascript
复制
Chip_TIMER_ResetOnMatchEnable(PWM_TIMER, PWM_MATCH);
票数 0
EN

Stack Overflow用户

发布于 2016-04-29 13:56:04

您不应该使用OS_CRITICAL_ENTER()和OS_CRITICAL_EXIT()。相反,您应该使用CPU_CRITICAL()和CPU_CRITICAL_EXIT(),以便在关键部分禁用中断。

而且,这个ISR不显示任何任务,因此不需要调用OSIntEnter()和OSIntExit()。我认为您的代码应该是:

代码语言:javascript
复制
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);
    }
}

吉恩

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36816519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档