Sari la conținut
ELFORUM - Forumul electronistilor

atmega8 o ia cu o secunda inainte...


adynis

Postări Recomandate

Jucandu-ma si cu un LCD am incercat sa fac microcontrolerul pe post de ceas extrem de exact ... si n-am reusit :(Este setat cu oscilatorul intern, la 4Mhz ... Am pus un timer cu prescaler de 256 care sa-mi dea o intrerupere cand ajunge la 15625 ( =4mil/256), iar in intrerupere incrementam secundarul cu 1 ... Cam la 1 minut el era cu o secunda inainte :( Mentionez ca lucrez in C nu in asm, dar totusi timerul ar fi trebuit sa functioneze exact, zic eu ... unde e problema ? De ce nu pot sa fac un ceas extrem de exact ?

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

Top autori în acest subiect

  • adynis

    3

  • Laci

    2

  • wingless

    1

  • psanyi

    1

Top autori în acest subiect

Vizitator DragosP

hmmm eu am un cuartz de 4Mhz (scrie pe el 4.000 AEC05B) asta e destu lde exact ? ... ce e ala circuit RTC ? :prayer:

Păi până la urmă cum e? Cu oscilator intern la 4MHz (aşa cum ai spus în primul post) sau cu cuartz extern? Că dacă-i pui cuartz extern, trebuie să-l setezi ca atare...Totuşi, o secundă la un minut este o eroare prea mare chiar şi pentru oscilatorul intern, verifică dacă nu-i o greşeală în program, sau, dacă nu, încearcă o calibrare a oscilatorului intern. Studiază foile de catalog ale uC-ului, vezi că sunt date variaţiile frecvenţei oscilatorului intern în funcţie de tensiunea de alimentare (şi aici vezi cam pe unde te afli de fapt cu frecvenţa) şi în funcţie de temperatură (unde nu prea ai ce să-i faci relativ simplu; complicat se poate, da' mai degrabă pui cuartz extern şi te-ai scos).
Link spre comentariu
Vizitator DragosP

Cu 4 MHz nu ai cum sa faci un ceas. Punct.

Eh Alex, uite că eu n-aş fi aşa de categoric. Dacă se foloseşte de ex timer-ul 1 (16 biţi), prescaler la 1024 şi TCNT1 încărcat cu 61630 (pentru un overflow la 3906) obţinem 4.000.000/1024/3906 = 1,000064 Hz, adică o eroare de 5,39999e-3%! Adică se poate, şi foarte bine. Nu ştiu cum e la alte uC-uri, dar la AVR-uri poţi obţine aproape orice.Asta ar fi o variantă, alta ar fi folosind timer-ul în mod CTC.Dar, ca de obicei, datasheet-ul ne ajută întotdeauna! :yawinkle:
Link spre comentariu

@DragosP Pana acum am incercat doar cu oscilator intern, dar am pe aici pe langa mine si un quartz pe care nu l-am folosit niciodata pana acum. Dar o sa incerc sa vad daca apar diferente ;)@Laci Nu am inteles exact... de ce imparti 15625 la 256 (poate e si pentru ca e noaptea tarziu :partyman: ) dar: prescalerul face ca odata la 256 cicluri, timerul sa se incrementeze. La 15625 de incrementari ar trebui sa se faca o secunda ... Pentru verificare fac 256*15625=4000000=1sec@DragosP 2Pai eu am folosit CTC gandind ca timerul va merge de la 0 la 15625 cand va genera o intrerupere ... Normal ca am incercat si cu alte prescaleruri decat 256 ... am ocolit 1024 ca acolo nu imi da exact ...O sa mai incerc si cu quartzul pe care il am sa vad ce iese. Este interesant si cum ns-a zis mai sus de circuit RTC ... dar totusi, e vorba de microcontroler, chiar nu reusesc precizie de 1 secunda :( ...

Link spre comentariu

Spunea cineva ca nu se poate obtine secunda cu un quartz de 4MHz.Intradevar utilizand numai resursele hard a MC-ului acest lucru nu se poate.In schimb daca (de exemplu ) ai utiliza prescalerul la valoarea clk/8 ,se obtine un ceas la timer de 500KHz.Incrcand TCNT-ul cu valoarea 56, se obtine la iesirea lui o frecventa de 2,5KHz. Din acest moment avem o sursa convenabila de ceas pe care o putem trata software. Se initilizeaza o intrerupere pe aceasta frecventa(ex. OV0),avand grija ca prima secventa din intrerupere sa reincarcam timerul cu valoarea de mai sus , mai putin ciclurile de reincarcare (ptr a pastra frecventa . In continuare nu trebuie decat sa facem un numarator soft cu 2500 si obtinem secunda un exemplu de programare :;prima oara definim registrii.def tmp1=r16.def tmp2=r17.def tmp3=r18.def rint=r3; deasemenea in RAM alocam locatii ptr valorile ceasului si a unui timer soft pe 16biti.dseg.org 0x60secunde: .byte 1zecisecunde .byte 1minute : .byte 1zeciminute: .byte 1ore: .byte 1zeciore: .byte 1timersoftlow: .byte 1timersofthigh: .byte 1;s-au alocat in ram locatii ptr fiecare din marimi.;in continuare apare secventa de program.cseg rjmp init ;;;; salt la liniile de inceput.org t0Ov: ;;;;;;; adresa ptr intrerupere a timer0 overflow rjmp isr_t0ov ;;;;' salt la rutina de tratare a intreruperiiinit:...... ;;;; diverse initilizari rcall init_t0 ; initilizarea timer0 overflow............ ;liniile de program efective....;;;;; rutina de initializare a timer0init_timer0: ldi tmp1,3;;;;;;;;;;;; valoarea prescaler out tccr0,tmp1;;;;;;;; in registrul de control ldi tmp1,56;;;;;;;;;;; valoarea timerului out tcnt0,tmp1;;;;;;';;; in timer dec tmp1 ;;;;;;;;;;;;;;;; se decrementeaza valoarea mov rint,tmp1 in tmp1,timsk;;;;;;;;;;; aici se valideaza ori tmp1,0b00000001;;;; intreruperea ptr t0 out timsk,tmp1 ret;tratarea intreruperii se v-a face incepand cu secventa de reincarcare;a timeruluiisr_t0ov: out tcnt0,rint;;;;;;;;;;;;;;; se reinitializeaza timerul cu 56-1 ,un ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ciclu dureaza operatia out push tmp1;;;;;;;;;;;;;;;;;;;; se salveaza registrii push tmp2 push tmp3 in tmp3,sreg;;;;;;;;;;;;;;; se salveaza si psw-ul lds tmp1,timersoftlow;;;;;;;;se incarca timerul soft lds tmp2,timersofthigh subi tmp1,1;;;;;;;;;;;;;;;;;;;;; se decrementeaza cu 1 sbci tmp2,0 brcs a_trecut_s ;;;;;;;;;;;;;; daca valoarea este 0 salt la rutina de tratare a ceasuluiaddr_revenire: sts timersoftlow,tmp1;;;;;;;;;; se salveaza valorile sts timersofthigh,tmp2 ;;;;;;;;;;ptr timerul soft ..... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; aici sunt alte linii de program din ...... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; intreruperea timer0 overflow exit_t0_ov: out sreg,tmp3 ;;;;;;;;;;;;;;;;;;; se restureaza registii pop tmp3 pop tmp2 pop tmp1 reti ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; si se iese din intreruperea_trecut_s:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; atrecut o secunda si trebuie sa lds tmp1,secunde;;;;;;;;;;;; facem refresh la ceasul real inc tmp1;;;;;;;;;;;;;;;;;;;;;; incrementeaza secunda sts secunde,tmp1;;;;;;;;;;;; se salveaza cpi tmp1,10;;;;;;;;;;;;;;;;;;;;;;;;; daca nu au tecut 10 s brne exit_rutina;;;;;;;;;;;;;;;;;;;;; se iese clr tmp1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;altfel se pun sec.=0 sts secunde,tmp1 lds tmp1,zecisecunde ;;;;;;;;; si se incrementeaza zecile inc tmp1;;;;;;;;;;;;;;;;;;;;;;;;; de secunde sts zecisecunde,tmp1 cpi tmp1,6 brne exit_rutina clr tmp1 sts zecisecunde,tmp1 lds tmp1,minute;;;;;;;;;;;;;;;;; se repeta operatia pana la inc tmp1;;;;;;;;;;;;;;;;;;;;;;;;;;; ;nivel de zeci de ore ....... ....... ....... lds tmp1,zeciore inc tmp1 sts zeciore,tmp1 cpi tmp1,24 brne exit_rutina clr tmp1 sts zeciore,tmp1exit_rutina:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; dupa aceasta se ldi tmp1,low(2500);;;;;;;;;;;;;;;; tmp1 si tmp2 se ldi tmp2,high(2500);;;;;;;;;;;;;;;;; incarca cu valoarea 2500 rjmp addr_revenire;;;;;;;;;;;;;; adresa de revenireBinentele ca rutina poate fi scrisa si sub alte forme , mult mai elegante, asta fiind numai o exemplificare a modului cum poate fi tratata problema din punct de vedere software.Se observa ca secundele, zeci secunde, minute ..etc sunt in format BCDsi se pot utiliza direct la afisare, fara a mai fi nevoie de conversii.ATENTIE .. ceasul intern a MC-ului NU este foarte precis, el depinde o cativa factori externi , cum ar fi temperatura, variatia tensiunii de alimentare etc.Pentru o calibrare a ceasului se poate umbla la FUSE sau mai simplu semodifica valoare de 2500 a timerului soft. O unitate adaugata sau scazuta din aceasta valoare face o rectificarea ceasului cu cca. 0,04% . astfel daca valoarea este de 2501, valoarea pe secundava creste cu 0,04%

Link spre comentariu
  • 4 săptămâni mai târziu...

S-a discutat de o mie de ori pe forum problema asta: "Ceas cu uC la 4MHz". Cu 4 MHz nu ai cum sa faci un ceas. Punct.Foloseste quartz de 3,2768MHz si ceasul o sa mearga ok.

Cu 4Mhz, faci o divizare de 256, dupa care mergi cu un CTC la 125, si o variabila de tip char tot la 125 (e mai rapid decat un integer). Cand se indeplineste conditia de egalitate ai exact o secunda.CTC este un feature pentru AVR.256*125*125 =4.000.000
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