Sari la conținut
ELFORUM - Forumul electronistilor

Probleme de incepatori


Postări Recomandate

Am o problema de incepatori, nu ce e pe aici...

Attiny44 are o frecventa de 8MHz. Daca setez un counter pe 16 biti sa aibe frecventa de clk/64 cu CTC, cum calculez pana la cat trebuie sa numere pentru a rezulta o secunda?

 

Codul meu arata cam asa:

 

int main( void ){DDRA=0xFF;PORTB=0x00;DDRB=0x0F;TCCR1B |= _BV(WGM12)|_BV(CS11)|_BV(CS10); // Set up timer at Fcpu/64 & CTCTCCR1A |= _BV(COM1B0);OCR1B = xxxxxx; // Set CTC compare value	while (1){	}}

Dati-mi doar explicatia cum se calculeaza si de ce, nu doresc alternative la cod.

 

Va multumesc!

Cu stima,

Vlad

Link spre comentariu

Dupa calculele mele cu datele pe care le-ai dat nu poti numara pana la o secunda. Ar fi asa:1 / 8000000 [clk] = 0,000000125 [sec]0,000000125 [sec] x 64 [prescaler] = 0,000008 [sec]0,000008 [sec] x 65535 [maxim counter pe 16 biti] = 0,52428 [sec]Counter maxim = 0,52428 secundeAi doua variante:Ori maresti prescalerul la 256 si rezulta counter maxim 2,09712 secunde, caz in care setezi counterul pe 16 biti la valoarea dorita ca sa rezulte 1 secunda, (aprox 32767) Ori micsorezi frecventa de ceas si refaci calculele.Succes!

Link spre comentariu

8000000/64 = 125000, e prea mare (peste 2 octeti), n-ai cum compara8000000/256 = 31250 - setezi prescalerul la 1:256, si octetii de compare la 31250 (0x7A12, deci 0x7A high, 0x12 low).later edit: Simnakovi a fost mai rapid, se vede cine se trezeste de dimineata :)iar daca cumva folosesti oscilatorul intern al controlerului (si nu quartz extern), zice lumea sa nu te astepti la precizie prea mare.

Link spre comentariu

Imi place ca toata lumea aici imparte OCR-ul de 16 biti in 2 reg H si L cand scrieti in el. Din cate am vazut in AvrGCC OCR e descris ca o concatenare de 2 variabile de 8 biti. Deci puteti scrie simplu OCRx=31500, atribuirea se face corect pe cei 2 reg de 8 biti.

Link spre comentariu

AVR073 application note (gasit la repezeala, sunt sigur ca se mai pot gasi exemple):

 

The ATtiny261/461/861 microcontroller family includes Timer/Counter modules that

can be used in 10- and 16-bit modes. Since the AVR® data bus is 8 bits wide,

special considerations must be made when accessing 10- and 16-bit registers.

Most AVR C compilers handle 16-bit (and 10-bit) register accesses transparently

when the two 8-bit registers that makes up the 16-bit value can be accessed at

consecutive addresses. In the ATtiny261/461/861 family, not all 10 and 16-bit

registers are not addressed at consecutive addresses, so compiler support is

limited to accessing the individual 8-bit registers.

 

 

 

Precum vezi, nu e o regula generala sa si functioneze corect si intotdeauna ceea ce spui tu.

In cazul de fata e vorba de attiny44, nu am stat sa caut exact ce e cu el, dar vorbesc la modul general. E suficienta o singura exceptie pentru a ma convinge sa nu fac cum zici tu.

"Assumption is the mother of all fuck ups". In 15 ani de programare am invatat sa nu presupun nimic. Si sunt necesare si unele reguli de good-practice.

 

Cel mai corect e de citit datasheetul:

- daca scrie ca trebuiesc citite/scrise separat (si eventual intr-o anumita ordine), atunci asa se va face

- daca scrie ca trebuiesc citite/scrise simultan, atunci asa se va face (desi nu mi-e clar cum se poate face asta pe un procesor pe 8 biti)

- daca nu scrie ordinea in care trebuiesc citite/scrise, atunci se va aplica prezumtia de "nu presupun nimic" si le operez separat pe fiecare. Codul rezultat (compilat) nu va diferi, in majoritatea cazurilor - oricum pe 2 cicli se vor executa.

Poate tu consideri ca e mai clar un cod scris cu octetii impreuna; altora din contra, le e mai usor sa citeasca codul scris cu H si L separat.

 

Sau, pe scurt: cat timp procesorul e pe 8 biti, nu castigi nimic sa tratezi registrul pe 16 biti, dar in schimb sunt situatii cand acest lucru e incorect.

 

 

LATER EDIT:

 

Recunosc, cateodata sunt paranoic. Am luat la re-citit bucatile despre timere din datasheet, si vad ca si ei, pentru exemplele in C, atunci cand e posibil, folosesc variabile/constante pe 16biti. Prin "atunci cand e posibil" ma refer ca totusi exista exceptii, dar atunci vad ca au botezat registrii diferit, pentru a nu mai putea fi accesati direct pe 16biti (cum e cazul lui TCNT1/TC1H din attiny 461).

Cu alte cuvinte, recunosc ca atunci cand apar exceptii, si-au luat masuri de precautie pentru a nu aparea greseli.

Peace.

Link spre comentariu

Cand exista riscul sa gresesc, asta e, recunosc. In marea majoritate a situatiilor, pare a fi mai bine de folosit accesarea pe 16 biti. Am gasit si explicatia pentru aceasta (sau cel putin una dintre ele):

 

To do a 16-bit write, the High byte must be written before the Low byte. For a 16-bit read, the Low byte must be read before the High byte.

Din teste, compilatorul genereaza corect ordinea si la read si la write. Si nu am motive sa cred ca ar gresi vreodata.

Omul in schimb ar putea gresi si sa le inverseze. Caz in care e mai bine sa ne bazam pe compilator, ca in fond de aceea scriem in C si nu in asm.

 

ok, multam de remarca, am mai invatat ceva.

Link spre comentariu

Stati sa vad daca am inteles bine...Daca am clk = 8MHz si iau Counter0 care e pe 8 biti, pentru a scoate 1kHz pe Counter0 am asa:Pt clk/1024 => frecventa noua = 7.8125kHz.Pentru 8 biti 7812.5Hz/256 = 30.51Hz => overflow se face din 30.51Hz in 30.51Hz.1kHz/30.51Hz = 31.77 - numarul de overflowuri care trebuie sa se execute pentru a avea 1kHz. Corect?Acum cum as putea implementa asta cel mai optim? Folosesc ATtiny44

Link spre comentariu

1kHz/30.51Hz = 31.77 - numarul de overflowuri care trebuie sa se execute pentru a avea 1kHz. Corect

Partea asta e eronata. Numarul de overflowuri pe secunda (sau frecventa lor) le-ai obtinut anterior, 30.51 .. Cam cum se fac calculele.1. iti alegi frecventa de ceas, in functie si de restul necesitatilor. Tu ai ales 8MHz, mergem mai departe cu 8MHz.2. iti alegi un factor de divizare (prescalerul) astfel incat frecventa:prescaler sa dea un numar rotund (fara virgule) - numar care e de preferat sa fie multiplu al frecventei pe care doresti sa o obtii. Avem:8000000/1024 = 7812.5 - nu ne e bun8000000/256 = 31250 - e rotund, dar nu e multiplu de 1kHz8000000/64 = 125000 - pare perfect3. Acum contorul timerului ti se va incrementa de 125000 de ori pe secunda; daca folosesti intreruperea de overflow, aceasta va fi apelata de ~488 de ori pe secunda (125000/256=488.ceva)Nu ne convine. De aceea vom folosi intreruperea pt compare (pt attiny44 - TIM0_COMPA de ex, cu flagul ocie0a). Incarcam in ocr0a valoarea de 125, cu urmatorul efect:125000/125 = 1000Deci intreruperea tim0_compA va fi apelata de catre procesor cu o frecventa de 1KHz (de 1000 de ori pe secunda).Ca o observatie: din cauza impartirilor astea multiple, in situatii de genul acesta, uneori, se prefera cristale cu frecventa putere al lui doi - gen 7,3728 MHZ, 32768Hz, etc. Tot ca o paranteza, daca folosesti oscilatorul intern al microcontrolerului (fara cristal extern), sa nu te bazezi prea mult pe frecventa generata (va avea o eroare ceva mai mare).
Link spre comentariu
  • 2 luni mai târziu...

saluttrebuie sa setez ceva nume ca sa pot cititi un atmega 48 cu ponyprog? la security bits? ca imi tot da eroarea -24 si nu pot sa il scriu?il proiect scrie asa BOOTSZ=11BODLEVEL=1CKSEL=1111SUT=11dar nu prea stiu care cum sunt alea din security bits de la ponyprog

Link spre comentariu

salut

 

trebuie sa setez ceva nume ca sa pot cititi un atmega 48 cu ponyprog? la security bits? ca imi tot da eroarea -24 si nu pot sa il scriu?

 

 

il proiect scrie asa

BOOTSZ=11

BODLEVEL=1

CKSEL=1111

SUT=11

 

dar nu prea stiu care cum sunt alea din security bits de la ponyprog

asta e problemă hardware, nu software!!!

vezi aici: viewtopic.php?f=37&t=47632

 

asta presupunând că ai un mcu scriş greşit la fusebiţi, dar dacă vrei să citeşti un mcu protejat la citire... nu prea ai mari şanse, poate cu jtag, dar nu prea-mi vine a crede că ai jtag la mega48!

Link spre comentariu

deci daca ii dau read all prima data imi arata eroarea -24 ii dau ignore si dupa care merge.... la sf imi zice reading was succesfull..si cand ii dau write la fel ii dau ignore dupa care o ia... dar dupa ce ii face veriffingul se blocheaza programul si ramane becul verde la programator aprins ar trebuii sa ii inlocuiesc oscilatorul de pe programator cu altul?

Link spre comentariu

Cum spunea si Mifty, ai o problema hardware cu acel microcontroler, adica ai blocat fusebitii si nu mai reusesti sa-l citesti.

-Poti incerca sa pui alt Quartz mai mare de 10MHz si apoi sa-l citesti din nou.

Daca nu:

-Poti incerca sa injectezi o frecventa generata de un oscilator extern, la pinul "9", aprox. 16-25MHz si apoi sa incerci sa-l citesti din nou.

Daca nu:

-Pune in locul Quartz-ului doua fire, tine-le intre degete, si incearca sa-l citesti din nou.

Daca nu:

-Poate merge metoda de aici: http://yo6pir.wordpress.com/arhiva/deblocare-atmega8/

Daca nu:

... mai incearca, pentru ca sigur exista o solutie, crede-ma! SUCCES!

Link spre comentariu

Salutare, in aceasta seara am reusit sa termin programatorul pentru Atmega8. Dimineata voi intra in posesia unui LCD 16x2 pentru a putea efectua diverse teste.Am facut o proba de scriere/citire cu un program simplu scris in bascom si a fost un succes (am reusit sa scriu si sa citesc cu pony prog 2000 fara erori).Acum, problema mea este ca nu imi intra in cap documentatia in engleza si in romana prea multe informatii nu am gasit (Ex: care porturi pot fi folosite pentru intrare, care pentru iesire, de pe care se pot citi valori analogice, de pe care digitale/impulsuri).Apoi am citit acest topic si am intrat si mai rau in ceata cu OCR, Prescaler, etc Ce anume inseamna acesti termeni? Nu pot sa cred ca sunt singurul care nu stie ce inseamna.De exemplu eu am un Atmega8-16PU.Am cumparat un cristal de quartz de 12 Mhz.Aplicatia ce doresc sa o creez va avea un meniu cu mai multe submeniuri si un meniu ascuns de setup (avea cineva in topic aceiasi problema).Trebuiesc citite diverse valori externe, unele in impulsuri (trebuiesc numarate impulsurile), altele in rezistenta (care se traduce prin valoarea efectiva a tensiunii fata de GND) si unul sau 2 I/O.Ca si soft de scriere cod folosesc Bascom-AVR IDE.Informatiile procesate doresc sa le afisez pe ecran la un interval de timp.Ex:1-5: Info 16-10: Info 211-15: Info 316-20: Info 4si la terminarea afisarii informatiilor sa se treaca iar la Info 1 si tot asa. De asemenea mai doresc la fiecare apasare a butonului de control sa se afiseze succesiv pe display valorile respective.P.S. Sper sa nu mi-o luati in nume de rau, nu cer sa mi se dea mura in gura bin-ul ce trebuie scris in atmega, doresc sa invat.Multumesc anticipat.

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