Vizitator BogyDruid Postat Mai 28, 2009 Partajează Postat Mai 28, 2009 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
Vizitator BogyDruid Postat Mai 29, 2009 Partajează Postat Mai 29, 2009 forumurile romanesti, atat de utile.... Link spre comentariu
danzup Postat Mai 31, 2009 Partajează Postat Mai 31, 2009 Ca sa-ti dai seama daca e de la ADC (poate ...) ai modificat codul ca sa citesti sa zicem doar de 2 ori ADC ul ?Ca sa te putem ajuta . Link spre comentariu
srdjan Postat Mai 31, 2009 Partajează Postat Mai 31, 2009 static volatile int counter = 0; //contorce face volatile aici? nu cumva contoru sta pe loc si iti face bucla infinita la citirea adc-ului? Link spre comentariu
danzup Postat Iunie 1, 2009 Partajează Postat Iunie 1, 2009 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 Postat Iunie 1, 2009 Partajează Postat Iunie 1, 2009 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
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum