Sari la conținut
ELFORUM - Forumul electronistilor

tmr0 16f877


sz3bbylA

Postări Recomandate

16f877 nu are internal oscilator

eu folosesc extern 20mhz iar in pdf-ul picului nu am inteles prea bine cum sta treaba cu tmr0

ma intereseaza sa folosesc o intrerupere tmr0 la 1 us si nu am inteles exact cum sa fac

pe un site am gasit ca 16f877 are pt tmr0 internal 4mhz (ceea ce nu am gasit deloc in documentatia picului)

http://www.microcontrollerboard.com/pic-timer0-tutorial.html - ma bulversat de tot asta

incerc sa creez un timer care sa fie un etalon ca sa pot executa alte operatii pina count ajunge la 500(ca exemplu)

 

hi-tech code:

 

void interrupt isr(void) {

if(T0IE && T0IF){ // handle timer interrupt

tmr0= 5; //200ns*5=1us

toif=0;

count++;

}

}

void main(){

GIE = 1; // Enable Interrupts

PEIE = 1; // Enable PIE Interrupt Sources

T0CS = 0; // timer mode

T0SE = 1; // high to low timer mode

PSA = 0; // Prescaler is assigned to the Timer0 module

PS2 = 0; PS1 = 0; PS0=0; // prescaler value

T0IF = 1; // Enable TMR0 Interrupt Sources

if(count==500){

count=0;

//do something

}

}

 

 

nu stiu daca formulele de pe linkul pus de mine sunt valabile si in cazul meu

Link spre comentariu
  • Răspunsuri 15
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Liviu M

    6

  • sz3bbylA

    6

  • ramsesrr

    2

  • MatyC

    1

Top autori în acest subiect

sincer nu am inteles formula si inca ma chinui sa inteleg care e frecventa interna pentru 16f877o incrementare in tmr0 este 20mhz/4 , sau 20mhz*4?in pdf spune Operating speed: DC - 20 MHz clock input DC - 200 ns instruction cycle

Link spre comentariu

In cazul tau este 20Mhz/4. Ai prescaler setat la 1:2 cu iesire catre tmr0. Asa ca in tmr0 ai 20Mhz/4/2 intrare. T(sec)=1/f(Hz). Ce este in paranteze sunt unitatile de masura standard valabile in formula. 20Mhz/4/2=20Mhz/8=2,5 Mhz frecventa intrare tmr0. 1/2.500.000 Hz=0,000.000.4 s= 400 ns.

Link spre comentariu

Nu e nici o vrajitorie la mijloc, cu putin "antrenament" reusesti sa intelegi despre ce e vorba.Referitor la frecventa, pentru fiecare instructiune un pic are nevoie de 4 pulsuri de ceas (asa e construit PIC-ul intern). De aici apare diviziunea cu 4 (20 MHz / 200 ns).Referitor la formula de la TMR0 - ca sa generezi o intrerupere cu un timer, trebuie ca registrele asociate timerelor sa "se umple"; urmatorul puls pe intrarea de ceas a registrului TMRx genereaza overflow => intrerupere.In cazul TMR0 ai un singur registru pe 8 biti, deci maximul care "incape" in el e 255. Asa ca TMR0 poate numara de la 0 la 255 + "pulsul de overflow" = 256. Daca vrem sa avem intrerupere dupa mai putin timp, trebuie ca registrul sa porneasca preincarcat cu o valoare X astfel aleasa incat TMR0 sa numere cat ne rebuie noua => 256 - X. Mai ramane de calculat X pornind de la ceasul de sistem. Am vazut ca instructiunile se executa in 4 cicluri de ceas. La fel se intampla si cu incrementarea registrilor timerelor. De aici 4 de la numitor.Pe de alta parte, pentru a putea "numara" timpi mai lungi, timerele au asociate prescalere/postscalere care sunt, practic, divizoare de frecventa. Folosind pre/postscalerele astea, ceasul care ajunge la timere e "mai rar" cu factorul de divizare al pre/postscalerului *). De aici "prescaler" din formula. *) Exemplu - un pre/postscaler 1:8 inseamna ca la fiecare 8 pulsuri de ceas de sistem e incrementat si registrul TMRx.

Link spre comentariu

multumesc pentru raspunsuri

banuiam ca e asa dar am fost bulversat de situl ala care imi zicea ca pt 16f877 ai ceas intern 4mhz - imposibil atata timp cat nu are decit extern

deci pentru mine ceasul picului e 20mhz

acum pt prescaler 000 am 1/2 din ce am inteles la maty 400ns =>pot folosi (265-5) pt 2us

pentru prescaler 001 am 1/4 => pot folosi (256-5) pentru 4 us

atunci pentru ca sa obtin 1ms folosesc timerul 500 ori (presc 000) sau 250 (presc 001)

 

hi-tech:

 

unsigned char count=0;

unsigned int nr=0;

void interupt isr(){

if(T0IE && T0IF){

count++;

TMR0=5;

T0IF=0;

}

}

void main(){

T0SE = 1; // high to low timer mode

T0CS = 0; // timer mode

PSA = 0; // Prescaler is assigned to the Timer0 module

PS2 = 0; PS1 = 0; PS0=1; // prescaler value to 400ns

TMR0=5;

T0IF = 1; // Enable TMR0 Interrupt Sources

GIE = 1; // Enable Interrupts

light=0; //becul e stins

while(1){

if(count=250){

count=0;

nr++;

}

if(nr=1000){

nr=0;

light != light; //se singe sau se prinde la 1 sec

}

}

}

 

mai e o problema

TOSE0 te lasa sa faci ceasul crescator sau descrescator

TOSE0 = 0 => low to high

TOSE0 = 1 => high to low

 

a doua problema a mea este ca mai exista niste delay-uri care apar la aparitia intreruperii si la esirea din ea

 

codul asta nu merge

nu stiu une gresesc

Link spre comentariu

Din cauza de timeout am pierdut tot ce scrisesem.Nu reiau tot.O greseala la tine e T0IF=1 in loc de T0IE=1 pentru activat intreruperi.Mi se pare putin ciudata metoda de folosire a intreruperii - TMR0 numara putin de multe ori.Pentru 1 ms cu prescaler 1:4 eu as incarca TMR0 cu ~5 si as incrementa o variabila de 5 ori:1000 us / 4 / 250 / 0.2 = 5.16F877 poate fi programat sa lucreze cu ceas extern - quarz sau oscilator RC - pana la 20MHz in functie de model - sau cu ceas intern de 4 MHz - pag. 120-121 in data sheet.Flancul ceasului (T0SE) are importanta daca pentru TMR0 folosesti oscilator extern dedicat conectat pe pinul T0CKI (RA4). Daca folosesti ceasul de sistem (cazul tau), poti sa-l ignori.

Link spre comentariu

va multumesc pentru indrumariin sfarsit vad ledul ca se aprinde/stingesincer nu inteleg exact ce-am faut dar merge(adica mai trebuie sa fac calcule ca sa ma prind ce inseamna o secunda)dar din nou am fost intors pe dos cu internal clockpag 120,121 imi spune Oscillator Configurations, dar nu am gasit sa scrie despre internal clock 4 mhze o mare nedumerire pentru mine atata timp cat picul 16f877 spune clar ca merge doar cu oscilator externsingurul lucru pe care l-am gasit legat de intarnal osc e poza asta

Link spre comentariu

Se pare ca ai dreptate, nu exista oscilator intern. Are nevoie cel putin de o rezistenta si un condensator externe.Hm, habar n-am de unde ramasesem cu ideea ca are si oscilator intern. Poate pentru ca l-am folosit tot timpul cu quarz? :nas:

Link spre comentariu

habar n-am de unde ramasesem cu ideea ca are si oscilator intern.

poate de la inlocuitorul sau PIC16F887, acesta are oscilator intern.Este foarte util si calculatorul de AICI , dar asta nu te scuteste de cunoasterea functionarii timer-ului.
Link spre comentariu

okeu folosesc 16f877887-le parca are osc intacum:T0CS = 0; internal deci eu presupun ca e 4 mhzps2 = 1, ps1=1, ps0 = 1 => inseamna 4mhz/4/256 = 256us o inrementare => mai mult de 1 sfert de secaproximam:4 incrementari = 1ms8 incrementari = 2ms16 incrementari = 4ms20 incrementari = 5ms40 incrementari = 10ms 80 incrementari = 20ms 200 incrementari = 50msin program folosescT0CS = 0; internal deci eu presupun ca e 4 mhz 50*2 = 100ms=> 20 incr pe count inseamna o seca trebuit sa pun counterul pe 200 ca sa obtin aprox 1 sec(e mai putin de 1 sec desi pt 111 am mai mult de 1 sfert de sec)asta am facut babeste ca sa nu ma incurc in stiinta//program:unsigned int count=0;void interrupt isr(void) { if(T0IE && T0IF){ count++; TMR0 = 200; // handle timer interrupt T0IF = 0; } }void main(){ ADCON1 = 0x07; // all pin I/O GIE = 1; // Enable Interrupts PEIE = 1; // Enable PIE Interrupt Sources T0IE = 1; // Enable TMR0 Interrupt Sources T0SE = 0; // 1 = high to low, 0 = low to high//aceasta intructiune nu are nici o valoare T0CS = 0; // 0 = internal clock, 1 = extern clock PSA = 0; // Prescaler is assigned to the Timer0 module PS2=1; PS1=1; PS0=1; // prescaler value T0IF = 0; TMR0 = 200;while(1){ if(count==200){ count=0; if(LCD_LIGHT==1) LCD_LIGHT=0; else LCD_LIGHT=1; }}ceva nu e logic aici

Link spre comentariu

acum:

T0CS = 0; internal deci eu presupun ca e 4 mhz...

Atentie! Internal aici inseamna ca e derivat din ceasul de sistem (20 MHz / 4 /(eventual)prescaler), nu ca e un oscilator intern pe undeva. Cu alte cuvinte, la un ceas de sistem de 20 MHz si un prescaler 1:2 frecventa cu care incrementezi TMR0 e 20 MHz / 4 / 2 = 2.5 MHz (daca n-am gresit la calcule). Adica cele 400 ns ale lui MatyC.

Timer0 poate fi utilizat cu un ceas derivat din ceasul de sistem (cu frecventa de mai sus) sau cu un oscilator extern conectat la pinul T0CKI(RA4) - vezi pagina 47 in data sheet pentru o poza.

ceva nu e logic aici

Sper c-am mai luminat putin subiectul :)
Link spre comentariu

Liviu M acum e ok si am inceput si eu sa ma luminez nitelsper sa mai ajute pe careva postul asta , eu am inceput sa intelegT0CS = 0 => la mine e ceasul intern adica 20mhzT0CS = 1 cind folosesc clock pe RA4in cazul meu trebuie sa folosesc T0CS = 0 cu folmula lui MatyCbafta tuturor care m-ati indrumat !CRISTOS A INVIAT !

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