Liviu M Postat Iulie 21, 2014 Partajează Postat Iulie 21, 2014 (editat) Salut,butonez momentan la un programel pentru 16F877 (ma rog, mai multe controllere selectabile din configuratii) in care:- folosesc TMR1 + quarz de 32768 pe post de RTC- folosesc TMR2 ca sa generez un semnal PWM (pentru controlat diverse - motoare, LED-uri, ce-mi mai trece prin cap).Programul functioneaza binisor pana cand vreu sa dezactivez TMR2 (sa opresc PWM-ul), moment in care se opreste si ceasul. Cand repornesc TMR2, reporneste si ceasul bine merci de unde ramasese.Pentru ca in timpul asta alte bucati functioneaza (am si niste butoane care merg in continuare) si pentru ca oscilatorul de la pinii TMR1 functioneaza in continuare (am pus osciloscopul pe pini), tind sa cred ca se intampla ceva ciudat cu intreruperile, dar reactivarea lor dupa TMR2ON = 0 nu ajuta la nimic.Intrebarea mea e, a mai patit/auzit cineva de o asemenea problema si stie ce fac aiurea? Pentru ca sunt destul de convins ca e de la mine, pentru ca am testat si cu un 18F4520 si se intampla fix acelasi lucru.Nu stiu ce bucati de cod as putea pune ca sa ajut "diagnoza".Partea de initializare: //CCP1-PWM1 CCP1CON = 0x0C; // 1100 = PWM mode, P1A, P1C active-high; P1B, P1D active-high //T2CON used by PWM modules T2CON = 0x01; //prescaler 1:4; TMR2OFF, postscale 1:1 PR2 = PR2_VALUE; iMaxPwmDC = (PR2 + 1) * 4 - 1; ucDCStep = iMaxPwmDC / 10; //10% duty cycle step // Timer1 - ceas TMR1L = 0x00; TMR1H = 0x80; // => aprox. 1 sec. T1CON = 0b00001111; // activate the timer 0 // Interrupts - TMR2 (PWM) & CMP TMR2IE = 1; // TMR2 to PR2 Match Interrupt Enable bit#if defined (_PIC18F4520_H_) CMIE = 1; // PIR2<6>#endif PEIE = 1; // Peripheral Interrupt Enable bit Prelucrarea intreruperilor if (TMR2IF && TMR2IE) { //TMR2 to PR2 match occurred (must be cleared in software) Flags.PWMUpdate = 1; TMR2IF = 0; } if(TMR1IF && TMR1ON) /*ceas*/ { T1CON = 0b00001110; // stop the timer TMR1L = 0x00; TMR1H = 0x80; // ~ 1 sec T1CON = 0b00001111; // start the timer Flags.ClkInt = 1; TMR1IF = 0; } Functiile de activare/dezactivare PWM void pwmStart(void) { TMR2 = 0; TMR2IF = 0; T2CONbits.TMR2ON = 1; //T2CON = 0x05; //prescaler 1:4; TMR2ON, postscale 1:1 PWM_EN = 1;}void pwmStop(void) { PWM_EN = 0; T2CONbits.TMR2ON = 0; //n-am idee de ce, dar cand opresc TMR2 nu mai merge ceasul.} Raman recunoscator pentru orice idee. LE Definitia lui PWM_EN (e de la 18F4520, ca pe asta il am activ acum in mplabx) #define PWM_EN LATCbits.LATC5 Editat Iulie 21, 2014 de Liviu M Link spre comentariu
Liviu M Postat Iulie 21, 2014 Autor Partajează Postat Iulie 21, 2014 (editat) Scuzati deranjul, am gasit buba - n-am initializat cum trebuie intreruperea TMR1. Acum merge. Interesant e ca parea sa mearga. Habar n-am de ce. LE Am gasit, testul if(TMR1IF && TMR1ON) /*ceas*/ e gresit, trebuie sa fie if(TMR1IF && TMR1IE) /*ceas*/ Editat Iulie 21, 2014 de Liviu M Link spre comentariu
sofian Postat Iulie 22, 2014 Partajează Postat Iulie 22, 2014 ptr o precizie mai buna nu mai opri timerul if(TMR1IF && TMR1IE) /*ceas*/{if(TMR1H && 0x80){Flags.ClkInt = 1;}TMR1IF = 0;} Link spre comentariu
Liviu M Postat Iulie 22, 2014 Autor Partajează Postat Iulie 22, 2014 (editat) Multumesc de sfat, da' cred ca nu functioneaza. Cand intra in intreruperi, TMR1H == TMR1L == 0 (generararea de intreruperi se intampla la overflow, dupa care registrii-s 0), asa ca cred ca testul if(TMR1H && 0x80) nu e niciodata adevarat. Ce fac eu in intrerupere e "reinitializarea" registrilor timerului cu valoarea de start (0x8000), altfel numara de la 0 si nu mai are nici o treaba cu secundele. Daca oprire/pornirea timerului la scriere e necesara sau nu, nu mai stiu exact, da' parca asa scrie in data-sheet. Verific. LE Din data-sheetul lui 16F877A 6.4.1 READING AND WRITING TIMER1 INASYNCHRONOUS COUNTER MODE Reading TMR1H or TMR1L while the timer is running... ...For writes, it is recommended that the user simply stopthe timer and write the desired values. Editat Iulie 22, 2014 de Liviu M Link spre comentariu
sofian Postat Iulie 23, 2014 Partajează Postat Iulie 23, 2014 Asa este nu functioneaza cum am zis eu trebuie sa setezi doar bitul 7 din TMR1H, asa timerul functioneaza si ai precizie mare cind reinitializezi timerul este posibil ca in TMR1L sa fie deja o valoare, deci pierzi din timp, valoare care se poate calcula in "C" depinzi de ce face compilatorul, adica cite instructiuni sunt rulate pina sa reinitializezi timerul Link spre comentariu
Liviu M Postat Iulie 23, 2014 Autor Partajează Postat Iulie 23, 2014 (editat) Stiu si ai dreptate, dar cel putin in aplicatia asta precizia e irelevanta. In aplicatia in care ar fi relevant am un modul DCC77 care regleaza ceasul o data pe zi. Altfel, ar fi probabil cateva minute pe luna abatere. Nici o nenorocire. Problema mea nu era cum fac ceasul sa mearga cat mai exact, ci de ce mi se opreste ceasul cand opresc PWM. Raspunsul e simplu - pentru ca era prost initializat. Editat Iulie 23, 2014 de Liviu M 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