MSP430, Microcontrollori 16 bit Ultra Low Power

MSP430F233 - adc

  • Mary
  • Autore della discussione
  • Nuovo Utente
  • Nuovo Utente
Di più
9 Anni 8 Mesi fa - 9 Anni 8 Mesi fa #1 da Mary
MSP430F233 - adc è stato creato da Mary
Buongiorno a tutti,

apro questa discussione perché è la prima volta che provo a programmare un microcontrollore (MSP430F233). Ho provato a realizzare il codice ma il programma non funziona e non riesco a capire dov'è l'errore (anche se suppongo che sia nella parte del codice riguardante l'ADC).

Lo scopo del codice sarebbe il seguente: al microcontrollore arriva in ingresso un segnale ad onda quadra variabile in ampiezza; al superamento di una determinata soglia (tensione che fornisco dall'esterno) il comparatore del micro dovrebbe attivare l'ADC: prendo 16 campioni del segnale, e li scrivo in un vettore di cui vado a svolgere la media; in seguito confronto la media calcolata con ms (come posso dichiararla uguale al 10% della VCC?) e in base al confronto attivo o disattivo l'uscita di alcune porte.

questo è il codice che ho scritto:
Code:
#include <msp430.h> #define n 16 volatile unsigned int cont=0; volatile float reg[n]; volatile float ms=0.1; int main(void) { static unsigned int j; static float me=0; WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer /*Initialization of the comparator_A*/ CACTL1 = CAON | CAREF_0 | CARSEL; // comparator_A on, external reference, Vref to - terminal CACTL2 = P2CA4 | P2CA3 | P2CA2 | P2CA1; // input on CA1 (+ terminal) and referenca on CA7 (- terminal) /*Initialization of the Port pins*/ P2DIR |= 0x0004; // P2.2 as output P2SEL |= 0x0004; // P2.2 = CAOUT P5DIR |= 0x000E; // P5.0 as input // P5.1, P5.2, P5.3 as output /*Initialization of the ADC*/ P6SEL |= 0x0001; // P6.0 = A0, input P5DIR |= 0x0040; // P5.6 option selected P5SEL |= 0x0040; // P5.6 = ACLK ADC12CTL0 = ADC12ON + SHT0_2 + MSC; // turn on ADC, 16 ADC12CLK cycles ADC12CTL1 = CONSEQ_2 + SHP; // repeat-single-channel, clksource=ACLK, S&H pulse-mode ADC12MCTL0 = INCH_0 + SREF_0; // input_channel=A0, Vref+=AVcc; Vref-=AVss ADC12IE = 0x01; // enable interrupt ADC12CTL0 |= ENC; // enable conversion for(;;) { do {} while(!(CAOUT)); // wait until CA output is HIGH __delay_cycles(4); // delay=122us ADC12CTL0 |= ADC12SC; // start conversion __bis_SR_register(LPM0_bits+GIE); // enter LPM3, enable interrupt for(j=0;j<16;j++) // me me+=reg[j]; me=me/16; if(me<ms) { P5OUT |= 0x0002; // P5.1 ON cont++; } else { P5OUT &= ~0x0002; // P5.1 OFF if(cont>0) cont--; } if(cont>1 && cont<6) // if 1<cont<=5 P5.2 ON P5OUT |= 0x0004; else P5OUT &= ~0x0004; // else P5.2 OFF if(cont>5) // if cont>5 P5.3 ON P5OUT |= 0x0008; else P5OUT &= ~0x0008; // else P5.3 OFF } return 0; } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = ADC12_VECTOR __interrupt void ADC12_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12_ISR (void) #else #error Compiler not supported! #endif { static unsigned int i=0; reg[i] = ADC12MEM0; // Move results in a 16-element vector i = (i+1)%n; if (i == 0) {LPM0_EXIT;} }

Vi ringrazio in anticipo per l'aiuto!!!

Buona giornata
Ultima Modifica 9 Anni 8 Mesi fa da Mauro Laurenti.

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

  • Mauro Laurenti
  • Moderatore
  • Moderatore
Di più
9 Anni 8 Mesi fa #2 da Mauro Laurenti
Risposta da Mauro Laurenti al topic MSP430F233 - adc
Ciao Mary,

benvenuta nel Forum!

Non ho visto tutti i dettagli sul programma, ma qualche nota di quello che ho visto:

*) Non mi sembra di vedere l'inizializzazione del clock

*) La seguente media ti potrebbe creare problemi:

for(j=0;j<16;j++)
me+=reg[j];
me=me/16;

ad ogni interrupt che legge un valore fai il ciclo sul buffer reg.

*) Nella funzione main non c'e' bisogno di avere variabili static. Infatti dalla funzione main non esci mai.
Se esci il programma e' terminato.

*) relativamente all'ISR dove scrivi :

i = (i+1)%n;

Personalmente farei uso di un contatore e non del resto. quando i diventa grande avrai bisogno sempre di piu' cicli di clock. Inoltre potresti avere problemi al passaggio da 0xFFFF a 0x0000. Potresti perdere una misura (ma su questo non ci ho riflettuto molto ma e' un rischio che dovresti verificare).

Per quanto riguarda l'esempio cercherei di dividerlo in piu' parti.
Farei funzionare prima la parte del comparatore.
Poi userei il solo ADC per fare 16 misure e media.
poi unirei il programma...

Che cosa ti ha portato a scegliere l'MSP430F233?


Saluti,

Mauro
I seguenti utenti hanno detto grazie : Mary

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

  • Mary
  • Autore della discussione
  • Nuovo Utente
  • Nuovo Utente
Di più
9 Anni 8 Mesi fa #3 da Mary
Risposta da Mary al topic MSP430F233 - adc
Ciao Mauro!

Ti ringrazio tanto per i consigli per il mio programma!

Intanto mi sono accorta anche di avere fatto un errore per quanto riguarda l'inizializzazione del vettore reg[n]. Ho visto infatti che se lo inizializzo come "volatile unsigned int reg[n];" anziché come float il programma non va più in loop.

Poi ho dovuto (non so se sia corretto) utilizzare l'istruzione "__bic_SR_register_on_exit(LPM0_bits+GIE);" alla fine dell'ISR perché altrimenti il programma continuava a svolgere l'interruzione e non rientrava nel main.

Per quanto riguarda l'inizializzazione del clock non ci avevo pensato perché pensavo che fosse sufficiente inizializzare correttamente il registro ADC12CTL1 dal momento che non dovevo far compiere al clock nessuna istruzione particolare.

Comunque ho scelto l'MSP430F233 perché mi sembrava abbastanza completo come modello per fare degli esperimenti di programmazione.

Adesso cercherò di mettere in pratica i tuoi consigli così da vedere se finalmente sarò in grado di far funzionare correttamente il programma!

Per ora ti ringrazio,

saluti,

Maria

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

  • Mauro Laurenti
  • Moderatore
  • Moderatore
Di più
9 Anni 8 Mesi fa #4 da Mauro Laurenti
Risposta da Mauro Laurenti al topic MSP430F233 - adc
Ciao Mary,

Relativamente alla funzione intrinseca __bic_SR_register_on_exit(LPM0_bits+GIE);

andrebbe scritta formalmente come __bic_SR_register_on_exit(LPM0_bits);
Serve per cambiare il valore dello status register contenuto nello stack, visto che lo status register contiene appunto il valore low power a cui bisogna tornare dopo l'interrupt. Per evitare di rimanere in LPM0 bisogna cambiarlo in AM, questo permette di eseguire le istruzioni successive...
Trovi maggiori dettagli nel seguente capitolo del corso MSP430 .

Per la scelta dell'MSP430F233 e' ok, ma visto che probabilmente stai lavorando su un progetto universitario (In Italia gli MSP430 sono usati prevalentemente nelle universita'...) anche la famiglia FRAM poteva essere una buona scelta visto che contiene il fiore all'occhiello della tecnologia di memorie non volatili.

Cosa stai progettando con gli MSP430?

Saluti,

Mauro
I seguenti utenti hanno detto grazie : Mary

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

  • Mary
  • Autore della discussione
  • Nuovo Utente
  • Nuovo Utente
Di più
9 Anni 8 Mesi fa #5 da Mary
Risposta da Mary al topic MSP430F233 - adc
Ciao Mauro,

volevo comunicarti che finalmente ora il mio progetto funziona!!

I tuoi consigli sono stati veramente utili!!

Come correttamente hai ipotizzato sto lavorando ad un progetto universitario. Il progetto consiste nella realizzazione di un firmware che rilevi (generando degli allarmi) il passaggio di un oggetto attraverso una barriera ottica a luce NIR impulsata.

Comunque valuterò la possibilità di utilizzare un microcontrollore della famiglia FRAM in un eventuale progetto futuro.

Per ora ti ringrazio!!!

Saluti,

Maria

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.

Forum - Ultimi messaggi