Проблема с прерыванием MSP430 после закрытия отладчика

Я использую следующий код, чтобы мигать светодиодами с помощью прерывания таймера:

#include <msp430.h>

#define LED1 BIT0                       //define LED1 as bit 0 (0x00)
#define LED2 BIT6                       //define LED2 as bit 6 (0x40)

int main(void)
{
    //stop watchdog timer
    WDTCTL = WDTPW | WDTHOLD;

    //P1 initialization code
    P1OUT &= 0x00;                      //clear all bits on P1
    P1DIR |= (LED1|LED2);               //set P1.0 and P1.6 to output direction

    //Timer_0A3 initialization
    TA0CCR0 = 12e3;                     //count limit (16 bit)
    TA0CCTL0 = 0x10;                    //enable counter interrupts, set bit 4 high
    TA0CTL = TASSEL_1 + MC_1;           //Timer A0 with ACLK @ 12KHz (TASSEL_1), count UP (MC_1)


    //low power mode
    _BIS_SR(LPM0_bits + GIE);           //LPM0 (low power mode) with interrupts enabled
}

#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)       //service routine for Timer0 A0 interrupt
{
    P1OUT ^= (LED1|LED2);               //toggle P1.0 using exclusive-OR
}

И знаете что, это работает! Но только когда я запускаю отладчик. Когда я закрываю отладчик, он прекращает свои действия, и какой бы светодиод ни горел в это время, он продолжает гореть. Сброс платы совсем не помогает.

После небольшого исследования в Интернете я попытался пойти Tools -> Debugger Options -> MSP430 Debugger Options -> Clock Control, чтобы снять отметку с соответствующего таймера. У меня есть такие варианты: []ACLK []SMCLK []TACLK. Я пробовал каждую комбинацию проверок / снятий, и, похоже, ничто не позволяет моим прерываниям работать после того, как отладчик перестает работать.

Если бы мне пришлось угадывать, я бы сказал, что таймер работает, но почему-то флаги прерывания не устанавливаются должным образом. Есть идеи, что здесь происходит?


person austincrft    schedule 11.07.2014    source источник
comment
Мне кажется, что вы, вероятно, не активируете BIT3. Подключены ли физические провода к нужным контактам?   -  person Scott Solmer    schedule 11.07.2014
comment
Все это делается на доске разработки LaunchPad. Никакой проводки не требуется. BIT3 присоединен к переключателю противодействия, который сейчас не используется. Я уберу это из кода.   -  person austincrft    schedule 11.07.2014


Ответы (5)


Очистите флаг прерывания таймера в обработчике прерывания:

#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)       //service routine for Timer0 A0 interrupt
{
    TA0CTL &= ~TAIFG;                   // Reset interrupt
    P1OUT ^= (LED1|LED2);               //toggle P1.0 using exclusive-OR
}
person benpro    schedule 11.07.2014
comment
По-прежнему возникает та же ошибка, но, вероятно, мне все равно нужно было это сделать. - person austincrft; 11.07.2014
comment
Это могло быть TA0CCTL0 & = ~ CCIFG; - person benpro; 11.07.2014
comment
На самом деле, мне удалось получить ваш код - как есть - для правильной работы на MSP430F5438. Если исключить любые вариации процессора, я полагаю, что происходит что-то еще. - person benpro; 11.07.2014
comment
Вы заставили его работать вне режима отладки? Тогда я понятия не имею, что происходит. Вы используете Code Composer Studio? - person austincrft; 11.07.2014
comment
да. Когда возникают такие необъяснимые проблемы, я начинаю с того, что вставляю индикаторы других типов оборудования, например, устанавливаю на других выводах оборудования высокий уровень для отслеживания выполнения программы. Может случиться так, что выполнение так и не доходит до конца программы из-за какой-либо ошибки или выход из LPM0 по какой-то причине. - person benpro; 14.07.2014

Похоже, вы запускаете приложение из ОЗУ. Дважды проверьте конфигурацию компоновщика и убедитесь, что вы ориентируетесь на Flash, если хотите работать без отладчика.

Кроме того, вам нужно очистить любой флаг прерывания таймера? Может случиться так, что при подключенном отладчике режим низкого энергопотребления не используется, и прерывание по таймеру постоянно запускается. В режиме низкого энергопотребления возможно, что, если флаг прерывания не сброшен, процессор не будет снова пробуждаться, когда таймер снова попытается установить флаг прерывания.

person rjp    schedule 11.07.2014
comment
Кажется, я не могу найти конфигурацию компоновщика в Code Composer Studio. Вы знаете, где это находится, чтобы я мог это проверить? Еще одна интересная вещь заключается в том, что я закомментировал включение _BIS_SR(LPM0_bits + GIE); режима пониженного энергопотребления, и это дает мне тот же результат без прерывания даже с отладчиком. Возможно ли, что, когда отладчик не работает, он неправильно переходит в режим низкого энергопотребления? - person austincrft; 11.07.2014
comment
Я когда-либо использовал IAR EW430 только для работы с MSP430, поэтому я не знаком с CCS. Ответ @benpro, вероятно, правильный. - person rjp; 11.07.2014

Я обнаружил, что строку кода BCSCTL3 |= LFXT1S_2; нужно добавить между TA0CTL = TASSEL_1 + MC_1; и _BIS_SR(LPM0_bits + GIE);. Согласно техническому описанию, это должен быть установлен базовый системный элемент управления часами. Это как-то связано с кварцевым генератором, но я не совсем понимаю, что он делает. Если бы кто-нибудь мог предложить мне больше идей, это было бы здорово.

person austincrft    schedule 15.07.2014

У меня такая же проблема. Через некоторое время я понял, что проблема в ACLK. Когда код запускается из отладчика, правильная подача ACLK из VLO организует отладчик. Но в противном случае вам нужно установить источник для ACLK вручную, установив LFXT1Sx = 10b в C:

BCSCTL3 = LFXT1S_2;

Сделайте это где-нибудь в начале main().

person stanokonrad    schedule 03.05.2016
comment
Что вы имеете в виду под отладчиком устраивает? - person Peter Mortensen; 24.02.2017

Попробуйте добавить:

  • Первый

while (1);

до _BIS_SR(LPM0_bits + GIE);

  • Второй

while (1);

после _BIS_SR(LPM0_bits + GIE);

person Ruslan Gerasimov    schedule 12.07.2014
comment
while(1) до _BIS_SR(LPM0_bits + GIE); заставили огни вообще перестать мигать. while(1) после _BIS_SR(LPM0_bits + GIE); дает мне ту же ошибку. - person austincrft; 14.07.2014