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.

[参考译文] MSP430FR5994:在调试期间退出LPM,不带按钮功能

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1091820/msp430fr5994-exiting-the-lpm-during-debugging-without-push-button-functionality

部件号:MSP430FR5994

我正在使用BOOSTXL回放作为在MSP430FR5994上运行音频检测代码的参考。 使用的MSP是外部的,并且由启动板成功检测到。 在代码中,我使用开关盒结构在BOOSTXL示例中可用的'默认'和'重新连接'模式之间移动。 我的执行代码如下所示:

void runApplication(void)
{
    while(1)
    {
        P5IE &= ~BIT7;      // Disable interrupt on P5.7 // vm1010
        P5IE &= ~BIT6;      // Disable interrupt on P5.6
        P5IE &= ~BIT5;      // Disable interrupt on P5.5

        switch(applicationMode)
        {
            case RECORD:
            {
            ...............
            ...............
            break;
            default: break;
            }
        }

        // Toggle app mode
        applicationMode = DEFAULT;

        P6OUT &= ~BIT1;                 // vm1010

        // Set a Switch debounce to 500ms
        __delay_cycles(0.01 * __SYSTEM_FREQUENCY_MHZ__);

        P5IFG &= ~BIT6;                 // Clear interrupt on P5.6
        P5IE |= BIT6;                   // Enable interrupt on P5.6
        P5IFG &= ~BIT5;                 // Clear interrupt on P5.5
        P5IE |= BIT5;                   // Enable interrupt on P5.5
        P5IFG &= ~BIT7;                 // Clear interrupt on P5.7 // vm1010
        P5IE |= BIT7;                   // Enable interrupt on P5.7 // vm1010
        
        // vm1010 mode pin, o/p, high for WoS mode
        P6OUT |= BIT1;  // vm1010

        __bis_SR_register(LPM4_bits + GIE);

        int16_t spectrum[SIGNAL_ROWS1][SIGNAL_COLS1];

        if(FFT_data[1] != 0)
        {
        ..............
        ..............
        }
        
        
        

在外部MSP上载代码后,当我尝试运行此代码时,程序在检查应用程序的'默认'案例时无法退出LPM4。 我知道发生这种情况的原因是在本例中使用ISR,因为它使用按钮功能退出模式。 ISR的代码如下所示:

#pragma vector=PORT5_VECTOR
__interrupt void port5IsrHandler(void)
{
    switch (__even_in_range(P5IV, P5IV_P5IFG7))
    {
        case P5IV_NONE: break;
        case P5IV_P5IFG0: break;
        case P5IV_P5IFG1: break;
        case P5IV_P5IFG2: break;
        case P5IV_P5IFG3: break;
        case P5IV_P5IFG4: break;
        case P5IV_P5IFG5: break;
        case P5IV_P5IFG6:
            // Toggle record mode
            applicationMode = RECORD;
            //exit LPM mode on exit
            __bic_SR_register_on_exit(LPM4_bits+GIE);
            break;
        case P5IV_P5IFG7:
            // Toggle record mode
            applicationMode = RECORD;
            //exit LPM mode on exit
            __bic_SR_register_on_exit(LPM4_bits+GIE);
            break;
        default:
            break;
   }
}

但是,我正在使用的外部电路上没有按钮,因此,我需要直接退出LPM4,以便在MSP430执行初始检查后能够记录音频数据。 我正在使用内置调试器评估整个应用程序,在当前情况下-在输入LPM4后使用按钮,允许MSP检查'if'状态,然后进入'RECORE'模式。  

虽然我找到了描述使用中断退出LPM的可能性的各种文章,但我不确定如何使它在我的情况下发挥作用,因为我不想在执行过程中更改单个步骤的整个代码的结构。 我还尝试过使用不同ISR的可能性,但这不起作用,因为执行过程中仍涉及按钮功能。

如果需要其他信息,请告诉我,我将尽早回复。

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

    Siddhant,

    这里最简单的答案就是让主机MCU切换连接到与按钮相连的同一GPIO的GPIO。 否则,您只需更改代码,即可通过您想要的触发器中断和唤醒设备。  

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

    Jace,

    感谢您的回复。 因此,理想情况下,我根本不想包括切换GPIO。 在将代码更改为中断的情况下-我可以通过代码分支检查输入LPM后立即出现的If条件来执行重定向。 我尝试使用以下内容:

            __bis_SR_register(GIE);
            __no_operation();

    当代码移出休眠状态时,此方法不适用于:__bis_sr_register(LPM4_bits+GIE)。  

    此外,在上述情况下,代码会一直循环,并且永远不会进入已定义的其他应用程序模式。 我不知道我可以在这里尝试什么来改变中断。 我是否需要完全删除按钮ISR,然后添加新条件,或者它们是否仍保留在代码中?

    谢谢。

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

    您好,

    如果您进入低功耗模式,则需要一种通过中断摆脱此模式的方法。 几乎任何中断都会执行(取决于LPM级别,因为某些中断有限制)。 您需要在应用程序中决定如何 处理。 您可以根据需要对其进行编码。

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

    您好,Jace:

    我设法使用计时器功能解决了该问题,在1毫秒后将MSP从LPM中唤醒。 但是,我想用从麦克风获得的数字信号来代替它。 我不知道这如何工作,因为麦克风信号连接到配置为按钮开关的WFP 5.6。 如何使用此处提供的信号作为中断将我的程序从LPM中唤醒而不使用按钮功能?  

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

    您好Siddhant,

    从MCU的角度来看,引脚上是否有按钮,或者是否有电信号进入并不重要。 要中断引脚,您只需要高到低的过渡或低到高的过渡。 您可以在GPIO寄存器上配置此功能。  

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

    您好,

    好的,这消除了我的困惑。 基于此,我正在上传我修改的代码和我需要的功能。 请告诉我,您是否可以观察到任何结构问题:

    void runApplication(void)
    {
        while(1)
        {
            P5IE &= ~BIT7;      // Disable interrupt on P5.7 // vm1010
            P5IE &= ~BIT6;      // Disable interrupt on P5.6
    
            switch(applicationMode)
            {
                case RECORD:
                {
                    volatile uint16_t j;
                    runRecord();
                    amplify_data();
                    fft_init();
                    while(window_number < 64)
                    {
                        fft_cal();
                    }
                    window_number=0;
                    for(j = 1; j < (VECTOR_SIZE / 2); j++)  // vm1010
                    {
                        // vm1010
                        real = fft_res[2 * j] << 2;
                        imag = fft_res[2 * j + 1] << 2;
                        if(real < 0)
                        {
                            real_abs = ~real + 1;
                        }
                        else
                        {
                            real_abs = real;
                        }
                        if(imag < 0)
                        {
                            imag_abs = ~imag + 1;
                        }
                        else
                        {
                            imag_abs = imag;
                        }
                        if(real_abs >= imag_abs)
                        {
                            max = real_abs;
                            min = imag_abs;
                        }
                        else
                        {
                            max = imag_abs;
                            min = real_abs;
                        }
                        mag = max + 3 * (min >> 3);
                        FFT_data[j] = mag << 1;
                    }
    
                    int16_t spectrum[SIGNAL_ROWS1][SIGNAL_COLS1];
                    signed int a,b;
                    for(a=0; a<1; a++)
                    {
                        for(b=256; b>=0; b--)
                        {
                            spectrum[a][b] = FFT_data[b];
                        }
                    }
    
                    matrix_multiply(1, 256, 256, 20, spectrum, weights1, pdt1);
                    matrix_add(1, 20, pdt1, bias1, layer1);
                    act_funct(1, 20, layer1, act1);
    
                    matrix_multiply(1, 20, 20, 10, act1, weights2, pdt2);
                    matrix_add(1, 10, pdt2, bias2, layer2);
                    act_funct(1, 10, layer2, act2);
    
                    matrix_multiply(1, 10, 10, 2, act2, weights3, pdt3);
                    matrix_add(1, 2, pdt3, bias3, layer3);
                    act_out(1, 2, layer3, pred);
    
                    TB0CCR0 = 2000-1;                         // PWM Period, 4kHz --> 250 us --> 2000 (0 to 1999) ticks at SMCLK = 8MHz
                    TB0CCTL6 = OUTMOD_7;                      // CCR6 reset/set
                    TB0CCR6 = 1000;                           // CCR6 PWM duty cycle, 50% duty cycle, 1000 ticks
                    TB0CTL = TBSSEL__SMCLK | MC__UP | TBCLR;  // SMCLK, up mode, clear TBR
                    P1OUT |= BIT0;
                    // TA1.1 ---- P1.2 ---- Timer for approx. 3 seconds for buzzer and LED
                    TA1CTL = TASSEL__SMCLK | MC__CONTINUOUS | TACLR | TAIE;        // SMCLK, Continuous mode, clear TAR
    
                    P1OUT &= ~BIT0;
                    TA1CTL &= ~MC;
                    TB0CTL &= ~MC;
                    memset(FFT_data, 0, sizeof(FFT_data));
                    break;
                default: break;
                }
            }
    
            // Toggle app mode
            applicationMode = DEFAULT;
    
            P6OUT &= ~BIT1;                 // vm1010
    
            // Set a Switch debounce to 500ms
            __delay_cycles(0.01 * __SYSTEM_FREQUENCY_MHZ__);
    
            P5IFG &= ~BIT6;                 // Clear interrupt on P5.6
            P5IE |= BIT6;                   // Enable interrupt on P5.6
            P5IFG &= ~BIT7;                 // Clear interrupt on P5.7 // vm1010
            P5IE |= BIT7;                   // Enable interrupt on P5.7 // vm1010
            P6OUT |= BIT1;  // vm1010
    
            __bis_SR_register(LPM4_bits+GIE);
    
        }
    }
    //******************************************************************************
    // Port 5 interrupt service routine
    //      This ISR handles the push button to switch the application
    //      mode.
    //******************************************************************************
    #pragma vector=PORT5_VECTOR
    __interrupt void port5IsrHandler(void)
    {
        switch (__even_in_range(P5IV, P5IV_P5IFG7))
        {
            case P5IV_NONE: break;
            case P5IV_P5IFG0: break;
            case P5IV_P5IFG1: break;
            case P5IV_P5IFG2: break;
            case P5IV_P5IFG3: break;
            case P5IV_P5IFG4: break;
            case P5IV_P5IFG5: break;
            case P5IV_P5IFG6:
                // Toggle record mode
                applicationMode = RECORD;
                //exit LPM mode on exit
                __bic_SR_register_on_exit(LPM4_bits+GIE);
                break;
            case P5IV_P5IFG7:
                //Toggle record mode
                applicationMode = RECORD;
                //exit LPM mode on exit
                __bic_SR_register_on_exit(LPM4_bits+GIE);
                break;
            default:
                break;
       }
    }
    

    runApplication()是我在代码的main()函数中调用的函数。 操作将通过开关盒进入应用程序Mode=default,此处与MSP430相连的麦克风将在WFP 5.6 上提供信号。 我想将此用作来自4.0 的唤醒信号。 因此,我在代码的末尾输入4.0 ,对应的ISR表示对WFP 5.6 的转换。 我认为代码应该按如下方式运行:在禁用顶部的中断后,设置了applicationMode=default并对中断进行编程,之后设备将进入4.0 ,对于唤醒信号,我使用从WFP 5.6 获得的低到高的转换, 随后,代码再次转到顶部,并输入case applicationMode=record。 在这里,执行整个操作,代码最终到达一行applicationMode=default。

    根据您的建议和我在网上找到的所有内容,我找到了上面的代码。 这里还有一个小问题:MSP430是否会基于唤醒信号退出4.0 ,而无需在'DEBUG'模式下按下按钮? 或者调试器的中断唤醒例程是否与普通应用程序的中断唤醒例程不同。  

    如果需要其他信息,请告诉我。 非常感谢您之前提出的建议。

    此致,

    Siddhant