Sari la conținut
ELFORUM - Forumul electronistilor

Citiri consecutive de pe ADC la ATmega168


Vizitator BogyDruid

Postări Recomandate

Vizitator BogyDruid

am si eu o problema la programarea unor intreruperi ADC pe un ATmega168.

 

proiectul este urmatorul:

 

Am un server WEB care la interval de 1 minut trimite o pagina la client. In acea pagina prezint informatia masurata la ADC in felul urmator. In intervalul de 1 minut pana sa fie trimisa pagina, microcontrolerul trebuie sa masoare 200 de esantioane de pe pinul ADC, sa gaseasca maximul si minimul intre ele, sa faca a=max-min si sa returneze un log_10(a). Acest rezultat va fi inclus in pagina care va fi trimisa clientului.

 

Problema este ca folosind intreruperile ADC nu se mai incarca pagina deloc. Imi ramane la Waiting for . Nu cred ca ajunge la chestiile de TCP...

Codul meu arata cam asa:

 

static volatile int counter = 0; //contorstatic int info_read = 0; //variabila ce imi indica faptul ca functia de prelucrare vector de esantioane a avut successtatic int vector[200]; //vectorul ce va contine cele 200 de esantioanestatic int array_need_filled; //variabila ce determina daca incep sau  nu preluarea cele 200 de esantioanestatic int realADCvalue; //variabila ce va contine rezultatul log_10(a) ce va fi mai apoi pus pe pagina WEB//functia de intrerupere ADC, aici umplu vectorul cu valorile masurate pe pinul ADC, incrementez contorul, reinitializez //masurarea pe ADC, cand contorul ajunge la 200 opresc ADCISR(ADC_vect){    vector[counter] = ADCW;    counter = counter + 1;    if (counter < 200)    {        ADCSRA = 0xCB;    }else{             ADCSRA = 0x00;         }}//functia ce prelucreaza cele 200 de esantioane si returneaza o valoare ce va fi scrisa in pagina WEBint realADC(void){    int j=0,a=0;    int max=vector[0],min=vector[0];    for(j=0;j<200;j++)    {      if(vector[j] > max)      {         max = vector[j];      }else{            if(vector[j] < min)            {               min = vector[j];            }         }    }    a=max-min;           info_read = 1; //new line added here    return log10_approx(a);     }int main(void){             //initializez ADCul, ADC ON, ADC Interrupts ON      ADMUX = 0x43;      ADCSRA = 0x8B;      need_array_filled = 1;//am nevoie sa preiau cele 200 de esantioanewhile(1){          //incep preluarea esantioanelor prin activarea masuratorii cu bitul ADSC          if(need_array_filled)            {               counter = 0;               ADCSRA |= 0x40;               need_array_filled = 0;            }               //daca contorul a ajuns la 200 atunci prelucreaza datele si returneaza valoarea            if(counter == 200)            {               realADCvalue = realADC();               }            //daca datele au fost prelucrate atunci e nevoie de urmatoarea masuratoare de 200 de esantioane            if(info_read)            {               need_array_filled = 1;               info_read = 0;            } ...TCP stuff...    }}
Link spre comentariu
  • Răspunsuri 5
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • danzup

    2

  • srdjan

    1

static volatile int counter = 0; //contorce face volatile aici? nu cumva contoru sta pe loc si iti face bucla infinita la citirea adc-ului?

La ceva asemanator m-am gandit si eu ... dar se pare ca userul asta a abandonat prezenta pe elforum Dar nu la linia care ai zis tu !El face incrementare de contor mai jos in program ( linia de cod mentionata de tine @srdjan numai declara corect o variabila ) !Eu ma refeream la timpul necesar executie citirii care ar putea depasi orice altceva.Ne-ar mai ajuta daca ne-ar spune ce intrerupere foloseste pentru partea de TCP/IP adica care intrerupere e mai prioritara !ca nu rezulta ....
Link spre comentariu
Vizitator BogyDruid

am citit undeva ca pentru a folosi o variabile (in cazul de fata counter) atat in main() cat si in intrerupere trebuie declarata volatile.dupa mai multe incercari am ajuns la asa ceva:

uint8_t need_array_filled;unsigned int realADCvalue;volatile int contor;static unsigned int valori[200];ISR(ADC_vect){	//valori[contor] = ADCW;	//linie comentata deoarece necomentata provoaca stagnarea programului	if (contor < 200)	{		ADCSRA = 0xCB;		sei();		contor = contor + 1;	}else{			ADCSRA = 0x00;		 }}unsigned int realADC(void){	 int j=0,a=0;	 int max = 1023, min = 130;         // liniile de mai jos comentate deoarece daca in intrerupere am comentat initializarea vectorului valori nu am cu ce lucra aici        // manual am creat un max si min	 /*int max=valori[0],min=valori[0];	 for(j=0;j<200;j++)	 {		if(valori[j] > max)		{			max = valori[j];		}else{				if(valori[j] < min)				{					min = valori[j];				}			}	 }*/	 a=max-min;	 	 	 return log10_approx(a);	}int main(void){        		ADMUX = 0x43;		ADCSRA = 0x8B;                realADCvalue = 0;                need_array_filled = 1;                while(1){                                if(need_array_filled)				{					contor = 0;					ADCSRA |= 0x40;					need_array_filled = 0;				}				if(contor >= 199)				{					realADCvalue = realADC();					}....tcp....                }}
valoarea de care am nevoie ar trebui sa se afle in realADCvalue. in modul cum e prezentat codul de mai sus cu max si min dat de mine primesc un rezultat de 3446 ceea ce nu e corect. am vazut ca acest rezultat difera de la 32000 nu stiu cat la -32000 nu stiu cat in functie de cum declar variabilele globale. e total aiurea.in concluzie de ce nu pot face valori[contor] = ADCW; in intrerupere?? de ce se opreste programu?

Ne-ar mai ajuta daca ne-ar spune ce intrerupere foloseste pentru partea de TCP/IP adica care intrerupere e mai prioritara !

daca intreruperea de tcp era prioritara cred ca nu mai tinea pagina in Waiting for in cazul in care intreruperea de ADC era problematica ci o afisa si in loc de rezultatul dorit baga o eroare sau ceva nu?
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări