我正在使用BOOSTXL回放作为在MSP430FR5994上运行音频检测代码的参考。 使用的MSP是外部的,并且由启动板成功检测到。 根据样本代码,我将WFP 5.5 和WFP 5.6 上的两个按钮功能替换为WFP 5.7 插针上的一个外部中断。 这是我要用来触发ISR的功能,它从LPM 4.0 唤醒MSP430。 在示例中运行应用程序的代码如下所示:
void runApplication(void) { while(1) { // Disable button interrupt GPIO_disableInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN); GPIO_disableInterrupt(PUSHBUTTON2_PORT, PUSHBUTTON2_PIN); switch(applicationMode) { case RECORD: runRecord(); break; case PLAYBACK: runPlayback(); break; default: break; } // Toggle app mode applicationMode = DEFAULT; // Set a Switch debounce to 500ms __delay_cycles(0.5 * __SYSTEM_FREQUENCY_MHZ__); // Clear the interrupt flag GPIO_clearInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN); // Re-enable the interrupt GPIO_enableInterrupt(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN); // Clear the interrupt flag GPIO_clearInterrupt(PUSHBUTTON2_PORT, PUSHBUTTON2_PIN); // Re-enable the interrupt GPIO_enableInterrupt(PUSHBUTTON2_PORT, PUSHBUTTON2_PIN); // Enter low power mode __bis_SR_register(LPM0_bits + GIE); } }
我已使用可在WFP 5.7 上使用的外部中断将其替换为我的代码,如下所示:
void runApplication(void) { while(1) { P5IE &= ~BIT7; // Disable interrupt on P5.7 // vm1010 switch(appMode) { case app_mode_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); if(pred[0][0]==1) { //PM5CTL0 &= ~LOCKLPM5; // TB0.6 ---- P3.7 ---- PWM 4kHz for buzzer 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 __bis_SR_register(LPM4_bits + GIE); // Enter LPM4 w/ interrupt P1OUT &= ~BIT0; TA1CTL &= ~MC; TB0CTL &= ~MC; } memset(fft_res, 0, sizeof(fft_res)); memset(FFT_data, 0, sizeof(signal_fft)); break; } default: break; } appMode = app_mode_normal; // Need to put in normal mode and back to WoS mode to avoid issue where continuous clapping // causes interrupts faster than we can go in sleep mode, thus causing a state where we // are in sleep mode, but the interrupt is not recognized since interrupt flag is already high and // not cleared // vm1010 mode pin, o/p, low for normal mode P6OUT &= ~BIT1; // vm1010 // Set a Switch debounce to 10ms (500ms -- 0.5 * sys freq) __delay_cycles(0.01 * __SYSTEM_FREQUENCY_MHZ__); P5IFG &= ~BIT7; // Clear 5.7 P5IE |= BIT7; // P5.7 interrupt enabled // vm1010 mode pin, o/p, high for WoS mode P6OUT |= BIT1; // vm1010 // Enter low power mode __bis_SR_register(LPM4_bits+GIE); // sleep_Setup(); // if(FFT_data[1]==0) // { // sleep(1); // } } }
我正在调试模式下评估这两个实现。
在原始样本中,代码进入LPM0,按下WFP 5.5 上的按钮即可唤醒。 之后,应用程序根据 为端口5编写的ISR输入CASE:RECORD,如下所示:
#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: // Toggle record mode applicationMode = PLAYBACK; //exit LPM mode on exit __bic_SR_register_on_exit(LPM0_bits); break; case P5IV_P5IFG6: // Toggle record mode applicationMode = RECORD; //exit LPM mode on exit __bic_SR_register_on_exit(LPM0_bits); break; case P5IV_P5IFG7: break; default: break; } }
在我修改的样本中,我希望在对端口5的ISR进行修改的基础上,使用Pin WFP 5.7 进行类似的操作,如下所示:
#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: break; case P5IV_P5IFG7: __disable_interrupt(); P5IE &= ~BIT7; // Toggle record mode appMode = app_mode_record; //exit LPM mode on exit __bic_SR_register_on_exit(LPM4_bits); break; default: break; } }
但是,与原始样本不同,修改后的版本仅通过以下行进入LPM:__bis_sr_register (LPM4_bits+GIE)。 此后,MSP将在此时继续运行,而不切换到案例:app_mode_record。 我浏览了各种样本并尝试了一些想法,包括使用-__disable_interrupt ()来避免比赛条件。 但是,在runApplication()函数的开头已经完成了这一操作。 除了现在来自WFP 5.7 上的外部信号的中断之外,修改后的代码执行的操作完全相同,因此我无法找到任何不能正常工作的原因。
另外,我对执行的一部分很好奇,我使用上面提到的同一行-__bis_sr_register(LPM4_bits +GIE)- 在开关盒内输入LPM -这里,代码可以使用计时器TA1的计时器中断从LPM唤醒。
我在一些帖子中读到,在某些情况下,无法使用外部中断从LPM唤醒。 在我的情况下,这是否是问题? 在我完成整个项目的过程中,如果有任何建议或想法,我将不胜感激,我看不出 有任何其他可能的原因导致未完成执行。
两个项目的GPIO设置如下所示:
//GPIO interfacing for BOOSTXL Playback sample initGpio() { GPIO_setAsInputPinWithPullUpResistor(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN); GPIO_selectInterruptEdge(PUSHBUTTON1_PORT, PUSHBUTTON1_PIN, GPIO_HIGH_TO_LOW_TRANSITION); GPIO_setAsInputPinWithPullUpResistor(PUSHBUTTON2_PORT, PUSHBUTTON2_PIN); GPIO_selectInterruptEdge(PUSHBUTTON2_PORT, PUSHBUTTON2_PIN, GPIO_HIGH_TO_LOW_TRANSITION); } //GPIO interfacing for my modified sample initGpio() { ............... // vm1010 WoS digital out pin, i/p P5OUT &= ~BIT7; // Pull-down resistor on P5.7 P5REN |= ~BIT7; // Select pull-down mode for P5.7 P5DIR &= ~BIT7; // Set P5.7 to input direction P5IES &= ~BIT7; // P5 Lo/Hi edge .............. }