MSP430, Microcontrollori 16 bit Ultra Low Power

msp432 - adc14 timerA

  • luca.palombella
  • Autore della discussione
  • Nuovo Utente
  • Nuovo Utente
Di più
8 Anni 5 Mesi fa #1 da luca.palombella
msp432 - adc14 timerA è stato creato da luca.palombella
Ciao a tutti, riprendo questo mio post per verificare se quanto ho fatto può essere corretto a livello di codice (nella pratica funziona ma vorrei capire lo stesso se sto pilotando nel modo corretto l'adc del microcontrollore).
Faaccio una piccola sintesi:
  • Ho un timer che determina un interrupt ogni 20us nella quale si verificano degli eventi che spiego sotto
  • Al tempo 0 accendo un led (ok). Al tempo 20 dovrei accendere ADC che vorrei campionasse ripetutamente su un singolo canale (quello che msp definisce ADC14CONSEQ_2). Al tempo 200 spengo un led. Al tempo 800 spengo ADC e invio i valori sulla seriale.

Ora accensione e spegnimento del led funziona perfettamente. Quello che vorrei capire è se sto pilotando correttamente l'adc facendolo accendere, campionare continuamente ogni 20us e infine spegnere. Posto qui sotto le parti di codice che credo siano inerenti.
Code:
// costanti dei tempi di acquisizione #define STEP 20 // 20 us tempo dell'interrupt #define TIME_ON 0 // 0 us led on, signal = 0 V #define TIME_ADC_START 20 // 20 us inizio istante di acquisizione #define TIME_OFF 200 // 200 us led off, signal = 3 V #define TIME_ADC_END 800 // 800 us fine istante di acquisizione #define TIME_SAVE 900 // 900 us controllo fine ciclo #define TIME_RESET 1000 // 1.000 us periodo del segnale generato // ==========Configurazione ADC 14 bit========== P6SEL1 |= BIT1; P6SEL0 |= BIT1; // Canale A14 (P6.1) configurato per ADC ADC14CTL0 = ADC14ON | ADC14SHP | ADC14CONSEQ_2; // Turn on ADC14, set sampling time ADC14CTL1 = ADC14RES__14BIT; // Use sampling timer, 14-bit conversion results ADC14MCTL0 = ADC14VRSEL_0 | ADC14INCH_14; // A0 ADC input select; Vref=AVCC=3.3V // ==========Configurazione clock a 12 MHz========== CSKEY = 0x695A; // Unlock CS module for register access CSCTL0 = 0; // Reset tuning parameters CSCTL0 = DCORSEL_3; // Set DCO to 12MHz (nominal, center of 8-16MHz range) CSCTL1 = SELA_2 | SELS_3 | SELM_3; // Select ACLK = REFO, SMCLK = MCLK = DCO CSKEY = 0; // ==========Configurazione TimerA0========== NVIC_ISER0 = 1 << ((INT_TA0_0 - 16) & 31); // Enable TA0_0 interrupt in NVIC module TA0CCTL0 &= ~CCIFG; // Interrupt disable TA0CCR0 = STEP; // Overflow (step dell'interrupt) TA0CTL = TASSEL__SMCLK | MC__UP | ID_2; // SMCLK, UP mode, Divisione per 4 (12 MHz / 4 = 3 MHz) TA0EX0 |= TAIDEX_2; // Divisione per 3 (3 MHz / 3 = 1 MHz) // ===========================Interrupt Service Routines=========================== // Timer A0 interrupt service routine void TimerA0_0IsrHandler(void) { TA0CCTL0 &= ~CCIFG; /* STEP = 20 */ if(TIME_ADC_START <= microsecondi < TIME_ADC_END) { ADC14CTL0 |= ADC14SC | ADC14ENC; while(!(ADC14IFGR0 & BIT0)); values[index_N] = ADC14MEM0; index_N++; } switch (microsecondi){ case TIME_ON: IR_on(); //accende IR break; case TIME_OFF: IR_off(); //spegne IR break; case TIME_SAVE: if (index_N >= N){ index_N = 0; microsecondi = 0; IR_off(); ADC14CTL0 &= ~ADC14ENC; TA0_off(); send_all_values(); } default: break; } microsecondi += STEP; if (microsecondi >= TIME_RESET){ microsecondi = 0; } }

Esempi che trovo in giro spiegano come usare ADC in sequenze ripetute all'interno di un loop ma io voglio appunto limitarlo tra due tempi alla frequenza che voglio io. Grazie.

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

  • Mauro Laurenti
  • Moderatore
  • Moderatore
Di più
8 Anni 5 Mesi fa #2 da Mauro Laurenti
Risposta da Mauro Laurenti al topic msp432 - adc14 timerA
Salve Luca,

da una prima lettura sembra OK.

Puoi fare anche un passo in avanti.

Come riportato nel datasheet e user guide




puoi collegare direttamente il timer al trigger dell'ADC.
Per cui non devi fare alcun controllo nell'ISR del timer.

Dovresti poi gestire l'ISR dell'ADC relativa alla fine conversione, dove sposti il buffer di lettura nel tuo array.

...facendo poi un passo ancora in avanti puoi anche impostare il DMA che usa il segnale di fine conversione dell'ADC per spostare i dati. In questo modo la CPU si sveglia solo dopo il campionamento di tutti i valori d'interesse.

...in ogni modo va bene anche la tua soluzione, che ti permette effettivamente di controllare la frequenza di campionamento.

Per conversioni molto lente potresti disattivare il reference e l'ADC ma ad ogni attivazione dovresti aspettare che il voltage reference sia stabile (settling time). I tempi di attesa sono specificati nel datasheet.
Per conversioni rapide conviene attivare l'ADC e il reference e disattivarli solo alla fine di tutte le letture.

Saluti,

Mauro

P.S.
Ho cancellato il secondo post.
Allegati:

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

  • luca.palombella
  • Autore della discussione
  • Nuovo Utente
  • Nuovo Utente
Di più
8 Anni 5 Mesi fa #3 da luca.palombella
Risposta da luca.palombella al topic msp432 - adc14 timerA
Ok diciamo che per quello che ho scritto fino adesso sono già contento ahah i passi avanti che mi dici di fare non saprei bene come fare però se mi confermi che così adc è pilotato bene allora sono soddisfatto :) poi se hai altri suggerimenti scrivi pure, sono principiante e sto imparando un po per volta

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

  • Mauro Laurenti
  • Moderatore
  • Moderatore
Di più
8 Anni 5 Mesi fa #4 da Mauro Laurenti
Risposta da Mauro Laurenti al topic msp432 - adc14 timerA
...perfetto.

Dividi e conquista.

Saluti,

Mauro

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

  • luca.palombella
  • Autore della discussione
  • Nuovo Utente
  • Nuovo Utente
Di più
8 Anni 5 Mesi fa #5 da luca.palombella
Risposta da luca.palombella al topic msp432 - adc14 timerA
Ciao volevo solo una conferma perchè (almeno per me che magari sono poco pratico) ci vuole poco per avere un comportamento diverso. Per come ho scritto io il codice quindi sto pilotando l'adc in modo che al tempo 20 inizi a campionare ripetutamente su un singolo canale e si fermi poi al tempo 800? Sono giuste anche le accensioni (ADC14CTL0 |= ADC14SC | ADC14ENC;) e gli spegnimenti a conversione ultimata (ADC14CTL0 &= ~ADC14ENC;) dell'adc? infine anche la parte di configurazione dell'acd è giusta? scusa per questi miei dubbi, vorrei solo capire se sto ragionando nel modo giusto xD

Grazie mille per l'aiuto
Luca

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

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.