Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

ADC e TIMER che fanno a cazzotti

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] ADC e TIMER che fanno a cazzotti

Messaggioda Foto Utentedadduni » 19 feb 2018, 18:09

salve a tutti,
vi faccio una domanda particolare perché non mi era mai capiutata una cosa simile.
Sto lavorando su un AtTiny 817, configuro l'ADC come freerun mode e con le inteurrupt ad ogni conversione:funziona.
Apro un nuovo programma per provare la configurazione del timer che genera un interrupt quando va in overflow: funziona.
Metto tutto in un programma solo... l'ADC non genera più l'interrupt! mi basta commentare l'inizializzazione del timer per far funzionare l'adc.

Secondo voi dove può stare il problema?
Davide
Ultima modifica di Foto UtenteWALTERmwp il 20 feb 2018, 1:51, modificato 1 volta in totale.
Motivazione: Spostato da "Elettronica generale" a quì
Avatar utente
Foto Utentedadduni
2.073 2 7 12
Expert EY
Expert EY
 
Messaggi: 1370
Iscritto il: 23 mag 2014, 16:26

1
voti

[2] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto Utentexyz » 19 feb 2018, 22:07

Impossibile dire nulla senza codice, non specifichi neanche quali timer usi e quale porta ADC e come viene programmato se direttamente in C o usi API particolari come quelle di Arduino o programmi direttamente in assembler o altro.
Avatar utente
Foto Utentexyz
6.864 2 4 6
G.Master EY
G.Master EY
 
Messaggi: 1778
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin

1
voti

[3] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto UtenteFedhman » 19 feb 2018, 23:20

Forse il timer si impadronisce dei registri di interrupt usati dall'ADC. Leggi bene il datasheet, alla sezioni interrupt, timer e ADC - a volte per risovere problemi simili sugli interrupt serve pure leggere qualcos'altro*. Sii puntiglioso!

*qualcos'altro potrebbero essere i registri che vanno a configurare come sono abilitati gli interrupt. Talvolta non sono descritti nella sezione degli interrupt.
I don't fight weather - Woodrow W. Smith
Avatar utente
Foto UtenteFedhman
5.195 2 9 13
Master
Master
 
Messaggi: 483
Iscritto il: 4 giu 2013, 14:05
Località: Augusta Taurinorum

1
voti

[4] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto Utenteharpefalcata » 20 feb 2018, 9:48

Oppure, più semplicemente i timer sono programmati per avere un intervallo troppo ristretto e generano un proliferare di interrupt tale, che quelli dell'ADC, anche se presenti, vengono completamente ignorati.
Avatar utente
Foto Utenteharpefalcata
326 1 3 6
Stabilizzato
Stabilizzato
 
Messaggi: 422
Iscritto il: 28 lug 2015, 21:03

0
voti

[5] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto Utentedadduni » 20 feb 2018, 15:26

Codice: Seleziona tutto
int8_t TIMER_0_init()
{

   //TCA0.SINGLE.CMP0 = 0xffff; /* Compare Register 0: 0x0 */

   // TCA0.SINGLE.CMP1 = 0x0; /* Compare Register 1: 0x0 */

   // TCA0.SINGLE.CMP2 = 0x0; /* Compare Register 2: 0x0 */

   TCA0.SINGLE.CNT = 0x0000; /* Count: 0xff */

   TCA0.SINGLE.CTRLB = 0 << TCA_SINGLE_ALUPD_bp       /* Auto Lock Update: disabled */
                       | 0 << TCA_SINGLE_CMP0EN_bp    /* Compare 0 Enable: enabled */
                       | 0 << TCA_SINGLE_CMP1EN_bp    /* Compare 1 Enable: disabled */
                       | 0 << TCA_SINGLE_CMP2EN_bp    /* Compare 2 Enable: disabled */
                       | TCA_SINGLE_WGMODE_NORMAL_gc; /*  */

   // TCA0.SINGLE.CTRLC = 0 << TCA_SINGLE_CMP0OV_bp /* Compare 0 Waveform Output Value: disabled */
   //       | 0 << TCA_SINGLE_CMP1OV_bp /* Compare 1 Waveform Output Value: disabled */
   //       | 0 << TCA_SINGLE_CMP2OV_bp; /* Compare 2 Waveform Output Value: disabled */

   TCA0.SINGLE.DBGCTRL = 1 << TCA_SINGLE_DBGRUN_bp; /* Debug Run: enabled */

   // TCA0.SINGLE.EVCTRL = 0 << TCA_SINGLE_CNTEI_bp /* Count on Event Input: disabled */
   //       | TCA_SINGLE_EVACT_POSEDGE_gc; /* Count on positive edge event */

   TCA0.SINGLE.INTCTRL = 0 << TCA_SINGLE_CMP0_bp   /* Compare 0 Interrupt: enabled */
                         | 0 << TCA_SINGLE_CMP1_bp /* Compare 1 Interrupt: disabled */
                         | 0 << TCA_SINGLE_CMP2_bp /* Compare 2 Interrupt: disabled */
                         | 1 << TCA_SINGLE_OVF_bp; /* Overflow Interrupt: disabled */
   //TCA0.SINGLE.INTFLAGS |= 1<<0;
   TCA0.SINGLE.PER = 0x0f00; /* Period: 0xffff */

   TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc /* System Clock / 1024 */
                       | 1 << TCA_SINGLE_ENABLE_bp; /* Module Enable: enabled */

   return 0;
}

ho impostato così il timer A. Setto un valore in PER (period) che dovrebbe essere il massimo a cui arriva e poi si resetta generando un overflow interrupt.
Il codice di inizializzazione è generato da Atmel START che è una interfaccia grafica per impostare i parametri nei registri, sono comunque stati controllati e a me sembrano giusti.
Voi ci vedete qualcosa che non torna?
Avatar utente
Foto Utentedadduni
2.073 2 7 12
Expert EY
Expert EY
 
Messaggi: 1370
Iscritto il: 23 mag 2014, 16:26

0
voti

[6] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto UtenteEcoTan » 20 feb 2018, 17:04

non è che hai abilitato anche l'interrupt di compare 0 mentre l'istruzione che imposta il registro compare 0 è commentata?
Avatar utente
Foto UtenteEcoTan
7.720 4 12 13
Expert EY
Expert EY
 
Messaggi: 5420
Iscritto il: 29 gen 2014, 8:54

1
voti

[7] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto Utentedadduni » 20 feb 2018, 17:32

mistero risolto!
ogni volta che viene generata un'interrupt, deve essere resettata a mano la flag. Pensavo che per l'overlow azzerandosi il timer si resettasse da solo ma a quanto pare no, nel capitolo dei timer non c'era scritto ma stava nel capitolo delle interrupt :twisted:
se tutto va come deve settimana prossima potrebbe uscire un articoletto :mrgreen:
Avatar utente
Foto Utentedadduni
2.073 2 7 12
Expert EY
Expert EY
 
Messaggi: 1370
Iscritto il: 23 mag 2014, 16:26

0
voti

[8] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto UtenteFedhman » 20 feb 2018, 17:41

dadduni ha scritto:[..] nel capitolo dei timer non c'era scritto ma stava nel capitolo delle interrupt :twisted:


Tipico! :lol:
I don't fight weather - Woodrow W. Smith
Avatar utente
Foto UtenteFedhman
5.195 2 9 13
Master
Master
 
Messaggi: 483
Iscritto il: 4 giu 2013, 14:05
Località: Augusta Taurinorum

0
voti

[9] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto Utentedadduni » 22 feb 2018, 19:48

ho aggiornamenti e mi servirebbero chiarimenti se potete!
questa è la funzione handler dell'interrupt dell'ADC
Codice: Seleziona tutto
ISR(ADC0_RESRDY_vect)
{   rms_buffer[rms_buffer_pointer]= ADC0.RES;
   rms_buffer_pointer++;
   /* The interrupt flag has to be cleared manually */
   ADC0.INTFLAGS = ADC_RESRDY_bm;
   ADC0.COMMAND=1;
}

Scrivo in un buffer circolare, resetto la interrupt flag e faccio ripartire la nuova conversione. A voi sembra una routine troppo lunga? perché mi sono accorto che se la lascio così la interrupt del timer non viene proprio eseguita invece se tolgo i comandi che scrivono nel buffer il timer funziona perfettamente. Voi che ne pensate? pensavo di poter scrivere in un paio di registri in una interrupt!

PS non ha senso però che nella routine faccio alzare un bit che segnala la fine della conversione perché poi dovrei fare polling nel main a questo punto tanto vale la pena fare direttamente polling e questa interrupt non generarla nemmeno!
Avatar utente
Foto Utentedadduni
2.073 2 7 12
Expert EY
Expert EY
 
Messaggi: 1370
Iscritto il: 23 mag 2014, 16:26

1
voti

[10] Re: ADC e TIMER che fanno a cazzotti

Messaggioda Foto Utentexyz » 22 feb 2018, 21:21

Quello non è un buffer circolare. Manca il controllo del limite massimo nell'indice e molto probabilmente hai un buffer overflow con conseguenze deleterie nel codice. Devi mettere un test sull'indice, se raggiunge il massimo azzerarlo.

Un trucco per evitare il test è creare il buffer con un numero di elementi uguale a una potenza di 2, quando incrementi l'indice fai un "and" binario (&) col numero numero di elementi meno 1. Ad esempio se il buffer ha 16 (2^4) elementi, quando incrementi l'indice fai:

Codice: Seleziona tutto
rms_buffer_pointer = (rms_buffer_pointer + 1) & 0x0F
Avatar utente
Foto Utentexyz
6.864 2 4 6
G.Master EY
G.Master EY
 
Messaggi: 1778
Iscritto il: 5 dic 2009, 18:37
Località: Italy Turin


Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 4 ospiti