× MSP430, Microcontrollori 16 bit Ultra Low Power

Gestione degli interrupt

11 Anni 1 Mese fa #6 da elpablito
Risposta da elpablito al topic Gestione degli interrupt
Vorrei riassumere il problema, sperando di essere d'aiuto a chi come me si è imbattuto nel fattaccio.

Creando un nuovo progetto (FILE-NEW-CCS project-etc.) viene creato in automatico un file per il Linker generalmente col nome lnk_msp430gxxxx.cmd dove con le quatto x si identifica il micro usato.
Le definizioni dei vettori contenute nell'ultima parte di questo file sono l'origine del problema.
Prendiamo ora il programma di cui sotto, che è il solito esempio per far lampeggiare il LED.
dove non si fa uso di alcun interrupt.
Se lo si compila vengono segnalati tanti warning quanti sono i MASKABLE interrupts cioè quelli
gestibili delle periferiche. Andando nel file citato si possono constatare i warning e a chi sono associati.

La domanda postasi era come eliminare questi Warning che nel caso specifico avendo usato un MSP430G2553 erano ben 13.
Le soluzioni possibili sono:
- Far finta di niente, tanto gli interrupt non sono usati.
- Nelle opzioni del compilatore far ingnorare i corrispondenti Warning
- Modificare il file del linker
- Definire i vettori
Le prime tre soluzioni non sono piaciute per cui come promesso ho provato la quarta.
Il problema in questo modo sembra risolto, anche se attendo il parere di Mauro per sapere se esistono effetti secondari che non so.
Questa soluzione potrebbe essere un'idea; basta copiare e incollare tutte le routine; poi se serve un interrupt basta servirlo nella corrispondente routine.
Per far questo basta ricordare che non tutti i micro hanno gli stessi interrupt, le periferiche sono diverse, ma questi sono definiti nel file del linker, aggiungere o cancellare qualcosa non è quindi un problema.
Il nome della funzione dell'interrupt, quello che è definito nella corrispondente routine, se non vi piace potete cambiarlo, io ho usato quello diciamo di default.
Mi spiego meglio con un esempio.
Questa routine USCIB0RX potreste non averla

/*
* ======== USCIAB0RX interrupt service routine ========
*/
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR_HOOK(void)
{
/* USER CODE START (section: USCIAB0RX_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: USCIAB0RX_ISR_HOOK) */
}

eliminatela e se avete invece un interrupt USI, modificate di conseguenza

/*
* ======== USI interrupt service routine ========
*/
#pragma vector = USI_VECTOR
__interrupt void USi_ISR_HOOK(void)
{
/* USER CODE START (section: USI_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: USI_ISR_HOOK) */
}

Si dovrebbe poter fare anche un file.c dove buttare queste routine e togliersele
dal main, ci devo provare, in caso mi rifaccio vivo.

Saluti Paolo

Questo è il Main completo


#include <msp430.h>

int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
P1DIR |= 0x01; // Set P1.0 to output direction

for(;;) {
volatile unsigned int i; // volatile to prevent optimization

P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR

i = 10000; // SW Delay
do i--;
while(i != 0);
}

}


/*
* ======== PORT1 Interrupt Service Routine ========
*/
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR_HOOK(void)
{
/* USER CODE START (section: PORT1_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: PORT1_ISR_HOOK) */
}


/*
* ======== PORT2 Interrupt Service Routine ========
*/
#pragma vector=PORT2_VECTOR
__interrupt void PORT2_ISR_HOOK(void)
{
/* USER CODE START (section: PORT2_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: PORT2_ISR_HOOK) */
}

/*
* ======== USCIAB0TX interrupt service routine ========
*/
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR_HOOK(void)
{
/* USER CODE START (section: USCIAB0TX_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: USCIAB0TX_ISR_HOOK) */
}


/*
* ======== USCIAB0RX interrupt service routine ========
*/
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR_HOOK(void)
{
/* USER CODE START (section: USCIAB0RX_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: USCIAB0RX_ISR_HOOK) */
}


/*
* ======== ADC10 Interrupt Service Routine ========
*/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR_HOOK(void)
{
/* USER CODE START (section: ADC10_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: ADC10_ISR_HOOK) */
}


/*
* ======== Timer0_A0 Interrupt Service Routine ========
*/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER0_A0_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: TIMER0_A0_ISR_HOOK) */
}


/*
* ======== Timer0_A1 Interrupt Service Routine ========
*/
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER0_A1_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: TIMER0_A1_ISR_HOOK) */
}


/*
* ======== WDT Interrupt Service Routine ========
*/
#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR_HOOK(void)
{
/* USER CODE START (section: WDT_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: WDT_ISR_HOOK) */
}


/*
* ======== COMPARATORA Interrupt Service Routine ========
*/
#pragma vector=COMPARATORA_VECTOR
__interrupt void COMPARATORA_ISR_HOOK(void)
{
/* USER CODE START (section: COMPARATORA_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: COMPARATORA_ISR_HOOK) */
}


/*
* ======== Timer1_A0 Interrupt Service Routine ========
*/
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER1_A0_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: TIMER1_A0_ISR_HOOK) */
}


/*
* ======== Timer1_A1 Interrupt Service Routine ========
*/
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER1_A1_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: TIME10_A1_ISR_HOOK) */
}


/*
* ======== WDT Interrupt Service Routine ========
*/
#pragma vector=NMI_VECTOR
__interrupt void NMI_ISR_HOOK(void)
{
/* USER CODE START (section: NMI_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: NMI_ISR_HOOK) */
}

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • elpablito
  • Platinum Member
  • Platinum Member
Di più
11 Anni 1 Mese fa #7 da Mauro Laurenti
Risposta da Mauro Laurenti al topic Gestione degli interrupt
Ciao,

effettivamente la via del dichiarare tutte le ISR e' quella giusta.
Dovresti resettare pero' il bit delle interruzioni per quelle interruzioni in cui il flag non si resetta automaticamente alla chiamata dell'ISR.
Infatti se consi non facessi, avendo GIE abilitato, se un flag va ad 1 e non lo si resetta, il microcontrollore quando esce dall'ISR rientra subito nell'ISR in un loop infinito.

Si potrebbe anche settare una variabili di stato per segnalare che un Interrupt imprevisto e' stato eseguito.
per esempio una funzione di sistema di controllo richiamata ogni minuto controlla la variabili di stato per vedere anomalie di sistema.


Saluti,

Mauro

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Mauro Laurenti
  • Avatar di Mauro Laurenti
  • Moderator
  • Moderator
Di più
11 Anni 1 Mese fa #8 da elpablito
Risposta da elpablito al topic Gestione degli interrupt
Buon giorno
Ci ho provato , anche se non ci giuro, dagli un occhio:
Non so cosa fare con WDT e MNI

Saluti
Paolo


/*
* ======== PORT1 Interrupt Service Routine ========
*/
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR_HOOK(void)
{
/* USER CODE START (section: PORT1_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: PORT1_ISR_HOOK) */
P1IFG &= 0x00; /* all flags to zero */
}


/*
* ======== PORT2 Interrupt Service Routine ========
*/
#pragma vector=PORT2_VECTOR
__interrupt void PORT2_ISR_HOOK(void)
{
/* USER CODE START (section: PORT2_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: PORT2_ISR_HOOK) */
P2IFG &= 0x00; /* all flags to zero */
}

/*
* ======== USCIAB0TX interrupt service routine ========
*/
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR_HOOK(void)
{
/* USER CODE START (section: USCIAB0TX_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: USCIAB0TX_ISR_HOOK) */
IFG2 &= ~UCA0TXIFG;
IFG2 &= ~UCB0TXIFG;
}


/*
* ======== USCIAB0RX interrupt service routine ========
*/
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR_HOOK(void)
{
/* USER CODE START (section: USCIAB0RX_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: USCIAB0RX_ISR_HOOK) */
IFG2 &= ~UCA0RXIFG;
IFG2 &= ~UCB0RXIFG;
}


/*
* ======== ADC10 Interrupt Service Routine ========
*/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR_HOOK(void)
{
/* USER CODE START (section: ADC10_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: ADC10_ISR_HOOK) */
ADC10CTL0 &= ~ADC10IFG;
}


/*
* ======== Timer0_A0 Interrupt Service Routine ========
*/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER0_A0_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: TIMER0_A0_ISR_HOOK) */
TA0CCTL0 &= ~CCIFG;
}


/*
* ======== Timer0_A1 Interrupt Service Routine ========
*/
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER0_A1_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: TIMER0_A1_ISR_HOOK) */
TA0IV &= 0x00;
}


/*
* ======== WDT Interrupt Service Routine ========
*/
#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR_HOOK(void)
{
/* USER CODE START (section: WDT_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: WDT_ISR_HOOK) */
}


/*
* ======== COMPARATORA Interrupt Service Routine ========
*/
#pragma vector=COMPARATORA_VECTOR
__interrupt void COMPARATORA_ISR_HOOK(void)
{
/* USER CODE START (section: COMPARATORA_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: COMPARATORA_ISR_HOOK) */
CACTL1 &= ~CAIFG;
}


/*
* ======== Timer1_A0 Interrupt Service Routine ========
*/
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER1_A0_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: TIMER1_A0_ISR_HOOK) */
TA1CCTL0 &= ~CCIFG;
}


/*
* ======== Timer1_A1 Interrupt Service Routine ========
*/
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR_HOOK(void)
{
/* USER CODE START (section: TIMER1_A1_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: TIME10_A1_ISR_HOOK) */
TA1IV &= 0x00;
}


/*
* ======== NMI Interrupt Service Routine ========
*/
#pragma vector=NMI_VECTOR
__interrupt void NMI_ISR_HOOK(void)
{
/* USER CODE START (section: NMI_ISR_HOOK) */
/* replace this comment with your code */
/* USER CODE END (section: NMI_ISR_HOOK) */
}

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • elpablito
  • Platinum Member
  • Platinum Member
Di più
11 Anni 1 Mese fa #9 da Mauro Laurenti
Risposta da Mauro Laurenti al topic Gestione degli interrupt
Ciao,

da una prima lettura direi che sembra apposto.

Per NMI considera che viene generato in tre casi:

• fronte su RST/NMI se configurato come NMI
• Problema all'oscillatore
• Accesso illegale nella memoria flash

Ogni opzione ha relativo bit di enable : NMIIE, ACCVIE, OFIE
E relativo flag: NMIIFG, ACCVIFG, OFIFG

Per cui questi sono i bit da resettare.

Per il WDT c'e' il relativo enable interrupt WDTIE e flag WDTIFG.

...sei ormai preso dagli MSP430! :)

Saluti,

Mauro

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Mauro Laurenti
  • Avatar di Mauro Laurenti
  • Moderator
  • Moderator
Di più
11 Anni 4 Settimane fa #10 da Blu
Risposta da Blu al topic Gestione degli interrupt
Ciao a tutti.

Scusate se intervengo così tardivamente; vorrei riportarvi, qui sotto, una possibile soluzione per la gestione degli Interrupt che non vengono utilizzati.
In sostanza, è un'unica ISR, che teoricamente non dovrebbe mai essere attivata (se tutto va bene), il cui unico compito è quello di pulire il flag che per qualche motivo si è attivato. Potete fare la prova di copiarla ed incollarla nel vostro programma, con me ha funzionato bene.



#pragma vector = PORT1_VECTOR, PORT2_VECTOR, ADC10_VECTOR, USCIAB0TX_VECTOR, USCIAB0RX_VECTOR, TIMER0_A0_VECTOR, TIMER0_A1_VECTOR, COMPARATORA_VECTOR, TIMER1_A0_VECTOR, TIMER1_A1_VECTOR, NMI_VECTOR, WDT_VECTOR
__interrupt void Interrupt_Inutilizzati(void)
{
P1IFG &= 0x00;
P2IFG &= 0x00;
ADC10CTL0 &=~ ADC10IFG;
IFG2 &=~ (UCA0TXIFG + UCB0TXIFG + UCA0RXIFG + UCB0RXIFG);
TA0CCTL0 &=~ CCIFG;
TA0IV &= 0x00;
CACTL1 &=~ CAIFG;
TA1CCTL0 &=~ CCIFG;
TA1IV &= 0x00;
FCTL3 &=~ ACCVIFG;
IFG1 &=~ (NMIIFG + OFIFG + WDTIFG);
}


So che ciò che sto per scrivere è scontato, ma visto che questo forum è frequentato anche da chi (come me) è alle prime armi, vorrei puntualizzare una cosa:
RICORDATEVI DI TOGLIERE TUTTO CIO' PER CUI AVETE SCRITTO UN'APPOSITA ISR.
Quindi, se avete previsto, nel vostro codice, di avvalervi dell'Interrupt del modulo CCR2 del Timer0_A, dovrete togliere sia "TIMER0_A1_VECTOR" che "TA0IV &= 0x00".
Ora, una piccola precisazione: se tutto va bene, questa ISR non verrà MAI eseguita. Ad ogni modo, penso che sia meglio scriverla nel migliore dei modi.
Ad esempio, generalmente è inutile dare l'istruzione di pulire quei flag che vengono automaticamente puliti nel momento in cui viene eseguita l'ISR (ad esempio, i moduli CCR0 del Timer0_A e del Timer1_A). Se lo stesso principio vale anche per questa ISR, sarebbe utile se qualcuno la riscrivesse (qualcuno più esperto di me), in modo da renderla il più compatta possibile, considerando anche il fatto che si tratta di una parte di codice che potrebbe essere riportata in tutti i nostri progetti.

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Blu
  • Junior Member
  • Junior Member
Di più
Moderatori: Mauro LaurentiMatteo Garia

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Login