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.

[参考译文] MSP-EXP430FR4133:ISR 代码 isn#39;t 正在执行- CAN#39;t 明白原因

Guru**** 2535880 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/920969/msp-exp430fr4133-isr-code-isn-t-executing---can-t-figure-out-why

器件型号:MSP-EXP430FR4133

大家好、我正在尝试利用 Launchpad 的 OutofBox 演示源来证明一些功能并获得平台方面的一些经验。 我遇到了一个问题、其中 TimerA0 ISR 代码似乎没有执行、我很难弄清楚原因。 可以有人来看看、教育我吗? 我觉得这是一件很小的事情、我似乎无法找到。  

让我感到困惑的一件事是、如果我在 ISR 中取消对 printf()语句的注释、代码将按预期执行。 我将此处所述的两个 LED 用作状态机检测调试、以确定它们是否被调用。 我尝试仅发布相关代码段、但可以在适当时提供更多内容。  

#pragma vector = TIMER0_A0_VECTOR
__INTERRUPT void TIMER0_A0_ISR (void)
{
//同时按住按钮 S1和 S2
如果(!(P1IN 和 BIT2)&&!(P2IN 和 BIT6))
{
保持计数++;
isrcount++;
如果(保持计数= 40)
{
//停止计时器 A0
Timer_A_stop (timer_A0_BASE);

//更改模式
// printf ("检测到模式开关\n");
如果(*模式==0)
{
//此部件工作
// printf ("切换到 ADCRAW 模式\n");
(*模式)= ADCRAW_MODE;
P1OUT |= BIT0;//打开 LED1
P4OUT &=~BIT0;//关闭 LED2

}
如果(*模式=ADCRAW_MODE)则为其他值
{
//此部分不会-此代码仅在未注释的 printf()语句中执行,但随后会正常运行
// printf ("切换到 LINEARFLOW 模式\n");

P1OUT &=~BIT0;//关闭 LED1
P4OUT |= BIT0;//打开 LED2

(*模式)= LINEARFLOW_MODE;
}
如果(*模式=LINEARFLOW_MODE)则为其他模式
{
// printf ("切换到 HFLOW 模式\n");
P1OUT |= BIT0;//打开 LED1
P4OUT |= BIT0;//打开 LED2

(*模式)= gpHFLOW_MODE;
}
如果(*模式=gpHFLOW_MODE)则为其他值
{
// printf ("切换到 ADCRAW 模式\n");
P1OUT |= BIT0;//打开 LED1
P4OUT &=~BIT0;//关闭 LED2

(*模式)= ADCRAW_MODE;
}

_BIC_SR_REGISTER_ON_EXIT (LPM3_BITS); //退出 LPM3
}
}

//按钮 S1已松开
IF (P1IN 和 BIT2)
{
*S1buttonDebounb回= 0; //清除按钮去抖
P1OUT &=~BIT0;
}

//按钮 S2被释放
IF (P2IN 和 BIT6)
{
*S2buttonDebounb回= 0; //清除按钮去抖
P4OUT &=~BIT0;
}

//同时释放按钮 S1和 S2
IF (((P1IN 和 BIT2)&&(P2IN 和 BIT6))
{
//停止计时器 A0
Timer_A_stop (timer_A0_BASE);
__BIC_SR_REGISTER_ON_EXIT (LPM3_BITS);//退出 LPM3
}
} 
int main (void)
{
//WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
WDT_A_HOLD (_MSP430_BASEADDRESS_WDT_A__); //停止 WDT

/*
* LaunchPad 演示包含此代码以从低功耗模式唤醒
*
//检查是否从 LPMx.5唤醒
IF (SYSRSTIV = SYSRSTIV_LPM5WU)
{
init_gpio();
_enable_interrupt ();

switch (*模式)
{
案例 ADCRAW_MODE:
中断;
案例 LINEARFLOW_MODE:
中断;
案例 GPHFLOW_MODE:
中断;
}
}
else // else 必须是首次引导,运行 inits
{

/*
*在我们执行任何有趣的操作之前初始化例程
*
init_gpio();
init_Clock();
init_rtc();
init_lcd();
GPIO_clearInterrupt (GPIO_PORT_P1、GPIO_PIN2);
GPIO_clearInterrupt (GPIO_PORT_P2、GPIO_PIN6);
*S1buttonDebounce =*S2buttonDebounce =* MODE = 0;
_enable_interrupt ();

RTC_setModulo (RTC_BASE、8191);
RTC_enableInterrupt (RTC_BASE、RTC_overflow_interrupt);
RTC_START (RTC_BASE、RTC_CLOCKSOURCE_XT1CLK);

displayScrollText ("flow demo");//引导消息-仅限大写

字符}

/*
*主循环
*

while (1)
{

switch (*模式)
{
案例 ADCRAW_MODE:
displayScrollText ("选择 ADC 原始模式");
ClearLCD();
//调用 ADC Init & Start
中断;
案例 LINEARFLOW_MODE:
displayScrollText ("选择线性流模式");
ClearLCD();
中断;
案例 GPHFLOW_MODE:
displayScrollText ("GPH not implemented");
ClearLCD();
中断;

默认值: //必须是首次启动
DisplayScrollText ("保持 S1和 S2以切换模式");
ClearLCD();
中断;
}

_bis_SR_register (LPM3_bits | GIE);//输入 LPM3
__no_operation();
}


}// main 的末尾() 

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

    您好、Dave、

    不确定 printf()的来源。 如果它是您自己的、并且基于诸如 putchar()之类的内容、直接实施到反向通道 UART、而不涉及中断;那么它将起作用。 如果您使用更巧妙/功能更丰富的 printf()实现并在后台执行中断 =>那么一切都很清楚,它无法正常工作。

    当在 ISR()内部时,所有其它中断被禁用,并且将一个复杂的通信函数放在一个 ISR()内会阻止所有中断。

    三种方法:

    -仅从外部使用 printf(),并通过令牌/标志与消息生成通信 -或-

    -使用一个不需要任何中断的简单的愚蠢 printf()实现。 但是不要把这个叫做 printf(),它可能会误导人..

    -作为第三种解决方案、允许中断嵌套;但是、如果嵌套到相同类型的中断中、这可能会变得很棘手。

    我希望大家编码愉快

        Johann

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

    Johann、您好、我想您误解了我的帖子。 printf()函数是 CCS MSP430项目中的默认编译,这里没有什么特别之处,printf()实际上似乎正常执行。 我感到困惑的是,在 printf()语句之后立即执行的部分代码(请参阅上面片段中的注释)似乎仅在 printf()语句 注释时执行。  

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

    您好、Dave、

    只是为了澄清。

    如果 printf 包含在代码中、您可以看到 LED 开关处于关闭状态、对吧? 如果 printf 未包含在其中、则无法看到任何 LED 活动。

    这种理解是否正确?

    如果是这种情况、如果 printf 未包含在代码中、如何检查 LED 活动? 只需目视。 您是否尝试使用示波器检查是否有任何活动(脉冲非常短?)。

    可能是 printf 充当延迟、这为能够看到 LED 提供了足够的时间。

    现在请让我。

    此致

    Kostas

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

    您好、Dave、

    感谢您的耐心等待。 我收到通知、我的'FR4133电路板已发货。 我很快就能 X 检查出了什么问题。 目前在家工作、并且没有所有 EVM 都已安装到位、这就是为什么...

    Johann

     

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

    您好 Johann、

    我废除了该代码、编写了自己的代码、并继续进行。 我决定暂时不要担心去抖、因为它对我的最终应用并不重要、只用于概念验证。 我认为这个问题与定时器使能标志有关、但我还没有返回到重复检查。 如果您确定问题是什么、我肯定会理解它以供将来参考。  

    对于它的价值、我发现很难遵循该示例代码、尤其是去抖逻辑、因为很少有人会对该流程进行说明。  

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

    您好、Dave、

    我加载了"OutOfBox"演示、将代码调整为与您的代码类似、添加了一些定义以关闭打开的引用并运行它。

    我首先关闭的是通过在寄存器窗口中设置 RTCCTL.RTCIE=0来实现的 RTC 中断...因为 RTC 中断反复出现。

    (笑声) 和... 你是对的... 在"struct"参数中也是如此..._TAIE 从未被置位、因此 TA0CCTL0.CCIE 也没有 ISR。  手动设置标记会导致预期反应。

    顺便说一下,你给我展示了一件有趣的事情… :我了解了如何实现"StopWatchMode.c"中的“void Inc_RTC ()”函数... 它使用模数除法而不是比较。 请不要这样做、不要以此为例;尽管它在数学上是正确的、但它不是省电的方法。  看起来我们在工作中有一个"抽象程序员"。

    Dave、很抱歉给您带来不便...   

        Johann

    PS:我可能会再来这里告诉你“Inc_RTC()”上的时钟差

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

    您好、Dave、

    我对函数"inc_rtc()"有一些检查结果 、结果有点惊讶。 我还在"LpInc_RTC()"下面提供了一个替代实现,这是一个更节能的方案。

    以下是性能检查的结果:

    案例名称 …func()之前; …func()之后; INC_RTC ();[CLKS] LpInc_RTC ();[CLKS]
    无进位 00:00:00.00 00:00:00.01 189. 13.
    CSEC 进位 00:00:00.99 00:00:01.00 379. 28.
    SEC 进位 00:00:59.99 00:01:00.00 569. 40
    最小进位 00:59:59.99 01:00:00.00 751. 52.
    HRS 进位 99:59:59.99 00:00:00.00 75 50

    原始函数"inc_rtc ();"、如演示中所示。

    //递增实时计数器
    void inc_rtc ()

       //时钟增量逻辑
       //最多处理100小时,然后回绕到00:00:00
       (*本位数)++;
       (*本位数)%=100;
       如果((*本秒)==0)
       {
           (*秒)++;
           (*秒)%=60;
           如果((*秒)==0)
           {
               (*分钟)++;
               (*minutes)%=60;
               如果((*分钟)==0)
               {
                   ++(*hours);
                   (*hours)%=100;
               }
           }
       }

    在低功耗实现"Lpinc_rtc ();"下面 、这更保守能源(变量名称也被更改)

    空 Lpinc_rtc ()

     if ((* LpCSec)<99)(* LpCSec)++;
     否则{
       (*LpCSec)=0;
       if (*LpSec)<59)(*LpSec)++;
       否则{
         (*LpSec)=0;
         if ((* LpMin)<59)(* LpMin)++;
         否则{
           (*LpMin)=0;
           if (*LpHrs)<99)(*LpHrs)++;
           否则(* LpHrs)=0;
         }
       }
     }


    我还检查了该演示中使用的其他一些软件技术(其中一些技术也不常见);我想将来会更新该演示。 时间就说明了。

    快乐编码

        Johann