This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430G2432:更改占空比时出现奇怪的问题

Guru**** 2391045 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/569409/msp430g2432-strange-issue-when-changing-duty-cycle

器件型号:MSP430G2432

大家好、

我有一个应用、其中有两个 PWM 输出相互补充(即当一个输出为25%时、另一个输出为75%)。  我使用计时器 A 来生成两个信号(此芯片上只有一个计时器)。  频率为1kHz。

以下是我的代码的作用:

1) 1) PWM1从低电平开始/ PWM2从高电平开始

2) 2) PWM1每10ms 上升0.1%、而 PWM2下降0.1%、直到分别达到100%和0%。   

3) 3)程序等待5秒。

4) 4) PWM2每10ms 上升0.1%、PWM1下降0.1%、直到分别达到100%和0%。  与#2相反。

5) 5)程序等待五秒。

6) 6)步骤2至5无限期重复。

除了一个奇怪的问题外、它运行良好。  当 PWM1的占空比从~6%变为下一步时、信号在一个周期内保持高电平、然后返回到应该的位置。  下面是我的示波器屏幕截图。  这也会在从~95%到下一步的关断期间发生。  

是否有人对如何解决问题有任何想法?

我尝试的一件事是在更改 TACCR1和 TACCR2中的值之前停止计时器、然后再重新启动计时器。  这没用。

提前感谢、

John

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果有用、这里是我的初始化代码...

    void tmra_init (void)
    {
    TA0CTL = tassel_2 | ID_3 | MC_1;// SMCLK、1MHz、上行模式
    TACCR0 = 1000 - 1;// 1ms 溢出-> 1kHz 频率
    TACCTL0 = CCIE;//启用中断(用于100us 上溢)
    
    // PWM1 Setup
    = TA0L1;//启用中断(用于100us 上溢)//端口2.6 (引脚19)-> PWM 切换/设置模式
    TACCR1 = 0;//从0%占空比
    开始 P2SEL |= BIT6;//端口2.6 (引脚19)-> CCR1输出
    
    // PWM2设置
    TA0CCTL2 = OUTMOD_6;//端口1.4 (引脚6)-> PWM 切换/设置模式
    TAR2 = 0;//从0%占空比
    P1SEL 开始|= BIT4;//端口1.4 (引脚6)-> CCR2输出
    P1SEL2 |= BIT4;
    
    P2DIR |= BIT6;
    P2SEL |= BIT6;
    P2SEL2 &=~BIT6;
    
    //端口2.7设置
    P2SEL &=~
    ~BIT4;P2SEL|= BIT7;P2SEL|= BIT2 |
    
    = BIT2;TAC_TAC3 |= BIT2;// TAC_TAC2 // SMCLK、1MHz、向上计数模式
    } 

    这里是我更改占空比值的地方。

    void set3000KdutyCycle (uint16_t Duty)
    {
    TACCR1 = Duty;
    }
    
    
    
    void set5000KdutyCycle (uint16_t Duty)
    {
    TACCR2 = Duty;
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我的第一个猜测是您缺少比较、即将 CCR 更新为小于当前 TAR 值的值、因此不会发生 OUTMOD 操作。 这是无缓冲的 CCR 带来的风险。 在比较之后立即更新 CCR 有助于。 有时、选择不同的 OUTMOD 可以使该过程更安全。

    这里没有足够的代码来说明"6%"触发器来自何处、但如果(较高优先级) CCR0中断的延迟与之相关、这也不会让我感到意外。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Bruce、

    感谢你的答复。

    我了解由于 CCR 值小于 TAR 值、您错过比较后的思考过程。  我添加了这一行代码、以防止这种情况发生。

    void set3000KdutyCycle (uint16_t Duty)
    {
    if (Duty <= TAR){}
    其他
    {
    TACCR1 =占空比
    ;}
    
    } 

    不幸的是、它没有解决它。  它确实使它在不同的占空比下发生的频率降低。

    我还尝试了切换至所有不同的输出模式、但没有成功。  将其从模式6更改为模式2会使信号在混乱的上升周期期间保持低电平、而不是保持高电平。

    您还有其他想法要尝试吗?

    谢谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    不幸的是,你的 TAR 守卫有一场比赛(如果 TAR 在 IF ()和 CCR 更新之间进行了节拍),你很可能会在你需要的时候输掉比赛。

    我怀疑您正在更新 CCR0中断中的占空比。 您可能需要尝试启用 CCR1/2中断(TIMER0_A1_Vector)并在此处更新相关的 CCR。 通过在 CCR 匹配后立即更新、您将有一个完整周期来获取更新。 这不是一个通用解决方案、但在您的情况下、如果您的增量很小、则应该可以使用。

    我想我看到"6%"来自哪里。 我猜您的 CCR0中断大约需要60微秒才能运行。 对于低于60usec 的脉冲宽度、ISR 始终会丢失、但由于 CCR 在下一次(再次缺失时)匹配、因此会出现问题。 如果脉冲宽度超过60usec、ISR 始终会命中、并且在同一周期中存在 CCR 匹配。 在60秒内、您会得到两个 CCR 匹配(上一轮中的一个"缺失"+刚刚写入的新"命中")、因此它会切换两次。 我希望在 CCR 匹配处更新占空比、而不是在 CCR0处更新占空比将消除这种情况。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果在定时器/CCR0溢出 ISR 中执行此操作、则可以避免非缓冲 CCR 的更新毛刺-尤其是当 MCLK 比定时器时钟快得多时。 确保以16MHz 的频率尽可能快地运行 CPU。 伪代码显示创意:

    void set3000KdutyCycle (uint16_t Duty)

    TEMP_TACCR1 =占空比;


    _interrupt void CCR0_interrupt_ISR (void)

    TACCR1 = temp_TACCR1;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Bruce、

    我想您可以在这里走上正确的轨道。  这很有道理。

    “我怀疑您正在更新 CCR0中断中的占空比。 您可能需要尝试启用 CCR1/2中断(TIMER0_A1_Vector)并在此处更新相关的 CCR。 通过在 CCR 匹配后立即更新、您将有一个完整周期来获取更新。 这不是一个一般的解决方案,但如果您的增量很小,它应该起作用。”

    我实际上不是在 CCrO 中更新占空比。  但是、我的代码在一个定时循环中运行、当 TAR 与 TACCR0匹配时(每1ms)、这个循环启动。  因此、占空比在 CCR0中断后不久会更新。

    我尝试根据您的建议进行更改。  但是、很明显、我设置了一些错误、因为我为每种情况设置了断点、程序仅在 CCR0溢出而不是 CCR1和 CCR2匹配时停止。  您看到此代码有什么问题吗?

    这是我的初始化...

    void tmra_init (void)
    {
    TA0CTL = tassel_2 | ID_3 | MC_1;// SMCLK、1MHz、向上计数模式
    TACCR0 = 1000 - 1; // 1ms 溢出-> 1kHz 频率
    
    // PWM1设置
    TA0CCTL1 = OUTMOD_6; //端口2.6 (引脚19)-> PWM 切换/设置模式
    TACCR1 = 0; //从0%占空比开始
    P2SEL |= BIT6; //端口2.6 (引脚19)-> CCR1输出
    
    // PWM2设置
    TA0CCTL2 = OUTMOD_6; //端口1.4 (引脚6)-> PWM 切换/设置模式
    TACCR2 = 0; //从0%占空比开始
    P1SEL |= BIT4; //端口1.4 (引脚6)-> CCR2输出
    P1SEL2 |= BIT4;
    
    P2DIR |= BIT6;
    P2SEL |= BIT6;
    P2SEL2 &=~BIT6;
    
    //端口2.7设置
    P2SEL &=~BIT7;
    P2SEL2 &=~BIT7;
    
    TA0CTL = tassel_2 + ID_3 + MC_1 + TAIE;// SMCLK、1MHz、向上计数模式、启用 TAIFG 中断
    }
    

    这里是中断矢量...

    #pragma vector=TIMER0_A1_vector
    __interrupt void timer0_A1_interrupt (void)
    {
    开关(TAIV)
    {
    案例 TA0IV_TACCR1:
    if (pred3000KDuty!=荷兰货币 Cycle3000K)
    {
    TACCR1 = DutcurryCycl3000K;
    pred3000KDuty = Dutcurrycle3000K;
    }
    否则{}
    中断;
    案例 TA0IV_TACCR2:
    if (前推5000KDuty!= Dutcurrycle5000K)
    {
    TACCR2 = DutcurryCycl5000K;
    将5000KDutyCycle5000K 推为
    }
    否则{}
    中断;
    案例 TA0IV_TAIFG:
    One_ms_Elapsed = true;
    中断;
    默认值:
    中断;
    }
    
    }
    

    我在中断矢量的第7行、第15行和第23行设置了断点。  它仅在23时停止。

    非常感谢你的帮助。

    John

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在 CCR1匹配 ISR 中更新 CCR1会导致 CCR1值递增时出现问题-在单个计时器周期内、您将获得双 CCR 匹配、这在切换 PWM 模式时很明显会导致毛刺脉冲。  

    最好将 CCR1/CCR2更新置于计时器溢出中断中、而不是"在 TAR 与 TACCR0匹配时启动的定时循环中(每1ms)。"

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、llmars、

    感谢您的回复。  我认为我没有解释我做得好的事情。  当 TAR 与 TACCRO 匹配时、我设置一个标志。  然后、我的主循环仅包含检查和清除标志以及运行例程。

    while (1U)
    {
    if (One_ms_Elapsed)
    {
    One_ms_Elapsed = false;
    
    light_task();
    timer_task ();
    
    CLR_WDT_M ();
    
    }
    否则{}
    
    

    我首先在 TIMER0_A0_Vector 中设置此标志、但根据 Bruce 的建议、我更改为 TIMER0_A1_Vector。   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    不用担心、我知道您在做什么。 重要的是、您的轮询周期方法比我提供的方法占用更多的 CPU 资源。 计时器时钟为1MHz、CPU 最大频率为16MHz、这意味着每个计时器周期只需16个 CPU 周期。 如果希望在较低的 CCR 值下进行无干扰的 CCR 更新、则不应像这样浪费 CPU 时间。 当 CCR1/CCR2等于1且更新后将为2时、即使是 ISR 方法也可能太晚、但我不能告诉您-您应该尝试(很明显、如果您选择)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 John:

    查看您发布的 CCRx 中断不起作用的代码后、我看到您尚未在 TA0CCTLx 寄存器中启用 CCRx 中断。 尝试执行此操作、查看中断是否开始工作。 此外、如果您仍然遇到占空比问题、请告诉我。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Caleb、

    感谢您的回复。  解决了这个问题。  可惜,我在尝试这项建议后,仍然有一个奇怪的占空比问题。  还有其他想法吗?

    谢谢、

    John

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我应该更具体地说明我尝试了什么:)

    Bruce 建议在每次比较发生时更新占空比。  因此、我更改了我的代码、这样、它不会实际更新 TACCRx 寄存器、而是设置占空比的全局变量和在下一次比较中断期间更改的标志。  

    …
    
    currDutyCycl5000K++;
    update5000KPWM = true;
    
    …… 

    #pragma vector=TIMER0_A1_vector
    __interrupt void timer0_A1_interrupt (void)
    {
    开关(TAIV)
    {
    案例 TA0IV_TACCR1:
    if (update5000KPWM)
    {
    TACCR2 = DutcurryCycl5000K;
    update5000KPWM = false;
    }
    否则{}
    中断;
    案例 TA0IV_TACCR2:
    if (update3000KPWM)
    {
    TACCR1 = DutcurryCycl3000K;
    update3000KPWM = false;
    }
    否则{}
    中断;
    案例 TA0IV_TAIFG:
    One_ms_Elapsed = true;
    中断;
    默认值:
    中断;
    }
    
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 John:

    感谢您的澄清。 我认为这种做法有一些缺陷,正如伊尔玛斯指出的那样:

    "更新 CCR1匹配 ISR 中的 CCR1会导致 CCR1值递增时出现问题-在单个计时器周期内、您将获得双 CCR 匹配、这在切换 PWM 模式时很明显会导致毛刺脉冲。  

    最好将 CCR1/CCR2更新置于计时器溢出中断中、而不是"在当 TAR 与 TACCR0匹配时启动的定时循环中(每1ms)"。

    您能否尝试与上述方法类似的方法、但在设置相应的 updatexKPWM 标志后、不更改 CCRx 中断中的 CCRx 值、而是在 CCR0中断中更改它?

    此致、  
    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Caleb、

    我将中断例程更改为这个。

    #pragma vector=TIMER0_A1_vector
    __interrupt void timer0_A1_interrupt (void)
    {
    开关(TAIV)
    {
    案例 TA0IV_TACCR1:
    中断;
    案例 TA0IV_TACCR2:
    中断;
    案例 TA0IV_TAIFG:
    One_ms_Elapsed = true;
    
    if (update5000KPWM)
    {
    TACCR2 = DutcurryCycl5000K;
    update5000KPWM = false;
    }
    否则{}
    
    if (update3000KPWM)
    {
    TACCR1 = DutcurryCycl3000K;
    update3000KPWM = false;
    }
    否则{}
    
    中断;
    默认值:
    中断;
    }
    
    } 

    当我以这种方式运行它时、它确实执行了一些奇怪的操作。  输出将在2.5us 内变为高电平、并返回低电平。  

    然后、我从每个 TA0CCTLx 寄存器中删除 CCIE 使能、以查看它是否起作用、以及它们现在是否无关。

    // PWM1设置
    //TA0CCTL1 = OUTMOD_6 | CCIE;//端口2.6 (引脚19)-> PWM 切换/设置模式
    TA0CCTL1 = OUTMOD_6;
    TACCR1 = 0;//开始占空
    比为0% P2SEL |= BIT6;//端口2.6 (引脚19)-> CCR1 = OUTMOD/
    
    TACCM2输出设置
    //端口1.4 (引脚6)-> PWM 切换/设置模式
    TA0CCTL2 = OUTMOD_6;
    TACCR2 = 0;//从0%占空比
    P1SEL 开始|= BIT4;//端口1.4 (引脚6)-> CCR2输出
    P1SEL2 |= BIT4; 

    之后工作正常、但占空比问题仍在发生。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 John:

    您以多高的频率运行 CPU? 您是否曾尝试增加中断次数、以便更快地执行中断并为您提供更多时间来更改 CCRx 寄存器?

    此外、如果您愿意提供更完整的代码示例、我可以尝试在我的末尾复制此问题。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Caleb、

    我一直以8MHz 的频率运行。 我刚刚将其增加至16MHz。 运气差。 如果您可以对其进行测试、那将非常好。 您希望我如何为您提供代码?

    谢谢、
    John
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 John:

    我刚刚向您发送了一个朋友请求。 接受后、您可以向我发送包含您的代码的个人消息。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我发送了它。 谢谢。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 John:

    我将查看它并尽快返回给您。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 John:

    我已经能够测试您的代码并复制您遇到的问题。 我还尝试了我们在整个主题中建议的所有权变措施、并获得了与您相同的结果。 这里的优点是我们可以复制它、并且我们都位于同一页上。

    遗憾的是、我仍然没有对此问题进行解释。 如您所述、即使停止计时器、然后更新 CCRx 值也无法解决问题。 这让我感到担忧、因为这是在不考虑竞争条件的情况下修改这些值的"正确"方法。

    我需要做更多的测试、我将与我们的质量团队合作、了解这里的实际情况。 我会在整个过程中不断更新您的信息。

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Caleb Overbay"]我已经能够测试您的代码并复制您遇到的问题。

    很好奇-会出现哪些 CCR1/CCR2范围更新毛刺问题? 是低范围<= 2吗?

    如果是这样、那么我将按照以下方式实现 CCR1更新:等待计时器从 CCR1 "安全距离"运行、然后更新它:

    if (TACCR1 < 3)
    __DELAY_CYCLLES (16*50);//假设 timerfreq =1MHz 和 cpufreq =16MHz
    TACCR1 = DutcurryCyclle3000K;
    update3000KPWM = false;
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Caleb Overbay">John、您好、

    我已经能够测试您的代码并复制您遇到的问题。 我还尝试了我们在整个主题中建议的所有权变措施、并获得了与您相同的结果。 这里的优点是我们可以复制它、并且我们都位于同一页上。

    遗憾的是、我仍然没有对此问题进行解释。 如您所述、即使停止计时器、然后更新 CCRx 值也无法解决问题。 这让我感到担忧、因为这是在不考虑竞争条件的情况下修改这些值的"正确"方法。

    我需要做更多的测试、我将与我们的质量团队合作、了解这里的实际情况。 我会在整个过程中不断更新您的信息。

    此致、
    Caleb Overbay

    [/报价]

    您好 Caleb、

    感谢您的更新。  很好、您可以重复该问题。  请告诉我您是否希望我在我的最后尝试任何操作

    谢谢、

    John

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ilmars、  

    查看干扰发生的位置后、我计算出 CCR1从值6转换到值7时、它处于范围内。 CCR0中断应该有足够的时间来更新寄存器。 即使我停止了计时器、然后更新了 CCR1中的值、问题仍然存在。

    我将测试您的上述理论、并告诉您所有的结果。  

    此致、  
    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Caleb Overbay"]查看干扰发生的位置后,我计算出 CCR1从值6转换为值7时,它在范围内的某处。

    CPU @8MHz 只有8个时钟周期在以1MHz 运行的定时器节拍期间执行。 在6个计时器周期内、CPU 甚至可能无法完成对整个 ISR 的处理、并且恰好在 CCR 更新指令时、计时器已达到值6且发生 CCR 匹配、PWM 输出已切换。 然后 CPU 将 CCR 值更改为7、在下一个计时器节拍上出现下一个匹配(在同一 PWM 周期内)时、输出再次切换、您会在示波器上看到毛刺脉冲。 在设置/复位或复位/设置模式下、您不会看到干扰。

    我建议重新考虑 PWM 模式,将其从切换更改为设置/重置和/或重置/设置,并关闭此线程的定时器/CPU 竞争状态捕获:)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Ilmars、

    这也是我所期望的、但更改输出模式没有效果。 我同意切换输出模式不应用于此应用。

    我今天要尝试的一些操作:

    • 将10ms 更新为20ms
    • 延迟一段时间后 CCRx 中断中的更新
    • 使用 TimerA 模块在另一个部件上尝试

    此致、  
    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 John:

    我有一些好消息。 这里似乎有一个非常独特的比赛条件、我仍然没有找到确切的根本原因。 但是、如果 CCR1的值小于7、我可以通过使用 Ilmar 的建议在更新 CCR1之前添加延迟来缓解该问题:

    if (update3000KPWM)
    {
    IF (TACCR1 < 7)
    _DELAY_CYCLES (8*50); //假设 timerfreq = 1MHz 且 cpufreq = 8MHz
    TA0CTL &=~MC_1; //停止计时器
    TACCR1 = DutcurryCycl3000K;
    TA0CTL |= MC_1; //启动计时器
    update3000KPWM = false;
    }
    否则{} 

    通过增加此延迟、我们将确保在将 CCR1更新为7之前 TAR 中的值至少为50。 这可以避免由于从6更新到7而发生的竞争情况。  此外、我强烈建议将 OUTMOD 更改为"复位/设置"。 通过这种方法、我们知道 PWM 下降沿始终在达到 CCRx 时、而上升沿始终在达到 CCR0时。

    我将进一步深入探讨这一点、以找出根本原因、但您能否尝试一下、让我知道您的结果。

    此致、  

    Caleb Overbay

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    很棒!  我将在周一早上进行测试、并告诉您结果。  感谢

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Caleb Overbay"[用户名="Caleb Overbay]")通过添加此延迟、我们将确保在将 CCR1更新为7之前 TAR 中的值至少为50。 这可以避免由于从6更新到7而发生的竞争情况。 [/报价]

    很高兴您取得了进展、努力工作。 IMHO 计时器重新启动是超快速的、它也无助于 PWM 频率保持恒定。 BTW 的最佳做法是使用调试引脚-在 CCR 更新前设置它、在 CCR 更新后重置-以查看何时将 CCR 分别更新为 PWM 周期状态。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好  和

    这解决了 Caleb 的代码问题。  遗憾的是、当我将修复重新放入生产代码时、TACCR1线路上的最后一个周期保持高电平(当 TACCR2线路关闭时)。  

    Caleb、

    我将在 PM 中向您发送我的代码。

    谢谢、

    John

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [报价用户="John Death"]我将在 PM 中向您发送我的代码。

    您是否尝试了解这种情况的发生原因? 或者"我将向您发送我的代码、进行修复"。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有什么让您感觉我不想理解这个问题?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我对这里的重量级人物犹豫不决、但我仍然推荐我的原始解决方案。 对于此应用、每次更改都是8个 CPU 时钟的固定增量、您将始终赢得比赛、因为您无法在8个 CPU 时钟内完成 ISR。 (可能也不在16、24或32个时钟中。)

    原始症状的原因并不神秘(我想我在上面解释过)、它是基于 CCR0执行 CCR 更新的结果;由于软件无法在零时间内更新 CCR、因此始终会存在具有较小 CCRn 值的竞争。 (相比之下、TimerB 中的缓冲 CMR 会在零时间内更新、因为有硬件可执行此操作。) 通过在比较匹配处进行更新、您可以将允许的延迟扩展到整个周期(减一点)。

    我建议您使用原始 A1 ISR、但(1)您忘记了 CCIE 设置、(2)您正在向后执行 CCR 更新(TAIV_CCR2应更新 TA0CCR2)。

    正如我说过的、这不是一个通用的解决方案、但它应该完成您正在尝试的操作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="John Deaton)] TACCR1线路上的最后一个周期保持高电平(当 TACCR2线路关闭时)。  [/报价]

    1)不是尝试在正确的时间停止计时器并且不产生干扰、只需关闭 PWM 输出、然后禁用计时器:1)为 PxOUT 中的 PWM 输出引脚设置所需的值2)将 PW 输出引脚功能更改为 GPIO 输出3)禁用计时器。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好

    我认为它现在可以工作了!  我回到 Bruce 的建议、将更新放在 A1矢量中。  这导致了一个问题... 一旦我将占空比设置为零或满、 TA0IV_TACCRx 中断将不再被调用。  为了解决这一问题、我继续使用之前的占空比、如果 TA0IV_TAIFG 中断从0或1000开始、则重新设置它的占空比。  这是我的中断例程、它似乎目前正在工作。

    #pragma vector=TIMER0_A1_vector
    __interrupt void timer0_A1_interrupt (void)
    {
    switch (TAIV)
    {
    case TA0IV_TAIFG:
    One_ms_Elapsed = true;
    
    if (前推 DutyCycle3000K = 0 &&当前 DutyCycle3000K!= 0)
    {
    TACCR1 = DutcurryCycl3000K;
    预防性 DutyCycle3000K =当前预防性 Cycle3000K;
    }
    否则{}
    if (前推 DutyCycle5000K = 0 &&当前 DutyCycle5000K!= 0)
    {
    TACCR2 = DutcurryCycl5000K;
    预防性 DutyCycle5000K =预防性 DutyCycle5000K;
    }
    否则{}
    
    if (前推 DutyCycle3000K =1000 &&当前 DutyCycle3000K !=1000)
    {
    TACCR1 = DutcurryCycl3000K;
    预防性 DutyCycle3000K =当前预防性 Cycle3000K;
    }
    否则{}
    if (前推 DutyCycle5000K =1000 &&当前 DutyCycle5000K !=1000)
    {
    TACCR2 = DutcurryCycl5000K;
    预防性 DutyCycle5000K =预防性 DutyCycle5000K;
    }
    否则{}
    
    中断;
    案例 TA0IV_TACCR1:
    if (update3KDuty)
    {
    update3KDuty = false;
    TACCR1 = DutcurryCycl3000K;
    预防性 DutyCycle3000K =当前预防性 Cycle3000K;
    }
    中断;
    案例 TA0IV_TACCR2:
    if (update5KDuty)
    {
    update5KDuty = false;
    TACCR2 = DutcurryCycl5000K;
    预防性 DutyCycle5000K =预防性 DutyCycle5000K;
    }
    中断;
    默认:
    中断;
    }
    
    

    如果我看到另一个干扰、我会告诉大家。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我还以1%(10个计数)开始占空比、以解决另一个问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 John:

    很高兴听到您取得了进展。 您的应用是 TimerA 的一种常见用法、因此可以预期出现类似的断续情况。 我认为您上面概述的解决方案可能是 TimerA 限制条件下的最佳解决方案。 这是否适合您、或者您有其他问题吗?

    此致、
    Caleb Overbay
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Caleb、

    感谢您的登记。  是的、它似乎在工作。  您的意思是、对于这个应用、我应该已经选择了一个具有计时器 B 的 MCU?  不幸的是,我不得不选择最便宜的选项,这样会经常工作:)。  

    此致、

    John