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.

[参考译文] Msp430l092:多中断问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/587862/msp430l092-multiple-interrupt-problem

器件型号:MSP430L092
主题中讨论的其他器件: MSP430WARE

我将处理 msp430l092芯片。 我可以通过 IAR 嵌入式软件对其进行编程。 我有 ADC 中断和计时器中断的示例代码。 它们各自工作良好。 当我将 ADC 中断添加到计时器中断时、它不起作用。 我是说 ADC 中断第一次工作、我的代码卡在计时器中断内部。 我想准备我的代码以读取 ADC 值并处理时间间隔。 可以给我一个建议吗? 提前感谢

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

    您好!

    请发布您的代码吗? 我想看一下。

    谢谢你

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

    我添加了两个不同的中断、我需要处理计时器和模拟值、但它并不能完全正常工作。 不会发生任何情况。

    /*-版权所有-、BSD_EX

     *版权所有(c) 2012、德州仪器(TI)公司

     *保留所有权利。

     *

     *以源代码和二进制形式重新分发和使用、有无

     *如果满足以下条件、则允许进行修改

     符合*:

     *

     ** 源代码的重新分发必须保留上述版权

     *   注意、此条件列表和以下免责声明。

     *

     * *二进制形式的再发行必须复制上述版权

     *   请注意、中的此条件列表和以下免责声明

     *   随分发提供的文档和/或其他材料。

     *

     * *德州仪器公司的名称和名称均不相同

     *   其贡献者可用于认可或推广衍生产品

     *   未经特定的事先书面许可。

     *

     *本软件由版权所有者和贡献者"按原样"提供

     *以及任何明示或暗示的保证、包括但不限于:

     *特定适销性和适用性的隐含保证

     *不承认目的。 在任何情况下、版权所有者不得或

     *派遣国应对任何直接、间接、偶然、特殊、

     *典型或必然的损害(包括但不限于

     *采购替代货物或服务;丧失使用、数据或利润;

     *或业务中断)、无论原因是什么以及任何责任理论、

     *无论是合同、严格责任还是侵权行为(包括疏忽或)

     *否则)因使用本软件而以任何方式产生、

     *即使被告知可能会发生此类损坏。

     *

     秘书长的报告

     *

     *                      MSP430代码示例免责声明

     *

     * MSP430代码示例是通常包含的低级程序

     *高度演示单个外设功能或器件功能

     *简明扼要。 为此、代码可能依赖于器件的加电默认值

     *寄存器值和设置、如时钟配置和注意

     *在组合多个示例中的代码时应采取这种方法、以避免潜在的问题

     *效果。 有关 GUI、另请参阅 www.ti.com/grace 和 www.ti.com/msp430ware

     *用于外设配置的 API 函数库方法。

     *

     *--/版权--*/

    /*  说明:多个 ADC 通道*/

    /********* A_POOL ADC 转换********* /

    /*                                                                              *//

    /*                                                                              *//

    /*                         +--L092--+                                       */

    /*                         |*1     14 |                                       */

    /*                         | 2     13 |                                       */

    /*                         | 3     12 |<-通道 A0 (0-256mV)                 */

    /*                         | 4     11 |                                       */

    /*                         | 5     10 |                                       */

    /*通道 A2 (0-1000mV)->|  6      9 |                                       */

    /*通道 A1 (0-256mV)->|  7      8 |                                       */

    /*                         +--- +                                       */

    /*                                                                              *//

    /* D.Dang/D.Archbold/D.Szmulewicz                                            *

    /* 德州仪器(TI)公司                                                       *

    /* 使用 IAR 版本5.10.4构建                                               */

    / /

     

    #include

     

    int ChannelA0、ChannelA1、ChannelA2;

     

    int main (空)

      

      WDTCTL = WDTPW + WDTHOLD;                             //停止 WDT

      

      P1DIR |=(BIT1+BIT4+BIT5);                           

      

     // CHANNEL2的模拟输入1000mV

       APVDIV=A2DIV_1;

       

     //开始配置 A-POOL 寄存器  

       APCTL = 0;                                           //清除 APCTL 寄存器

       APCNF = CMPON+DBON+CONVON+EOCBU+APREFON+CLKSEL_MCLK; //配置 A-POOL 元素,选择 MCLK 作为 A-POOL 时钟源

       APINT = 0x00;                                        //清除 ADC-DAC-REG

    /********* /

    /*设置端口          */

    /********* /

     

           

                 P1SEL0 |= BIT5;                

                 P1SEL1 |= BIT5;    

       

    /******** /

    /*设置 CCS           */

    /* SMCLK = LFCLK       */

    /******** /

                 CCSCTL0 = CCSKEY;                      //解锁 CCS

                 CCSCTL5 = 0;                           //将 SMCLK 的分频器设置为1

                 CCSCTL4 |= SELM_1 + SELESS_1 + SELA_1;   //选择 LFCLK/VLO 作为 ACLK、MCLK 和 SMCLK 的源   

                 CCSCTL0_H |= 0xFF;                     //锁定 CCS

    /*通过写入高字节锁定*/

       

       while (1)

       {

         

       

     

       APIE = EOCIE;                                       //为转换结束启用中断

       APINT = 0x00;                                        //清除 ADC-DAC-REG

       APCTL = OSEL+CBSTP+RUNSTOP+APNSEL_2+APPSEL_5;        //设置通道并开始转换

       _bis_SR_register (LPM0_bits + GIE);                  //启用中断后进入 LPM0

       ChannelA2 = APINT;                                   //获取 A2的结果    

       

      

        if (ChannelA2>20){

         

            P1OUT |= BIT4;

       

         

       }

       

        否则{

            P1OUT &=~BIT4;

        }

      TA0CCTL0 = CCIE;                       // TA0CCR0中断被启用

                 TA0CCR0 = 10;                                                  //设置 TA0CCR0的值

                  TA0CTL = tassel_2 + MC_1 + TACLR;      // SMCLK、续 模式

     

     _bis_SR_register (LPM0_bits + GIE);        //输入 LPM0 w 中断:CPU、MCLK 被禁用

                                                 // ACLK 激活,SMCLK 激活,HFOSC 打开

      

     __no_operation();                                    //在此处放置断点

       }

     

     

    //a_pool 中断服务例程

    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)

    #pragma vector=APOOL_vector

    _interrupt void a_pool (void)

    #Elif defined (_GNU_)

    void __attribute__((interrupt (APOL_vector)) a_pool (void)

    其他

    错误编译器不受支持!

    #endif

     

     

      

      

     

       APIFG = 0;                                       //清除中断标志      

    _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);                //退出活动状态以对下一个通道进行采样

     

    //计时器 A0中断服务例程

    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)

    #pragma vector=TIMER0_A0_VECTOR

    _interrupt void Timer_A0 (void)

    #Elif defined (_GNU_)

    void __attribute__((中断(TIMER0_A0_Vector)) Timer_A0 (void)

    其他

    错误编译器不受支持!

    #endif

     

          

           

           count = count + 1;

           

           if (count == 1000){

           // P1OUT ^= BIT1;

             计数= 0;

           }

           

           

           

      _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);

     

     

     

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

    您好!

    我尝试构建您的代码、变量计数未定义、因此构建失败。 我创建了一个全局变量计数。

    下面是我在代码中看到的问题:

    您的计时器中断被设置为使器件脱离低功耗模式并重新打开 CPU。 计时器永远不会被禁用、这意味着在您第一次设置计时器后、计时器将继续运行、并且在经过时间间隔时、它会尝试使器件退出 LPM。

    因此、当您第一次进入 while (1)循环时、代码将启用 ADC 并开始转换、进入低功耗模式、并等待 ADC 中断使其退出低功耗模式。 CPU 被打开并且代码继续在 main()中执行。 读取 ADC 值、GPIO 被置位或清零。 然后启用计时器。 它处于连续模式。 这意味着计时器在超时后会继续运行并定期超时。 器件进入 LPM 模式并等待计时器中断。 在第一个超时后,我们退出 LPM 并继续执行 main()中的代码。 我们返回到 while 环路的顶部。 ADC 已配置并启动、但请记住、这次当我们进入低功耗模式时、计时器仍在运行。 因此、这是计时器中断和 ADC 中断之间的争用、以使我们脱离 LPM。 这会导致您的问题。 它不允许 ADC 完成。

    要解决此问题,请在计时器退出 LPM 模式后,即在__no_operation()之前禁用计时器。

    如果您的原始问题得到了解答、请单击"验证答案"。 我们可以继续讨论您面临的更多问题。

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

    感谢您的关注。

    我可以通过更改计时器模式而不是禁用计时器来停止计时器。

    在 while 循环中、我累加  TA0CTL = tassel_2 + MC_0 + TACLR; 在进入 LPM 后的此行以停止计时器

      

     _bis_SR_register (LPM0_bits + GIE);        //输入 LPM0 w 中断:CPU、MCLK 被禁用

      TA0CTL = tassel_2 + MC_0 + TACLR;             

     __no_operation();                                    //在此处放置断点

       }

    我的方法是否正确?

    谢谢  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当然、您有很多权变措施、您的方法肯定会停止计时器。

    您能否单击帖子中最有用的"验证答案"按钮?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    它现在运行得很好。 你是对的。 我需要禁用计时器中断、以便为计时器添加停止模式代码(TA0CTL = tassel_2 + MC_0 + TACLR;)两个不同的位置。 第一个是定时器中断的结束、最后一个是在_NO_OPERATION ()之前;我的计数器通常每秒闪烁一次。 启用光电二极管后、我的计数器具有200~250 ms 的延迟。 我是说它每1250ms 闪烁一次。 您能不能建议我避免这种延迟?

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

    这是因为 P1.4具有1s 延迟+ ADC 采样和转换所需的时间。 在您的案例中、它看起来像是在200-250ms 之间的采样和转换。 这意味着、如果您希望每1秒设置/清除一次 P1.4、则必须重新排列代码。

    您可以这么做、

    1.启动定时器(并将超时周期设置为1)

    2.开始 ADC 转换

    3.进入低功耗模式

    由于在您的情况下 ADC 转换速度大约快4倍、因此首先会发生中断。 退出低功耗模式。

    4.读取 ADC 值

    5.再次进入低功耗模式(请记住计时器仍在运行并且尚未超时,它将在大约750-700ms 内超时)

    计时器中断将发生、使我们离开 LPM

    6.根据先前读取的 ADC 值设置/清除 P1.4

    7.重置计时器

    重复