Sari la conținut
ELFORUM - Forumul electronistilor

Problema timere 16F877 18F4520


Postări Recomandate

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 de Liviu M
Link spre comentariu
  • Răspunsuri 5
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

Scuzati deranjul, am gasit buba - n-am initializat cum trebuie intreruperea TMR1. :jytuiyu

Acum merge. :da

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 de Liviu M
Link spre comentariu

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 de Liviu M
Link spre comentariu

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

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 de Liviu M
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