我正在使用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
..............
}
