Jump to content
ELFORUM - Forumul Electronistilor
Sign in to follow this  
moro

Cum bag registrii TMR1H si TMR1L intr-o singura variabila?

Recommended Posts

Va salut, am un pic16f887 caruia pe pin RC2 ( CCP1) ii aplic un semnal dreptunghiular pwm, caruia vreau sa-i citesc frecventa si s-o afisez pe un display

Am incercat sa unesc cei doi registrii din timer1 intr-o singura variabila "counter" care apoi s-o afisez pe un display 16x2 lcd

de test am pus un output pe pinul RB0 care sa fie updatat de intreruperea pe high edge si vad ca ccp-ul functioneaza ok, in sensul ca daca aplic 1526hz pe RC2, tot atat citesc si pe RB0, singura problema ramane cu timer-ul ala.

Sincer asta ar fi primul proiect cu timere....

 

void main() {T1CON=0X85;       // timer at Fosc/4 with 1:1 prescalerCCP1CON=0X05;       //     Capture mode, every rising edgeINTCON.GIE=1;  // enable global interruptsINTCON.PEIE=1; // enable peripherical interruptsPIE1.CCP1IE=1; // enable interrupts from CCP1 moduletrisc.rc2=1;trisd=0x00;trisb=0x00;portb=0x00;lcd_init();while(1) {   CCP1CON=0X05;  if (PIR1.CCP1IF) {    portb.rb0=1;    PIR1.CCP1IF = 0;    portb.rb0=0;   Hi(counter)= TMR1H; // 8 MSB   Lo(counter)= TMR1L;// 8 LSB   wordtostr(counter,freq);   lcd_out(1,1,freq);TMR1H=0; // reset timerTMR1L=0; // reset timerlcd_cmd(_lcd_clear);  }}}

Share this post


Link to post
Share on other sites

Nu stiu daca am inteles corect intrebarea dar concatenarea a 2 byte intr-un word se face asa:

 

int counter;counter = TMR1H << 8; //se shifteaza la stanga cu 8 pozitii TMR1Hcounter |= TMR1L; //se adauga TMR1L

Share this post


Link to post
Share on other sites

nu mai pot edita, dar raspunsul pentru tine cred ca este result = TMR1H*256+TMR1L (nu 255 din primul post)succes

Share this post


Link to post
Share on other sites

O sa incerc, si revin cu un raspuns. Multumesc !!

Share this post


Link to post
Share on other sites

mars, costi:eu cred ca in solutiile date de voi (TMR1H*256 sau TMR1H<<8) trebuie facut 'casting'.adica: ((int)TMR1H<<8) + TMR1Lps: inmultirea cu 256 este tradusa de compilator tot intr-o deplasare la stanga cu 8.moro, mai ai o problema cand nu tratezi in intrerupere TMRx (adica acolo unde esti sigur ca TMRx a generat overflow) :este posibil sa incepi citirea lui TMRx cand are valoarea 0xFFFF, (TMRxH=0xFF, TMRxL=0xFF) .se poate intampla asa:1. citesti TMRxH=0xFF (si eventul faci si <<8 . deci pierzi timp)2. in timp ce ai facut pasul "1" , TMRx a devenit 0x0000 si citesti TMRxL=0x003. rezulta ca a fost TMRx=0xFF00 .... fals!4. cum crezi ca scapi de cazul asta particular ?

Share this post


Link to post
Share on other sites

Am incercat sa unesc cei doi registrii din timer1

De ce nu lucrezi cu CCPRxH, CCPRxL? Sunt pusi acolo special pentru asta. Asa ai scapa si de intrebarea capcana a lui brad :rade: (la varianta cu timer trebuie sa-i raspunzi singur).

In Capture mode, the CCPRxH, CCPRxL register paircaptures the 16-bit value of the TMR1 register when anevent occurs on pin CCPx.

@brad: oricum cred ca vorbim intre noi, moro n-a mai dat pe aici de vreo doua zile. :rade:

Share this post


Link to post
Share on other sites

mars, costi:eu cred ca in solutiile date de voi (TMR1H*256 sau TMR1H<<8) trebuie facut 'casting'.adica: ((int)TMR1H<<8) + TMR1Lps: inmultirea cu 256 este tradusa de compilator tot intr-o deplasare la stanga cu 8.moro, mai ai o problema cand nu tratezi in intrerupere TMRx (adica acolo unde esti sigur ca TMRx a generat overflow) :este posibil sa incepi citirea lui TMRx cand are valoarea 0xFFFF, (TMRxH=0xFF, TMRxL=0xFF) .se poate intampla asa:1. citesti TMRxH=0xFF (si eventul faci si <<8 . deci pierzi timp)2. in timp ce ai facut pasul "1" , TMRx a devenit 0x0000 si citesti TMRxL=0x003. rezulta ca a fost TMRx=0xFF00 .... fals!4. cum crezi ca scapi de cazul asta particular ?

De fapt casting-ul se face sau nu functie de compilator. Eu am folosit aceasta operatie cand, de ex, (procesor pe 8bit) recuperam valori pe 16bit scrise in EEPROM si nu am avut nevoie de casting cand am folosist operatii cu biti.Dar este si o greseala aici: variabila counter ar trebui sa fie un unsigned int sau un long (long-ul va fi ineficient dpdv al spatiului ocupat in memorie dar va rezolva problema). Daca TMR1H este gen 0b1xxxxxxx si rezultatul este stocat intr-o variabila tip INT, rezultatul ar avea o valoare negativa (parca Arianne s-a prabusit de la o problema de genul asta ???)Intrebarea la pct 4 este ori retorica ori cu intentie educativa dar se rezolva foarte usor cu disable / enable intreruperi (eventual salvare a starii registrului cu flaguri intrerupere inainte de disable, si restaurarea sa la finalul procesarii variabilei counter).

Share this post


Link to post
Share on other sites

De fapt casting-ul se face sau nu functie de compilator.

E "good practice" sa faci codul cat mai independent de compilator (recunosc ca si eu am tot lucrat fara casting). Ajuta, de exemplu, la portare mai usoara a codului pentru alt compilator. In cazul de fata, de exemplu, moro n-a zis ce compilator foloseste, asa ca poate la compilatorul lui o sa aibe probleme fara casting.

Intrebarea la pct 4 se rezolva foarte usor cu disable / enable intreruperi

Dezactivarea intreruperilor nu opreste timerul, acesta numara in continuare si eventuala problema ridicata de brad ramana. Ca sa nu mai numere/sa nu mai conteze ca numara, ori il opresti (pe timer), ori, in cazul de fata, faci cum am sugerat mai sus, folosesti registrii CCPRxH & CCPRxL.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.