Sari la conținut

Despre programarea microcontrolere Atmel AVR - intrebari si raspunsuri


Postări Recomandate

Cum este cel mai bine sa realizam clock-ul unui microcontroler: cu quartz extern, clock extern sau RC intern?

Si as mai avea o intrebare. Spre exemplu, daca realizam clock-ul microcontrolerului cu un quartz extern, spre exemplu, de 8 Mhz, si in al doilea caz, ii dam 8 Mhz dintr-o sursa externa de clock, pe unul din pini xtal a microcontrolerului, teoretic si practic, in ambele cazuri clock-ul real a microcontrolerului este 8 Mhz ?

 

stima

dan

Link spre post
Distribuie pe alte site-uri
  • Răspunsuri 163
  • Created
  • Ultimul Răspuns

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Dan,

Depinde de la aplicatie la aplicatie, sunt aplicatii unde precizia clock-ului nu e importanta, si altele unde e cruciala.

la cele unde precizia e importanta folosesti oscilatorul cu quartz, sau o sursa de clock externa.

asta cu clock-ul (divizat sau nu) e mai dificila pentru ca nu toate microcontollerele sunt la fel. Unele au in circuit pll si poti multiplica cu M si impartii la N ca sa obtii alte valori ale clock-ului, dar cele simple care nu au pll, de obicei au un oscilator RC de frecventa joasa, 32K sau 128K pentru aplicatii care nu necesita putere de procesare mare dar functioneaza pe baterii, si un oscilator RC de 8Mhz. (la seria AVR de exemplu) + oscilatorul cu quartz.

aceste oscilatoare RC asigura o precizie de ~ 1% care e suficienta in unele aplicatii, dar din pacate poate varia cu V/T.

daca alegi sa folosesti oscilatorul intern (care e de fapt un aplificator cmos inversor) pilotat cu quartz, sau sa-i dai un semnal de clock extern pe pinul XTAL1 (intrarea in aplificatorul CMOS) atunci va functiona cu cat ii dai extern, sau cu cat va oscila quartz-ul.

 

La procesoarele din seria 8051/8052 freceventa de la oscilator era divizata cu 12 inainte de CPU (deci fiecare MCU cu povestea lui) la Microcontollerele cu PowerPC poti sa stabilesti clock-ul la diferite blocuri CPU, BUS-uri, PCI, periferice separat prin scrierea unor registrii.

Daca-mi spui exact la ce MCU te referi pot sa-ti dau amanunte mai specifice.

RR

Link spre post
Distribuie pe alte site-uri

mersi de raspuns.

 

Mai am o nelamurire. Nu mai deschid alt topic.

Am vazut ca EEPROMul microcontrolerului atmega32 e impartit sau are mai multe adrese de genul 0x020...0x150 etc. O adresa are mai multe casute, parca vreo 16 casute unde se completeaza 00 sau FF. Daca fac programul astfel incat portul A, spre exemplu, sa citeasca adresa 0x020, cum se afiseaza semnalele la portul A care are 8 pini, cand o adresa contine mai mult de 8 casute?

 

stima

dan

Link spre post
Distribuie pe alte site-uri

hai s-o traduc, portul are 8 biti si adresa de eprom are 12 biti.

adresa e de fapt compusa din doua cuvinte de 8 biti, un octet high, si unul low (high=MSB low=LSB) in cazul tau din octetul high sunt folositi numai 2 biti mai putin semnificativi (LSB) restul sunt ignorati

deci trebuie sa construiesti adresa din doi octeti daca vrei sa acoperi tot spatiul de memorie Eeprom. Daca vrei poti sa tii octetul high constant si scrii numai pe cel LSB, dar vei acoperii numai 256 de locatii din spatiul total al EE.

Daca ti-e mai usor sa intelegi, poti considera octetul high ca o adresa de pagina (2 biti deci vei avea 4 pagini) iar octetul low ca o adresa in cadrul paginii (256 de locatii in fiecare pagina)

RR

 

cum se afiseaza semnalele la portul A care are 8 pini, cand o adresa contine mai mult de 8 casute?

prin doua afisari consecutive pentru octetul H, si L. (nu prea am inteles ce vrei sa zici cu afisezi, unde afisezi)

Editat de roadrunner
Link spre post
Distribuie pe alte site-uri

hai sa-ti spun ce vreau sa fac.

Am atmega32 si un port, sa zic portul B, care e intrare unde contectez 8 push butoane. Pe post de iesire e portul A, unde comand 8 relee. La un moment dat unele relee vor fi OFF altele ON, deci la iesirea portului A voi avea la un moment dat: 11011000. Apoi, daca se schimba starea celui de al doilea releu, iesirea va fi: 10011000. Eu vreau sa memorez asta in EEPROM, adica schibarea starii celui de al doilea releu sau la oricare releu, din cauza asta am intrebat mai sus cum scriu la aceeasi adresa schimbarea starii unui releu. Sau as putea folosi o alta adresa din EEPROM, dar daca fac asta, cum mai pot citi cu portul A adresele din EEPROM? Nu e mai simplu sa citesc o singura adresa dar nu stiu cum sa scriu schimbarea de care iti spuneam adineaori in EEPROM?

 

mersi de raspunsuri.

dator cred ca pana acum.. cu doua navete de bere! :hi:

 

stima

dan

Editat de dan_e
Link spre post
Distribuie pe alte site-uri

pai tii byte-ul HIGH din adresa de eprom 0x0, si lucrezi numai cu byte-ul LOW (practic reprezinti adresa pe un singur byte)

asta o sa-ti reduca spatiul de adresare la 256 de locatii. (practic adresele tale vor fi de la 0x000 la 0x0FF)

RR

 

PS - iti scriu eu doua trei linii de cod numa' sa ajung acasa (45Km)

RR

Editat de roadrunner
Link spre post
Distribuie pe alte site-uri
************

 

#include <avr/eeprom.h>

 

char valoare_port;

valoare_port=PORTA; //citeste valoare port A

eeprom_write_byte ((uint8_t *)(0x02),valoare_port); //scrie la adresa 0x02 in eeprom valoarea portului.

 

//invers citim inapoi din eeprom de la adresa 0x02

valoare_port = eeprom_read_byte ((uint8_t*)(0x02));

 

*********

 

imi cer scuze pentru intarziere.

success

RR

Editat de roadrunner
Link spre post
Distribuie pe alte site-uri

mersi de exemplu dar ceva ceva imi este neclar, adica tocmai randul asta din program:

eeprom_write_byte ((uint8_t *)(0x02),valoare_port);

Eu am mai multe bucle while, asa m-am gandit sa fac programul, conditionate de apasarea butoanelor. Deci, fiecare bucla while asteapta sa se execute daca se apasa un buton. Acum, cand bucla while, una din cele 8, se executa ea automat scrie in EEPROM (ramane sa vad exact cum cu ajutorul tau). Adica, cum fac sa scrie ca se modifica bitul 2 sau starea portului PA2 (a presupus ca portul A e iesire). Sa spunem ca prima oara se scrie in EEPROM lucru asta, ce fac cand se executa alta bucla while de la alt buton, si acolo am o instructiune care scrie in EEPROM si suprascrie aceasi adresa sau...???????????????????????????????????

 

La cum mi-ai spus tu, ar fi cam asa, poate gresesc, sa-mi spui:

se apasa primul buton de la portul B >>>> PORT A = 10000000 - se scrie valoarea asta in EEPROM;

se apasa al doilea buton de la portul B >>> PORT A = 01000000 - se scrie valoarea asta in EEPROM dar nu se pastreaza starea initiala, adica nu se memoreaza apasarea primului buton.

Eu asa am inteles ca face exemplu tau de program, dar poate am inteles gresit.

Editat de dan_e
Link spre post
Distribuie pe alte site-uri

corect, se suprascrie. (ppierzi valoarea veche din EEprom)

dar nu te impiedica nimic sa scrii la alta adresa daca nu vrei sa suprascrii.

RR

 

PS - programul meu nu face nimic, e numai un exemplu cum sa folosesti functiile din avr/eeprom.h

restul depinde de tine.

Editat de roadrunner
Link spre post
Distribuie pe alte site-uri

Bine, sa presupunem ca folosesc 8 adrese din EEPROM, cum le trimit la portul de iesire (portul A)? Sau, cand se intrerupe alimentarea montajului, cum citeste portul de iesire toate cele 8 adrese corect?

o adresa am inteles cum se citeste, cu exemplu tau, dar mai multe, nu!

 

stima

dan

Editat de dan_e
Link spre post
Distribuie pe alte site-uri

daca intrebarea e cum citesc 8 adrese consecutive din eeprom, atunci raspunsul e ceva de genul asta:

 

//char valori[8]; //definesti un array care in care sa citesti opt valori

//int i; //definesti o variabila

for (i=0;i<8;i++){

valori= eeprom_read_byte ((uint8_t*)(i)); //citesti in array din eeprom

}

 

 

valori[0] o sa contina ce ai memorat la adresa 0

valori[1] o sa contina ce ai memorat la adresa 1

...

valori[7] o sa contina ce ai memorat la adresa 7

 

Bine, sa presupunem ca folosesc 8 adrese din EEPROM, cum le trimit la portul de iesire (portul A)?

 

la intrebarea asta tu ai raspunsul, cum vrei sa le trimiti secvential in ordine credcatoare, descrescatoare la 1 secunda? tu decizi, eu nu stiu ce vrei tu sa faci.

 

RR

Editat de roadrunner
Link spre post
Distribuie pe alte site-uri

In ultima solutie propusa de roadrunner portul de iesire va citi cele 8 adrese si se va opri la ultima. Nici varianta asta nu te ajuta cu nimic.

 

dan, uite, am impresia ca nu prea ai inteles ce este o adresa. Un cod simplu de scriere in EEPROM ar fi de genul (am folosit platforma mikroC):

EEPROM_Write(0x150,0x55);               // Write some data at address 0x150

Hai sa-ti explic babeste.

In codul de mai sus 0x150 reprezinta o adresa de forma (al doilea rand de mai jos reprezinta adresa propriu zisa):

00	01	02	03	04	05	06	07	08	09	0A	0B	0C	0D	0E	0F
FF	FF	FF	FF	FF	FF	FF	FF	FF	FF	FF	FF	FF	FF	FF	FF

Orice adresa din EEPROMul unui uC pe 8 bit este codata dupa exemplu de mai sus: 01..0F si are valoarea FF atribuita implicit. Deci un rand FF inseamna o adresa. FF inseamna 0 logic, adica 0 volti pe pinii portului. Daca scrii 00 in loc de FF vei avea 1 logic, adica 5V pe toti cei 8 pinii a portului.

In codul de mai sus, la adresa 0x150 am zis ca scrii 0x55 in hexa, ceea ce in binar inseamna: 01010101. Tu spui ca portul A este iesire. Acolo ai PA0...PA7. Iei semnalul binar si treci la port astfel incat primul 0 a numarului binar pe care l-am scris se va atribui (cred ca nu gresesc!) portului PA7. PA6 va lua valoarea 1 s.a.m.d.

 

Spuneam initial ca nu poti sa folosesti mai multe adrese EEPROM, nu prea merge, deoarece nu te ajuta cu nimic. Ai putea sa folosesti o singura adresa si anumite valori binare care sa le transpui in hexa. Adica, pe tine de intereseaza 10000000, 01000000, 00100000... 00000001, ceea ce in hexa inseamna: 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01. In programul tau, pentru fiecare buton folosesti cate o data de asta. Iti alegi apoi o adresa din EEPROM, nu neaparat 0x150, poate sa fie 0x00. Si incepi ceva de genul asta, depinde ce compilator ai (in cazul tau inserezi o instructiune de asta de scriere in EEPROM in fiecare bucla while):

EEPROM_Write(0x150,0x80); 
EEPROM_Write(0x150,0x40);
...........
EEPROM_Write(0x150,0x01); 

Apoi trebuie sa inveti microcontrolerul sa-ti adune valoarea scrisa in EEPROM cu noua valoare aparuta si ai rezolvat problema. Spre exemplu, ai doua numere binare:

10000000 - la prima apasare a butonului 1 de la portul PB7 - conversia BIN in DEC = 128

01000000 - la apasarea butonului 2 de la PB6 - conversia BIN in DEC = 64

Daca adunam 128 + 64 = 192

Deci, avem noul DEC = 192 care inseamna in binar = 11000000, adica ceea ce vroiai tu, sa tina cont microcontrolerul ca ai apasat si butonul 1.

 

Acum mai trebuie sa scrii un cod care sa faca ce am spus eu mai sus.

 

Succes!

Editat de prog
Link spre post
Distribuie pe alte site-uri

@prog,

 

Cred ca nu v-ati gandit la partea cand portul de iesire va capata valoarea 11111111 (dupa 8 apasari consecutive ale butoanelor de la portul B) si se mai apasa inca o data un buton (aferent codul de iesire, de ex. 01000000). In acest caz, suma de care mentionezi la sfarsit nu mai este folositoare in program, deoarece de data aceasta microcontrolerul trebuie sa treaca iesirea 1 logic in 0 logic si daca aduna 11111111 cu 01000000 se va obtine 100111111 si nu 10111111 asa cum ar trebui. Deci, algoritmul tau e bun pana cand portul capata valoarea 1111111.

 

Numai Bine

Link spre post
Distribuie pe alte site-uri

donpetru ai dreptate, mai trebuie ceva.

 

Un uC pe 8 bit are maxim 255 DEC = 0xFF. S-ar putea introduce o instructiune if else unde dupa ce se aduna numerele si daca rezultatul e mai mare decat 255 sa nu faca adunare ci scadere. Spre exemplu, asa cum ai zis, daca se aduna 11111111 = 255 cu 01000000 = 64 rezulta teoretic 319 dar daca scad din 255 numarul dec 64 rezulta 191 = 10111111, ceea ce intereseaza. :thumbup3:

Link spre post
Distribuie pe alte site-uri

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
  • Navigare recentă   0 membri

    Nici un utilizator înregistrat nu vede această pagină.




×
×
  • Creează nouă...

Informații Importante

Folosim cookie-uri și tehnologii asemănătoare pentru a-ți îmbunătăți experiența pe acest website, pentru a-ți oferi conținut și reclame personalizate și pentru a analiza traficul și audiența website-ului. Înainte de a continua navigarea pe www.tehnium-azi.ro te rugăm să fii de acord cu: Termeni de Utilizare.

ATENTIE !!! Functionarea Tehnium Azi depinde de afisarea de reclame.

Pentru a putea accesa in continuoare site-ul web www.tehnium-azi.ro, va rugam sa dezactivati extensia ad block din browser-ul web al vostru. Dupa ce ati dezactivat extensia ad block din browser dati clic pe butonul de mai jos.

Multumim.

Apasa acest buton dupa dezactivarea extensiei Adblock