bodo_b Postat Decembrie 2, 2013 Partajează Postat Decembrie 2, 2013 Va salut! Am scris un cod pentru a putea masura perioada dintre doua impulsuri primite pe pinul INT0 al uC PIC24FJ128GA010. Codul l-am simulat in Proteus v 8.0 unde, la pinul INT0, am conectat o sursa de semnal ce genereaza pulsuri cu frecventa de 100 Hz. (Ca o paranteza: in locul acestei surse voi avea un circuit de detectie a trecerii prin 0 a unei sinusoide - priza, unde, dupa redresare, frecventa va fi de 100Hz.). Ca sa fie totul simplu am conectat si un display ce imi va afisa valoarea din registrul TMR1 dupa a doua intrerupere. Aici apare si problema caci valoarea afisata nu e nici pe aproape cu ceea ce ma asteptam sa vad. Pe scurt: - Frecventa imp. de tact Fosc/2 la acest tip de uC - Fosc = 32 MHz. - Prescaler-ul reg. TMR1 = 8:1 - Perioada pentru frecv. de 100Hz = 10ms - Val reg. TMR1 dupa a doua intrerupere ar trebui sa fie: 10 ms / ( 8 x 62.5 nS ) = 20. Valoarea afisata pe display este 32 ca si cand el ar fi masurat 16 ms perioada. Nu inteleg de ce... Diferenta este foarte mare. Codul este acesta: // Variable declarationssigned char i=0, gata=0;short value=0;unsigned char display[5] = {0,0,0,0,0,};// End of variable declarations// ISR declarationvoid ExtInt1() iv IVT_ADDR_INT0INTERRUPT ics ICS_AUTO { ++i; if(i == 1){ TMR1 = 0; // Reset TMR1 register T1CON = 0x8010; // Start TMR1, 8:1 PRESCALER (8 x 62.5 nS = 0.5 mS) } else if(i == 2) { T1CON = 0x0010; // Stop TMR1 value = TMR1; IEC0bits.INT0IE = 0; gata = 1; } IFS0bits.INT0IF = 0;}void main() { AD1PCFG = 0xffff; // Disable AN pins TRISA = 0; // PORTA pins PORTA = 0; // set as output, 0 logic TRISB = 0x00ff; PORTB = 0; TRISD = 0x00ff; PORTA = 0; TRISF = 0x00ff; PORTF = 0; Lcd_Init(); Lcd_Cmd(_LCD_CLEAR); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_FIRST_ROW); IPC0 = IPC0 |= 0x1001; // Select priority lvl 1 for INT0 INTCON2bits.INT0EP = 0; // Interrupt detection on rising edge IFS0bits.INT0IF = 0; // Delete IF IEC0bits.INT0IE = 1; // Activate INT0 for( ; ; ) { if(gata){ ShortToStr(value,display); Lcd_Out(1,1, display); } } } Link spre comentariu
Liviu M Postat Decembrie 2, 2013 Partajează Postat Decembrie 2, 2013 - Val reg. TMR1 dupa a doua intrerupere ar trebui sa fie: 10 ms / ( 8 x 62.5 nS ) = 20.Esti sigur ca 20 trebuie sa fie? Link spre comentariu
bodo_b Postat Decembrie 2, 2013 Autor Partajează Postat Decembrie 2, 2013 Eu asa zic.8 x 62.5 nS = 500 ns sau 0.5 ms10 ms / 0.5 ms = 20Sau nu te referi la asta ? Link spre comentariu
Liviu M Postat Decembrie 2, 2013 Partajează Postat Decembrie 2, 2013 Intre milisecunde (ms) si nanosecunde (ns) se ascund microsecundele (us).Asa ca tu trebuie sa numeri pana la 20000.Dupa ce numeri pana la 20000 (n-ar trebui sa fie o problema, timerul e parca pe 16 biti, deci poate pana la 65535), salvezi rezultatul intr-un short. Daca folosesti un compilator ANSI nici asta n-ar trebui sa fie o problema ca short e pe 16 biti (cu semn, ce-i drept, da' ia valori intre -32768 .. 32767, sau pe acolo, nu stau sa verific ultimele cifre), da' am senzatia ca folosesti mikroc la care short e pe 8 biti.Daca reprezinti 20000 in binar, iti iese ceva terminat in 0010000 (ultimii 8 biti). Ghici cat da asta in zecimal. Link spre comentariu
bodo_b Postat Decembrie 2, 2013 Autor Partajează Postat Decembrie 2, 2013 Corect.Chiar mi-a scapat urmatorul ordin ... (us). De aia am si ales char (8 biti) pentru ca ma gandeam ca incape dar ... deh.Multumesc frumos de ajutor! 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