|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
lojzek Član
Pridružen-a: Pet 25 Jan 2008 8:00 Prispevkov: 3352 Aktiv.: 17.02
|
Objavljeno: Sre Sep 03, 2008 7:05 am Naslov sporočila: |
|
|
1. S pomočjo ata googla sem prišel do spoznanja, da je potrebno v eeprom najprej spremenljivke zaprogramirati (recimo z avr studiem). Pri prevajanju programa kompiler naredi datoteko za vpis v eeprom. Ali je to dvoje res?
2. Potem, ko so spremenljivke prišle v eeprom in se izvaja koda v uC, ali je možno, da uC sam spreminja vrednosti (na zahtevo programa) teh spremenljivk ali je treba nove vrednosti zopet vnesti s programatorjem?
3. Če lahko uC sam piše / spreminja vrednosti spremenljivk v eepromu bi pa rad, če kdo tukaj prilima kakšen že izdelan konček programa, ki bi to počel. Tako da bi vsaj vedel, katere besede / ukaze moram poiskati z googlom.
PS, tisto, kar je o eepromu omenjeno v tej temi, mi ne pomaga prav veliko.
Imam pa winavr. |
|
Nazaj na vrh |
|
|
alessio Član
Pridružen-a: Pon 04 Dec 2006 8:39 Prispevkov: 363 Aktiv.: 1.72 Kraj: Ljubljana
|
Objavljeno: Sre Sep 03, 2008 7:31 am Naslov sporočila: |
|
|
Ni nujno, da podatke v eeprom najprej vpišeš z programatorjem, če jih hočeš uporabljati v programu. Je samo dodatna opcija.
Normalna uporaba je ta, da MCU sam bere in seveda tudi piše v ta del pomnilnika. Če bi rabil samo branje, bi za to uporabil Flash.
Prednost EEPROM-a pred Flash-om je v tem, da ti omogoča zelo granuliran vpis podatkov, pri Flash-u lahko vpišeš minimalno en cel page,
kar je min. 512B (odvisno od čipa). V EEPROM pa se da zelo enostavno vpisati samo po 1B.
Če delaš z winarm toolchain-om, potem imaš med drugim za handlanje z eeprom-om že vse pripravljeno v knjižnici avr-libc. Poglej si user manual sekcija 6.13.
http://www.nongnu.org/avr-libc/
Sicer pa že dolgo ne uporbljam AVR-jev, odkar sem na ARM core-ih, tak da ti žal ne morem postreči s kakim primerom.
Aleš |
|
Nazaj na vrh |
|
|
dragoon Član
Pridružen-a: Čet 03 Maj 2007 21:51 Prispevkov: 452 Aktiv.: 2.20 Kraj: Trojane
|
Objavljeno: Sre Sep 03, 2008 7:42 am Naslov sporočila: |
|
|
1. če variabli nastaviš vrednost jo moraš zapisat z .eep filom ja. če pa variablo samo inicializiraš, in jo potem spreminja program med delovanjem pa ti ni treba zapisat .eep filea.
2. ja lahko spremija vrednosti, to je fora eeproma.
3. za winavr išči <eeprom.h>. za codevision ne rabiš nič. samo inicializiraš z besedico eeprom. uporabljaš isto kakor ostale variable. npr:
Koda: |
eeprom char a=3; //variabli a nastaviš vrednost, compiler naredi eep file
eeprom int b; // var samo inicializiraš.
......
a=b+2;
|
tukaj imaš primer izdelave ure. uporablja kvarc kristal 32khz in asinhroni timer2. attiny nima takega timerja, glej datashet mega8, mega16,.... _________________ LP, Mitja |
|
Nazaj na vrh |
|
|
lojzek Član
Pridružen-a: Pet 25 Jan 2008 8:00 Prispevkov: 3352 Aktiv.: 17.02
|
Objavljeno: Sre Sep 03, 2008 1:44 pm Naslov sporočila: |
|
|
Bom tole malce preštudiral in preizkusil. Malce jasneje mi je že.
Hvala obema za odgovor!
Branko
PS dragoon: Če prav razumem, tvoj primer v eepromu ustvari char a in mu da vrednost 3 (to začetno vrednost v uC vneseš s programatorjem). Nato v eepromu rezervira prostor za int b (ki ima ob začetku verjetno vrednost 0). Nazadnje pa vsoto b+2 uC sam vpiše v eeprom kot novo vrednost char a.
Ali sem razmišljal prav? |
|
Nazaj na vrh |
|
|
dragoon Član
Pridružen-a: Čet 03 Maj 2007 21:51 Prispevkov: 452 Aktiv.: 2.20 Kraj: Trojane
|
Objavljeno: Sre Sep 03, 2008 6:18 pm Naslov sporočila: |
|
|
tako je, v codevisionu. Pri GCC ni tako enostavno.
dolgo sem pisal, pa me je allesio prehitel. _________________ LP, Mitja |
|
Nazaj na vrh |
|
|
lojzek Član
Pridružen-a: Pet 25 Jan 2008 8:00 Prispevkov: 3352 Aktiv.: 17.02
|
Objavljeno: Čet Sep 04, 2008 10:40 am Naslov sporočila: |
|
|
Zopet sem se z vašo pomočjo naučil malce več, tokrat o uporabi eeproma.
Rešitev problema (za tiste, ki bodo naleteli na to težavo)
Z winawrom je uporaba eeproma malce drugačna kot v Codevisionu.
1. Najprej je treba vključiti knjižnico <avr/eeprom.h>
2. Nato pri deklaraciji spremenljivk na začetku programa tisto, ki bo v eepromu deklariraš takole:
Koda: |
EEMEM unsigned char eespremenljivka = 15; |
Deklariraš lahko tudi druge tipe spremenljivk, ključna je beseda EEMEM, ki kompilerju pove, da jo mora shraniti v eeprom. Tej v tem primeru je že prirejena vrednost 15 (vrednosti pravzaprav ni nujno prirediti)
3. v programu jo potem prebereš takole:
Koda: |
spremenljivka = eeprom_read_byte (&eespremenljivka); |
Byte prebere en znak, word bi prebral dva znaka
4. V eeprom bi novo vrednost napisal takole:
Koda: |
eeprom_write_byte (eespremenljivka); |
No, tega še nisem preizkusil, ampak nekako tako bi moralo biti.
Pri kompiliranju programa se ustvari eep datoteka. to je potrebno zapisati v eeprom.
Je pa pomemben vrstni red zapisovanja: najprej program (hex) v flash, šele nato vrednosti spremenljivk (eep) v eeprom. Če zamenjaš vrstni red, pri zapisovanju programa očitno izbriše vrednost eeproma in postavi vse vrednosti na 0xFF.
V pomoč mi je bil tudi ta tutorial:
http://winavr.scienceprog.com/avr-gcc-tutorial/save-constants-to-avr-eeprom-using-winavr.html |
|
Nazaj na vrh |
|
|
tadej.ko2 Član
Pridružen-a: Sre 17 Okt 2007 18:26 Prispevkov: 76 Aktiv.: 0.38 Kraj: sveta trojica
|
|
Nazaj na vrh |
|
|
lojzek Član
Pridružen-a: Pet 25 Jan 2008 8:00 Prispevkov: 3352 Aktiv.: 17.02
|
Objavljeno: Pet Sep 05, 2008 1:22 pm Naslov sporočila: |
|
|
Hvala tadej, tvoj link prikazuje sicer izvedbo s Codevisionom. Tukaj pa je razlika sintakse v primeri z winavr in mi ne ustreza. Saj princip sem si nekako že razjasnil, samo še izvedba me .
Trenutno me muči 4. točka iz mojega prejšnjega posta.
bolj pravilno (čeprav ne povsem) bi se glasila:
Koda: |
eeprom_write_byte (eespremenljivka, spremenljivka) |
Pravilno pa ni zato, ker sem po dnevu tuhtanja ugotovil, da novo vrednost v eeprom zapiše tja, kamor mu paše (enkrat tukaj, drugič tam...). Se pravi ne tja, kamor bi jaz želel.
Pa še eno kratko vprašanje: ali se da uC resetirati programsko? Se pravi, ko bi uC nekaj naredil, bi se programsko resetiral in začel program izvajati povsem od začetka?
EDIT:
Pa še prejšnjo 4. točko sem ugotovil.
Popolnoma pravilno se glasi:
Koda: |
eeprom_write_byte (adresa, vrednost) |
adresa pomeni kam naj shrani, vrednost pa tisto, kar bo na podano adreso zapisal.
Torej je potrebna previdnost, da v eepromu ne povoziš napačnih podatkov - dobra organizacija spomina.
Nazadnje urejal/a lojzek Pet Sep 05, 2008 1:48 pm; skupaj popravljeno 1 krat |
|
Nazaj na vrh |
|
|
bolha95 Član
Pridružen-a: Pet 14 Dec 2007 21:33 Prispevkov: 296 Aktiv.: 1.49 Kraj: Križe / Tržič
|
Objavljeno: Pet Sep 05, 2008 1:48 pm Naslov sporočila: |
|
|
lojzek je napisal/a: |
Pa še eno kratko vprašanje: ali se da uC resetirati programsko? Se pravi, ko bi uC nekaj naredil, bi se programsko resetiral in začel program izvajati povsem od začetka? |
Enostavno - aktiviraj watchdog
LP
R |
|
Nazaj na vrh |
|
|
lojzek Član
Pridružen-a: Pet 25 Jan 2008 8:00 Prispevkov: 3352 Aktiv.: 17.02
|
Objavljeno: Čet Sep 11, 2008 9:25 am Naslov sporočila: |
|
|
Imam novo vprašanje (do problemov še nisem prišel ).
Sedaj sem namesto Tinyja v testno ploščo vtaknil Mego in se začenjam igrati z AD pretvornikom. Berem razne tutoriale in user manual od Mege, tako da mi je princip delovanja AD pretvornika teoretično razumljiv.
Prišel sem do tega izseka kode:
Koda: |
ADCSRA |= (1<<ADSC)|(1<<ADIE); |
Razumljivo mi je, da ta vrstica v register ADCSRA na mesti bitov ADSC in ADIE vpiše vrednost 1, ne razumem pa matematično, kako to naredi- ni mi popolnoma jasna logika C-ja.
Vprašanja:
1. prvi operand |= verjetno pomeni, da se bo sprememba izvedla samo na dveh bitih, omenjenih v nadaljevanju funkcije, brez spremembe stanja ostalih bitov?
2. kaj dejansko naredi operand <<? Prebral sem, da naj bi premaknil bite v levo.
3. naslednji operand | : ali je nujno potreben, oziroma ali bi to kodo lahko ločil v dve vrstici kode na tem mestu?
4. ali kompiler (winavr) že sam po sebi ve, da je ADSC 6. bit in ADIE 3. bit? Brez da bi ju predtem moral kako definirati?
5. kako potem, ko bom prebral rezultat, podan v dveh bytih, iz teh dveh bytov naredim eno besedo (kateri matematični operand se za to uporabi). Primer: iz bytov 0x1E in 0xFF bi rad dobil 0x1EFF?
LP Branko |
|
Nazaj na vrh |
|
|
trot Član
Pridružen-a: Čet 18 Jan 2007 20:25 Prispevkov: 1270 Aktiv.: 6.07 Kraj: glej fogl
|
Objavljeno: Čet Sep 11, 2008 10:02 am Naslov sporočila: |
|
|
1: ADCSRA |= (1<<ADSC)|(1<<ADIE); <==> ADCSRA = ADCSRA|(1<<ADSC)|(1<<ADIE);
2: to je shift operator
3: to je logični OR operator
4: ne ne ve, to ima zapisano v headerjih kot makro, npr
. To pomeni, da v fazi prevajanja na mesta kjer piše ADSC zapiše 6.
5: (0x1E<<8-)+0xFF
Malo preštudiraj osnove c-ja, npr tole _________________ lp, Klemen |
|
Nazaj na vrh |
|
|
lojzek Član
Pridružen-a: Pet 25 Jan 2008 8:00 Prispevkov: 3352 Aktiv.: 17.02
|
Objavljeno: Čet Sep 11, 2008 10:26 am Naslov sporočila: |
|
|
Hvala za hiter odgovor, ampak se mi je še nekaj vprašanj porodilo.
2. če normalno shiftaš samo 1 bit, ga dejansko zbrišeš. Ali potem ta izraz 1<<ADSC "postavi 1 pred bit ADSC in potem zashifta tako, da pride 1 v ADSC"? Malce pesniško sem opisal, ampak upam da je razumljivo.
3. to vem, ampak ali v tem primeru OR ločuje dve operaciji, ki se izvedeta ena za drugo? Torej bi lahko to kodo razdelil na dve vrstici?
4. Ali je torej potrebno #include kakšno knjižnico, ali je že dovolj da winavrju poveš, da delaš z Mego? Ker sem testno to vrstico prevedel in ni bilo napak...
5. To bom pa preizkusil v nadaljevanju |
|
Nazaj na vrh |
|
|
trot Član
Pridružen-a: Čet 18 Jan 2007 20:25 Prispevkov: 1270 Aktiv.: 6.07 Kraj: glej fogl
|
Objavljeno: Čet Sep 11, 2008 10:43 am Naslov sporočila: |
|
|
2: nisem razumel. Naredi pa tako, 1 v binarnem je 00000001. To potem 6x premakne v levo in z desne dodaja ničle. Tako potem dobiš v binarnem 01000000.
3: lahko bi napisal dve vrstici: ADCSRA = ADCSRA|(1<<ADSC); ADCSRA = ADCSRA|(1<<ADIE); Edini efekt tega je več pisanja.
4: mogoče že sam doda knjižnico, ko v makefile-u izbereš čip. _________________ lp, Klemen |
|
Nazaj na vrh |
|
|
upornik Član
Pridružen-a: Ned 09 Jan 2005 22:35 Prispevkov: 261 Aktiv.: 1.18 Kraj: Celje
|
Objavljeno: Čet Sep 11, 2008 11:23 am Naslov sporočila: |
|
|
Lojzek, glede bitnega naslavljanja z maskami je tudi mene mučilo v tej temi, zato bom sem še enkrat prilepil odgovor Domeniusa, ki sem ga takrat dobil, meni je razjasnil maske.
Citiram: |
Če hočeš spremeniti stanje celega porta pošlješ nanj nek bajt oz. 8 bitov. Tukaj ni nič problemov z maskami. MSB bit spremeni PORTX.7, LSB bit poslanega bajta pa PORTX.0. Če pa hočeš spremeniti stanje samo enega pina brez da bi vplival na ostale moraš uporabit maske.
PORTC |= 0x20; v bistvu pomeni PORTC = PORTC | 0x20;, samo da je krajše napisano. Ta operacija postavi nek bit (0x20 je peti bit, ker je 0x20 enako 32 - 2 na 5 potenco je tudi 32, od tod torej peti bit) na 1. Tista črta pomeni logično operacijo OR. In ker je 0 OR X = X in 1 OR X = 1 se postavi bit samo tam kjer je enica, ostali pini pa ostanejo v takšnem stanju kot so.
Enako je pri PORTC &= ~0x20; - to pomeni PORTC = PORTC & ~0x20;. Ta operacija postavi pin na 0. Znak & pomeni logično AND operacijo, znak ~ pa negacijo. Namesto ~0x20 bi lahko napisal tudi 0xDF, je čisto enako, samo takšen način z negacijo se meni zdi bolj pregleden. Ker je 0 AND X = 0 in 1 AND X = X se pin postavi na nič samo tam kjer je ničla v poslanem bajtu, kjer so pa enice se pa stanje ohrani (X). Za boljše razumevanje tega napiši par programčkov z maskami in brez in jih testiraj v simulatorju AVR Studia pa boš videl razliko.
Napačno krmiljenje porta: če boš na port poslal 00000010 brez maske se bo drugi pin postavil na 1, ostali pa na 0 - če boš pa na npr. četrtem pinu spremljal stanje pina (vhodni pin) in bo pred pošiljanjem bajta na port stanje vhodnega pina 1 se bo pojavila napaka - ne programska ampak pri odčitavanju vrednosti. |
|
|
Nazaj na vrh |
|
|
lojzek Član
Pridružen-a: Pet 25 Jan 2008 8:00 Prispevkov: 3352 Aktiv.: 17.02
|
Objavljeno: Čet Sep 11, 2008 11:46 am Naslov sporočila: |
|
|
@ upornik, vse to se že prebral in tudi nekako razumem . Pravzaprav vsakič, ko imam težavo, preberem celo temo.
@ trot: Aha sedaj razumem 2. točko. Pravzaprav izvede bitni OR med obstoječo vsebino registra ADCSRA in 6× v levo zašiftano 1 (0b0100000). Nato pa še ponovi enako operacijo s 3× zašiftano 1.
Povsem enak efekt bi torej dobil tudi z maskami. Npr. ADCSRA |= 0b01000100 |
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 48 dni
Powered by phpBB © 2001, 2005 phpBB Group
|