Kreator Postat Noiembrie 22, 2018 Partajează Postat Noiembrie 22, 2018 Hi all! Ma confrunt cu urmatoarea problema la un PIC16F1824 si anume intreruperea INT (acea care se produce la schimbarea starii pinului RA2) nu se produce. Codul de initializare a PIC-ului este: sub procedure initiere() SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH) OSCCON = %11111111 ANSELA = %00000000 ' All I/O pins are configured as digital ANSELC = %00000000 CM1CON0 = %00000000 ' Disbale comparators CM2CON0 = %00000000 ' Disbale comparators TRISA = %11111111 ' PORTA All Inputs, Except xxx TRISC = %00000000 ' PORTC All Outputs WPUA = %00111111 ' Pull-ups to be enabled APFCON0.SDOSEL = 0 APFCON0.SSSEL = 1 INTCON.GIE = 1 ' Enables all unmasked interrupts INTCON.PEIE = 0 ' Disables all peripheral interrupts INTCON.T0IE = 1 ' Enables the TMR0 interrupt INTCON.INTE = 0 ' Enables the RA2/INT external interrupt INTCON.IOCIE = 0 ' Disables the PORTA change interrupt INTCON.T0IF = 0 ' TMR0 register did not overflow INTCON.INTF = 0 ' The RA2/INT external interrupt did not occur INTCON.IOCIF = 0 ' None of the PORTA <5:0> pins have changed state OPTION_REG.WUE = 0 ' PORTA pull-ups are enabled by individual port latch values OPTION_REG.INTEDG = 1 ' Interrupt on rising/falling edge of RA2/INT pin OPTION_REG.T0CS = 0 ' set Timer0 clock source to internal OPTION_REG.T0SE = 1 ' Increment on high-to-low transition on RA2/T0CKI pin OPTION_REG.PSA = 0 ' asign prescaler to Timer 0 OPTION_REG.PS2 = 1 ' asign prescaler value OPTION_REG.PS1 = 1 ' asign prescaler value OPTION_REG.PS0 = 1 ' asign prescaler value end sub sub procedure Interrupt() iv 0x0004 ics ICS_AUTO dp.0 = not dp.0 INTCON.INTE = 0 INTCON.T0IF = 0 end sub main: ' Main program initiere() while TRUE citire() prepare_to_show_hour(h1, h0, m1, m0, dp, al ) afiseaza() wend end. Pentru INTCON.T0IE = 1 si INTCON.INTE = 0 adica sa se produca evenimentul pt TMR0 totul e OK, programul functioneaza OK (dp isi schimba starea) deci programul e OK. Problema este la combinatia INTCON.T0IE = 0 si INTCON.INTE = 1 (adica la schimbarea starii lui RA2): dp nu-si schimba starea. Unde gresesc, sau ce nu am configutar OK? Va multumesc! Link spre comentariu
mars01 Postat Noiembrie 22, 2018 Partajează Postat Noiembrie 22, 2018 (editat) Salut, Fara a spune ca rezolv problema ta, vreau sa fac cateva mentiuni: - cand faci initializarea hardware ordinea este asa: 1. oscilator 2. porturi 3. configurare alte periferice 4. configurare timere, intreruperi 5. la final faci enable la intreruperi si ma refer la bitul GIE In cazul tau, faci enable la intreruperea externa chiar in intrerupere. Ai un motiv pentru aceasta? Pentru ca ar fi fezabil doar daca vrei sa faci un fel de chain de intreruperi, gen in cazul in care apare intreruperea timer, doar atunci faci enable la inreruperea externa si cand se intampla intreruperea externa executi ceva si apoi o dezactivezi. Oricum acest cod nu apare in ce ai postat asa ca presupun ca ai facut o greseala. Intreruperea externa o activezi in afara rutinei de intrrupere (ma refer la bitul INTE) - rutina de intrerupere este una singura pentru toate intreruperile. Trebuie sa testezi in functia chemata de intreruperi care intrerupere a facut "call" la functia de intrerupere. Nu stiu sintaxa Basic dar ceva de genul: sub procedure Interrupt() iv 0x0004 ics ICS_AUTO // atentie C Code // daca modulul intrerupere externa este activat si daca tocmai a avut loc o intrerupere externa executa if (INTCON.INTE && INTCON.INTF){ // flagul pentru intr. ext trebuie facut zero manual INTCON.INTF = 0 // codul tau in caz ca ai intrerupere externa } // daca timer0 este activat si daca tocmai a avut loc o intrerupere generata de overflow al Timer0 if (INTCON.T0IE && INTCON.T0IF){ // flagul pentru intreruperea data de TMR0 trebuie facut zero in mod manual INTCON.T0IF = 0 // codul tau cand ai intrerupere data de TMR0 } // end C code end sub Nu am verificat secventa ta de initializare. Editat Noiembrie 22, 2018 de mars01 Link spre comentariu
Kreator Postat Noiembrie 22, 2018 Autor Partajează Postat Noiembrie 22, 2018 Multumesc @mars01 ca in totdeauna profesor doctor! Intradevar, eu vroiam sa sterg flagul pt intreruperea externa (INF) dar din neatentie stergeam bitul INTE (dezactivam intreruperea) Acum cu ajutorul tau merge OK! Multumesc mult! Link spre comentariu
mars01 Postat Noiembrie 22, 2018 Partajează Postat Noiembrie 22, 2018 Am gresit in postul precedent cand am spus ca activai intreruperea externa in functia de intrerupere. De fapt o dezactivai. Link spre comentariu
Liviu M Postat Noiembrie 23, 2018 Partajează Postat Noiembrie 23, 2018 10 hours ago, mars01 said: De fapt o dezactivai. Ceea ce, de altfel, n-are nici un efect, pentru ca la intrarea in rutina de servire a intreruperii GIE e facut 0 automat: Quote The following events happen when an interrupt event occurs while the GIE bit is set: • Current prefetched instruction is flushed • GIE bit is cleared ... Link spre comentariu
mars01 Postat Noiembrie 23, 2018 Partajează Postat Noiembrie 23, 2018 (editat) 10 hours ago, Liviu M said: Ceea ce, de altfel, n-are nici un efect, pentru ca la intrarea in rutina de servire a intreruperii GIE e facut 0 automat: Salut Liviu, ma bucur sa vad ca mai postezi pe aici In ceea ce ai postat tu de fapt m-am corectat pentru afirmatia precedenta aceleia, in care am spus ca " faci enable la intreruperea externa chiar in intrerupere" ceea ce era incorect datorita faptului ca bitul INTE era sters si nu setat. Bun addagio, totusi! Editat Noiembrie 23, 2018 de mars01 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