Sari la conținut
ELFORUM - Forumul electronistilor

PIC 24FJ128GA010 problema intrerupere


Postări Recomandate

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
  • Răspunsuri 4
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Zile populare

Top autori în acest subiect

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. :rade:

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