Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ATmega168 7-Segmentni Display
Ma Forth je cudo, ne opirem se toliko, pa prvo sto sam gledao je bio Forth za STM32, ima gotov, mož' misliti kako radi, razbija ...
Ajd sad sto ti to nisi probao nego si uzeo C/C++? : )  I jos da mu namestis FRAM da pamti reci u jos jedno 256k!?
I da kompajlira na samom sebi, i da ima mala web konzolica za kuckanje i ceo IDE da povuce sa CDN kroz JavaScript ... : )
Sad je mozda pravo vreme da ti probas Forth, sad ti je STM32 platforma potpuno jasna, kako bi izlgedao Forth sad za to? Mora da se proba ...
Ili Texas-ov ARM sa FRAM-om u sebi vec?

Vidi sledece, ako je izvodljivo odraditi TCP/IP sa soket konekcijom na MCU, moze da se iza toga u WEB okruzenju (on/off line) odradi kompletna logika za upravljanje i podesavanje sa svojim grafickim GUI skoncanim u HTML/JS. Ima tu neki Gospodin JSON i Gospodja REST koje prave celu pricu, programibilni API i sve preko toga moze da se odradi i sto je najlepse da radi taj GUI bukvalno na telefonu ...

U prilogu Blinky LED za Discovery u Forth-u, ko ovo razume blago njemu ... : )


Attached Files
.txt   FISH_STM32F4_DISCO_BLINKY_ByVic.txt (Size: 1,64 KB / Downloads: 16)
Reply
Pogledao sam onako na brzinu Forth ali ostat cu na ASM...jer ako cu se svako malo prebacivati sa kompilera na drugi necu nista da naucim Smile Hvala za Forth preporuku mozda kojom drugom prilikom krenem na njega...

E sad vrlo zanimljivo sto mi se dogadja pa ako ima objasnjenja zasto to tako ne radi, dakle inicijalizacija timer mi je bila problem:

; Timer1 Init
ldi yh, 0x05                            ; Prescaler 1024 (CS12, CS11, CS10 = &b00000101)
sts TCCR1B, yh
ldi yh, 0x01
sts TIMSK1, yh                       ; Enable Timer1 Overflow Interrupt
ldi r16, HIGH(0xB9B0)             ; Timer1 - 0xB9B0 (1sec)
sts TCNT1H, r16
ldi yl, Low(0xB9B0)
sts TCNT1L, yl

Dakle linija:

ldi r16, HIGH(0xB9B0)             ; Timer1 - 0xB9B0 (1sec)
sts TCNT1H, r16

- na početku sam imao umjesto r16 stavljeno yh CPU registar koji po inc filu za ATmega328P iznosi r29, i sa time yh LED blinka 4sekunde umjesto 1. Stavil li bilo koji od ova 6 registra:

; ***** CPU REGISTER DEFINITIONS *****************************************

.def XH = r27
.def XL = r26
.def YH = r29
.def YL = r28
.def ZH = r31
.def ZL = r30

LED blinka 4sekunde....i onda g.vojinilic lijepo posalje ovdje kod iz simulatora gdje je koristio r16 registre u ovom primjeru i led blinka tocno 1sekundu...tocno ko sat.

E sad me zanima zasto CPU registri X Y Z (ja najvise koristim yh uvijek i yl ako je gdje low byte) sa njima je tako veliki delay? Ipak su to registri po kojima se pise i cita...e to mi nije jasno...r16 definiran u m328p.inc nisam nigdje vidio pa me to tek buni ako moze malo pojanjenje...dakle jedino delay radi sa r16 ako stavim bilo koji od CPU registra delay 4sec. Zasto je to tako neznam....ali imao sam sliku da koristenjem tih 6 cpu registra pohranjujem i citam varijable  i oni za to sluze i da nemaju nikakv utjecaj na izvrsavanje programa...sad mozda dok ne nadjem u datasheetu mu treba tako dugi vremenski jump za te 6 CPU instrukcije da se oduzi LED blinkanje ili je nesto trece?

Program po ostalome radi fantasticno. Ima svega 35 Worda....HEX file je veliki 248bytova i dosad najmanji sto sam dobio...to mi govori da je optimizacija dobra (vjerujem da jos ima prostora da se optimizira na odlicnu ali problem je sto treba da jos vidim gdje bi se jos sto moglo da se ustedi pokoji word a da program se izvrsava brzo i tocno...trazim po netu kako se u avrasm2 ukljucuje optimizacija kod kompiliranja pa mozda i tu dobim jos manji efikasniji kod)

Nego da pitam citam sada malo za CTC Mode velika vecina ga koristi (Clear Timer On Compare) jeli to bolje rjesenje od ovog sto sada imamo napisano? Sa ovom naredbom samo na pocetku postavim vrijednost timer1 brojaca i dalje se kod interrupt overflowa sam brojac resetira i postavi na pocetnu vrijednost brojaca koja je od prije postavljena....ovo mi zvuci da malo preuvelicam odlicno...i mislim da je korak jos jedan k optimiziranom timeru...

Dakle zanima me teorijski ono što je mikikg napisao da se upise jedan bit na port bez read-modify-write ovo mi izgleda bas kao CTC tj slicno..jednom upises vrijednost na početku programa od koliko timer treba da broji i on onda samo cita to sa memorije...dakle ustedi se par Worda i par cyclova koji su AVR-u sada potrebni da upise ponovo u registar vrijednost brojaca od kojeg broja da pocne da broji i tu mislim da bi ovaj CTC rjesio stvar na bolje.
Reply
(04-04-2018, 12:14 AM)Macola Wrote: Šta misliš u čemu Mlađa programira test sisteme sada u Apple (preuzeli su ga iz Dialog Semiconductors već početkom godine)?
A znaš da Mlađa piše vrhunski u bar 15 jezika...

Test sisteme za sta tacno? Hvala.
“If you think you are too small to make a difference, try sleeping with a mosquito.” - Dalai Lama XIV
Reply
Ronovar,

lepo si primetio da su X, Y i Z registri smesteni na donje lokacije R resitara. Oni se koriste za indirektno adresiranje. Kada upises nesto u njih to znaci da pokazujes na neku memorijsku lokaciju. Npr. ako u par Yh i Yl upises 0x0000, to znaci da pokazujes na adresu 0. Evo konkretnog primera na tvom kodu:

ldi yh, 0x05 ; Ovde si upisao 5. To znaci da je sada pokazivac na memorisjku lokaciju 5
sts TCCR1B, yh ; Ovde si sadrzaj sa memorijske lokacije 5 prebacio u TCCR1B

Zbog toga ti nije dobro inicijalizovan TMR. Ti zelis da koristis direktan pristup memoriji. Onda koristis registre od R0-R.. (ne znam koji broj napamet). Mozes da definises i korisnicki registar u RAM memoriji:
.DSEG
TempPromenljiva: .BYTE 1 ; Rezervisi 1 bajt u data prostoru za promenljivu koju si nazvao TempPromenljiva.

Mozes i ovo da uradis:
.DSEG
TMR1_Value_H: .BYTE 1
TMR1_Value_L: .BYTE 1

ldi TMR1_Value_H, HIGH(0xB9B0) ; Timer1 - 0xB9B0 (1sec)
ldi TMR1_Value_L, LOW(0xB9B0)

sts TCNT1H, TMR1_Value_H
sts TCNT1L, TMR1_Value_L
Reply
Evo kao mala dopuna, ovog na šta ti je Vojin skrenuo pažnju, jedan dokument koji opisuje načine adresiranja kod AVR familije:

https://www.csee.umbc.edu/~alnel1/cmpe31...gModes.pdf

Pisao sam ti već da su ti X,Y i Z korisni kao pokazivači na memorijske lokacije. Sačuvaj ih za tu namenu a ostale registre koristi za "svakodnevne" stvari. Programi će ti zahtevati i neke matematičke operacije, rad sa nizovima ... a tu su ti pokazivači nezamenljivi.
Reply
(04-04-2018, 09:53 AM)gorankg Wrote: Evo kao mala dopuna, ovog na šta ti je Vojin skrenuo pažnju, jedan dokument koji opisuje načine adresiranja kod AVR familije:

https://www.csee.umbc.edu/~alnel1/cmpe31...gModes.pdf

Pisao sam ti već da su ti X,Y i Z korisni kao pokazivači na memorijske lokacije. Sačuvaj ih za tu namenu a ostale registre koristi za "svakodnevne" stvari. Programi će ti zahtevati i neke matematičke operacije, rad sa nizovima ... a tu su ti pokazivači nezamenljivi.

Gorane,

odlican dokument.
Ronovar, pazljivo prouci dokument koji je Goran dao. Kao sto je rekao, rad sa nizovima zahteva indirektno adresiranje. Ako registre za indiretno adresiranje koristis za direktno adresiranje, nikada neces znati sta se nalazi u registru, posto se u njemu nalazi podatak sa adrese na koju pokazuje upotrebljeni X,Y ili Z regista.
Reply
Sad mi je puuno jasnije..koristio sam indirektno adresiranje a to se koristi za pokazivanje na memorijsku lokaciju gdje se cuva vrijednost, za matematicke funckije itd...normalno da nije moglo tako da radi... po ovom tutorijalu koji pratim sve lijepo pise:

http://www.avr-asm-tutorial.net/avr_en/b...index.html

Dakle Svaki AVR ima 32 registra koji počinju od 0 pa do 32..tako da mogu da koristim od R0 pa do R31.

Ja sam na početku programa definirao:

.DEF rh = R16
.DEF rl = R17
.DEF rs = R18
.DEF rp = R19
.DEF rr = R20

i kasnije samo pozivam rh rl rs rp ili rr koje pristupaju direkt registrima. Skracenice sam si nazvao tako zbog ovih naziva:

rh => Register High (Value)
rl => Register Low (Value)
rs => Register Store (From SREG)
rp => Register Port (Read From Port DDRx Value)
rr => Register Restore (Restore From Register to SREG)

Nadam se da je tako ok, lakse ce mi biti nego da uvijek pisem R16 pa gdje trebam da radim kompare da pisem R17, R18 ovako lijepo stavim cmp rp, 255 i to je to...ako ima laksi ili bolji nacin oznacavanja ili je bolje da koristim R16...R20 napisite kako bih sada kada ucim znao koja je bolja metologija.

Evo BAS coda koji sam po gore codu postavio pa ako nema primjedbi na gore oznacavanje ja bih krenuo na sljedeci korak a to je multipleksiranje 7Seg displaya ali zasada bih stavio na stranu slanje podataka nego bih palio i gasio 3 LED diode koje se kao po shemi u prvom postu nalaze na PB0 do PB2 jer to mi je jakoo bitno posto paljenjem i gasenjem ledica kasnije zamjenim sa NPN tranzistorom i time ce se odabirati trenutni segment koji ce se paliti/gasiti...

Za paljenje/gasenje 3 LED diode segmenta nije mi jasno kako treba da bude pa cu napisati teorijski kako sam shvatio da treba da bude ako je to pravilno:

Kod povezivanja MCU na napajanje SVE 3 LED diode su OFF nakon sto timer napravi interrupt:

- UPALIM 1 LED ostale su ugasene

izadjem iz timera nakon sljedeceg interrupta:

- GASIM 1 LED palim 2 LED ostale ugasene

izadjem iz timera nakon sljedeceg interrupta:

- GASIM 2 LED palim 3 LED ostale su ugasene:

Dakle tablicom interrupta bi se to moglo ovako da prikaze:

LED1  LED2  LED3
0        0       0
1        0       0
0        1       0
0       0        1

I tako u loop dakle svaki redak u tablici je uzeti za stanje LED-ica kad se timer oveflow pokrene jesam li dobro razumio? I kasnije se to ubrza na 100HZ ili vise (ovisno u praksi kako ce biti bolje) i to bude to...jeli tako ok?


.rar   LED_BLINK.rar (Size: 635 bytes / Downloads: 1)
Reply
(04-04-2018, 07:03 AM)1van Wrote:
(04-04-2018, 12:14 AM)Macola Wrote: Šta misliš u čemu Mlađa programira test sisteme sada u Apple (preuzeli su ga iz Dialog Semiconductors već početkom godine)?
A znaš da Mlađa piše vrhunski u bar 15 jezika...

Test sisteme za sta tacno? Hvala.

Napravio je test bench za dubinsku analizu jednostrukih i višestrukih SMPS napajanja za aplikacije poput telefona, notebooka, CPU napajanja i slično.
Analizatorski uređaj, sa jednim inženjerom rukovaocem spuca za pola sata ono što je se neposredno pre toga, sa timom od nekoliko inženjera, radilo mesec dana.

Analize obuhvataju: analize EMI, analize ekstremnih uslova rada, analize odziva na load i Vin, analize stabilnosti i tako to...
Hardver je naravno konstruisao sam i vodi ga pomoću kontrolera koji je pisao u Forth.
Reply
(04-04-2018, 12:30 AM)mikikg Wrote: Ma Forth je cudo, ne opirem se toliko, pa prvo sto sam gledao je bio Forth za STM32, ima gotov, mož' misliti kako radi, razbija ...
Ajd sad sto ti to nisi probao nego si uzeo C/C++? : )  I jos da mu namestis FRAM da pamti reci u jos jedno 256k!?
I da kompajlira na samom sebi, i da ima mala web konzolica za kuckanje i ceo IDE da povuce sa CDN kroz JavaScript ... : )
Sad je mozda pravo vreme da ti probas Forth, sad ti je STM32 platforma potpuno jasna, kako bi izlgedao Forth sad za to? Mora da se proba ...
Ili Texas-ov ARM sa FRAM-om u sebi vec?

Vidi sledece, ako je izvodljivo odraditi TCP/IP sa soket konekcijom na MCU, moze da se iza toga u WEB okruzenju (on/off line) odradi kompletna logika za upravljanje i podesavanje sa svojim grafickim GUI skoncanim u HTML/JS. Ima tu neki Gospodin JSON i Gospodja REST koje prave celu pricu, programibilni API i sve preko toga moze da se odradi i sto je najlepse da radi taj GUI bukvalno na telefonu ...

U prilogu Blinky LED za Discovery u Forth-u, ko ovo razume blago njemu ... : )

Nisam naskočio na Forth iz istog razloga kao i ti :-)
Već sam bio zagazio u Basic tada, osećao otpor prema obrnutoj konotaciji i bio dovoljno lenj pored dva vrhunska učitelja u okruženju: tvog oca i Mlađe.

I žestoko se kajem prijatelju. A otpor je sad neuporedivo veći nego nekad...

Neki dečak, video sam na medijima, fenomenalno vozi bicikl naopako.
Od početka je tako pokušao i naučio.
Njemu je to smešno lako a nama to izgleda ludo teško...
Početak treba da se dogodi na početku baš i onda postaje prirodno okruženje.

Inače, u onom Blink-led primeru je samo poslednjih nekoliko redova definicija za blink-led, a sve ono iznad je inicijalizacija AHB, pinova i par sitnih alata, što se inače mora uraditi ma u čemu pisao i u stvari su uglavnom asm kod.

STM32 nije optimizovan za Forth, mada može da ubija u Forth-u, a pogledaj šta se koristilo za vrlo gadne aplikacije sa predisponiranim MCU i pogledaj mu smešne hardverske resurse u odnosu na premoćni 32F4, a obavezno pogledaj i za šta se koristi:

https://www.google.rs/url?sa=t&rct=j&q=&...2YyXeeFlX5

Jbg, za uskakanje u Forth je potrebna hrabrost i vreme i početnik se najlakše i najbrže prilagođava.
Moraš da priznaš da je veoma lepo kad su ti svi potrebni alati u samom MCU i kad možeš u letu da programiraš i probaš. Cena velikog truda za pravljenje sopstvenih alata posle bude i više nego opravdana.

Pozz
Reply
Malo ja iz busije kao totalni outsider, googlajući našao ja neki forth za Cypressove PSOC MCUe.

https://en.wikibooks.org/wiki/Forth/PSoC...evelopment
Reply
Evo dok se ceka odgovor (kada se nadje vremena) ja se poigrao za CTC i mogu reci da mi se ova AVR Arhitektura svida sve vise i vise...sada sam presa na HW Interrupt, znaci razlika je da CTC (Clear Timer On Compare) kada dodje do zadane vrijednosti countera automatski HW resetira pocetni brojac na 0 i kada se interrupt zavrsi odmah krene brojiti od 0 pa do postavljenog broja timera koji je u mome slucaju 18000. Znaci ide 0 broji do 18000 pozove Clear Timer On Compare A Interrupt HW postavlja zastavicu timer countera automatski na 0, tu palim/gasim LED...onda izlazim iz interrupta i timer opet pocne brojiti od 0 do 18000 i tako u loop...dakle time sam izbjegao Reload Timer Pocetne vrijednosti u interruptu i kod je optimiziran sa 260bytova na 244bytova...jedina razlika je da se kod racunanja timera vise ne oduzima od 65536 dobivena vrijednost nego se izracunata vrijednost stavlja da broji do te vrijednosti jer timer broji od 0 pa do te vrijednosti a sa obicnim interruptom broji od postavljene vrijednosti do 65536 dakle tu je samo razlika.

Evo asm i hex pa mozete u proteusu sa osciliskopom vidjeti vrijeme koje je tocno 1sekundu.

Eto molim da ako se moze jos optimizirati (ja neznam vise sto bih mogao) da se napise ovdje ali mislim da sam timere "doktorirao" Smile

Naravno salu na stranu..kod timera ima jos puno tu ... ima counter, pa Capture, Interrupt i Compare A i B...sve lijepo pise u datasheetu avr-a...jos mi je zanimljivo da i ima vanjski HW interrupt..npr imas lemnu stanicu ode ti thermocoupler i sa svojeg otpora npr 17R padne na 0R i radi "kratak spoj" moze se staviti interrupt da odmah na 7 Segmentnom displayu prikaze S-E (Senzor-Error) jer je kratak spoj na thermocoupleru aktivira externi interrupt u AVR-u...kazem samo da sam ja tek okosio mali dio timera sto on moze..a to su ogrooomne mogucnosti..evo koda pa ako ko sto zna da se jos bolje optimizira slobodno napise..ja vise neznam sto bih tu mogao da optimiziram mislim da je za HW timer to to...dakle sve se radi HW nista SW vise...


.rar   Projects.rar (Size: 1,63 KB / Downloads: 7)
Reply
Kako se definira array u assembleru i popunjuje sa zadatim vrijednostima? Ja sam pokušao ovako:

.DSEG
digit: .Byte 9 ; 7 Segments Digits

I u Reset funkciji nakon initilizacije stack pointera popunjavam array:

; load 7 segments digits into array (&h3f, &h06, &h5b, &h4f, &h66, &h6d, &h7d, &h07, &h7f, &h6f)
ldi xl,byte1(digit)
ldi xh,byte2(digit)
ldi zl,0x3f
st X+,zl
ldi zl,0x06
st X+,zl
ldi zl,0x5b
st X+,zl
ldi zl,0x4f
st X+,zl
ldi zl,0x66
st X+,zl
ldi zl,0x6d
st X+,zl
ldi zl,0x7d
st X+,zl
ldi zl,0x07
st X+,zl
ldi zl,0x7f
st X+,zl
ldi zl,0x6f
st X+,zl

Dakle učitavam array pointer u registre xl i xh (2x8bit), ulitavam vrijednosti segmenta u zl registar i postavljam u SRAM vrijednost jednu za jednom jer RAM nije definirani kao array nego ide vrijednost po vrijednosti...sa X+ zapisujem na sljedecu adresu vrijednost i povecavam pointer(pokazatelj na sljedecu memorijsku lokaciju) na koju ce se zapisati sljedeci podatak iz indirektnog CPU registra zl...dakle sad koristim indirektno adresiranje.

Sad me zanima dali je tako ok i koji je pravilni način? u .DSEG sam definirao 9 bytova u memoriji veličinu arraya koji ce mi sadrzavati brojke od 0 do 9 dakle tocno 9 bytova.

UPDATE:

X Y registri su SRAM lokacije a Z je Program Memory ili ti FLASH lokacija...tako da gornji kod:

ldi zl,byte1(63) ; LOAD - &h3f To Program Memory
st X+,zl ; STORE - &h3f From Program Memory Into SRAM location

Dakle stavljamo &h3f (63dec) vrijednost u programsku memoriju i zatim iz programske memorije kopiramo u SRAM poziciju i incrementiramo SRAM brojač X+....sad me zanima zasto se u ovom primjeru direktno ne upisuje u SRAM? Npr ovako:

ldi yl, LOW(&h3f)
st X+, yl

Tako bi direktno upisali u SRAM vrijednost 3f i samo bi kao u kodu inkrementirali X+ brojac SRAM lokacije da zapisuje array vrijednosti jednu za drugu...time bi kod bio kraci a i vjerujem da je vrijeme citanja iz Flasha 3cycle a SRAM-a 2cycla koliko sam uspio naci info u datasheetu...dakle ovako gubimo 5cycle za upis jedne array brojke iz Flasha u SRAM a ako bi direktno upisivali u SRAM dosli bi na 3cycle sto mi puno logicnije izgleda..pa molim objasnjenje zasto nebi isli direktno upisivat u SRAM?
Reply
Može ovako kako si napisao ali činiš dve greške:
- ponovo koristiš zl
- članovi tvog niza su po prirodi konstante a ti ih smeštaš u SRAM. Bolje je da konstante idu u FLASH a SRAM čuvaj za promenljive. Istina, čitanje iz FLASH-a je za jedan intrukcijski ciklus sporije nego iz RAM-a ali to nije presudno za tebe trenutno.

.CSEG
digit: .DB &h3f, &h06, &h5b, &h4f, &h66, &h6d, &h7d, &h07, &h7f, &h6f

Probaj ovako. Nisam 100% siguran ali tako nešto treba da ide.

Ovo ti je trenutno najbolja literatura:

http://ww1.microchip.com/downloads/en/De...01917A.pdf

ATMEL Studio treba da ima simulator. Pokreni ga i idi korak po korak po programu dok istovremeno pratiš registre od interesa. Tako se najbolje uči asembler.
Reply
Evo koda:

.DSEG
     decimal: .Byte 9


.CSEG

.ORG 0x0000
     rjmp _Reset

_Reset:
     ldi r16,byte2(RAMEND)
     out SPH,r16
     ldi  r16,byte1(RAMEND)
     out SPL,r16

     ldi xh,byte2(decimal)
     ldi  xl,byte1(decimal)
     ldi  r16,0x3f ; 0
     st X+,r16
     ldi  r16,0x06 ; 1
     st X+,r16
     ldi r16,0x5b ; 2
     st X+,r16
     ldi  r16,0x4f ; 3
     st X+,r16
     ldi  r16,0x66 ; 4
     st X+,r16
     ldi  r16,0x6d ; 5
     st X+,r16
     ldi  r16,0x7d ; 6
     st X+,r16
     ldi r16,0x07 ; 7
     st X+,r16
     ldi r16,0x7f ; 8
     st X+,r16
     ldi r16,0x6f ; 9
     st X+,r16

Slika iz simulatora je prilozena i kao sto se vidi na memorijske lokacije su upisane sve tocno vrijednosti koje trebaju...jeli sada tako ok? Izbacio sam Y jer vidim da se on koristi za program memory....i tu uvijek radim gresku...znaci na pocetku xh i xl ucitaju velicinu arraya rezerviraju velicinu arraya u SRAM-u, zatim upisujem u registar R16 vrijednosti brojeva od 0 - 9 za 7 Segmentni Display i pomocu naredbe st (Store) upisujem iz registra R16 u SRAM (memoriju) na prvu rezervirani index lokaciju a to je 0x0100 zatim sa X+ se povecava index za jedan tj incrementiraj brojac na sljedecu memorijsku lokaciju...upisujem u registar R16 novu vrijednost pa preko st narede upisujem na drugu memorijsku lokaciju i tako u loop do se ne upise svih 10 hex vrijednosti 7 segmentnih brojeva...

Posebno na slici primjetiti kako su lijepo upisani brojevi u SRAM (fantasticno je ovo...raditi preko SRAM-a jest malo kompleksnije ali je za 1 cycle brzi od spremanja konstane u flash...znam da mi sada netreba ta brzina ali kad vec ucim da naucim kako treba...kad tad ce mi trebati pisanje i citajne iz SRAM-a)

Reply
Trebao bih pomoc oko ovog koda...uspio sam srediti osvjezavanje 7 segmentnog displaya i to radi odlicno u Proteusu...ali imam problem citanje vrijednosti iz SRAM-a varijable therm pa ako moze pomoc kako da je ocitam ispravno u timer1 interruptu posto mi je zamisao da kada ovo proradi timer0 ce da radi interrupt svakih 500mS, očitava sa MAX6675 vrijednost temperature (dakle vraca HEX vrijednost) i pohranjuje je u varijablu therm koja je globalna i definirana je u .DSEG byte 2 (byte 1 bi bio samo od 0-255 a byte 2 mi dozvoljava punoo vecu velicinu posto ce se temperatura kretati od 0 - 500)....pa me zanima kako da postavim tu varijablu da je onda timer1 koji je zaduzen za osvjezavanje 7Seg Displaya pokupi dekodira svaku znameknu i iz arraya ocita dekodirani segment broj i prikaze tj upali odredjene znakove na segmentu?

Umjesto Timer0 sam u Loop petlji upisao u SRAM vrijednost 0x1B5 sto treba da je decimalno 437 sto treba da bude vrijednost therm varijable u cijelom programu i da se prikaze da displayu..meni se u proteusu prikazuje stalno 267 dakle nisam dobro upisao ili citao varijablu therm....pa ako moze mala pomoc posto mi je ostalo jasno...

Evo i programa i HEX...


.rar   Projects.rar (Size: 1,56 KB / Downloads: 1)
Reply
Prekidna rutina Tajmera1 (kao i sve druge prekidne) treba da bude što kraća. Ova računanja pojedinačnih cifara radi u glavnoj petlji nakon što pročitaš vrednost therm iz MAX6675.
Dekodirane vrednosti pojedinačnih cifara smesti u zasebne registre. Prekidna rutina treba da radi samo sa tim registrima nikako sa therm.
Velika je greška kada se jedna promenljiva ( globalna ) javlja u dve ili više zasebnih funkcija od kojih je jedna prekidna. Ti nikada ne možeš biti siguran sa kojom vrednošću ti onda barata prekidna rutina. Šta ako se prekid dogodi između ove dve linije koda?

    sts        therm, XH
    sts        therm, XL

Šta je u tom slučaju tačna vrednost therm? Tvoj slučaj je trivijalan jer ćeš već u narednom prolazu imati ispravnu vrednost na displeju ali šta ako nešto drugo radiš sa tom promenljivom therm? Recimo da je ona ulazna promenljiva za neki proces koji vodi alat od par stotina kilograma ili šta god što je mnogo opasnije od prikaza na LED displeju.
Temperaturu ne moraš da očitavaš sa tom učestanošću jer to nije veličina koja se tako brzo menja. Pokušaj da što više stvari izmestiš iz prekida tajmera1.
Reply
U prilogu postavljam uredjeni kod...dakle registre R23 R24 i R25 sam koristio u glavnoj petlji da postavim koji kod mora ici na segment (posto su registri 8-bitni i ja imam cifre od 0-9 su mi 8 bitne to mi je savrseno da cuvam vrijednost svake cifre u registru...). Tu sam stavio sto se moze vidjeti u kodu racunanja modulo funckije 0x1B5 iz razloga sto kad budem isao na pisanje koda za citanje temp vrijednosti iz MAX6675 budem vidio kako cu ih spremati....i ovaj kod radi hex 1B5 je dec 437 sto mi tocno pokazuje display u proteusu...u glavnoj loop petlji nisam postavio nikakav delay niti nikakvu prekidnu routinu..tu se vrti loop koji ce da cita vrijednost sa senzora i izracuna koje brojke treba da budu upaljene u kojem segmentu i upisuje ih u registre R23 R24 i R25.

Prekidna routina Timer1 je sada upotrijebljena samo za inkrement brojaca za +1 i gasenje svih znamenki i citanje iz registra ovisno o segmentu (brojaca) upisa na PORTD i paljenjem samo tog segmenta. Kada dodje brojac na 3 onda se u na kraju funkcije koja postavlja sve na segment3 taj brojac postavlja na 0. Mislim da je tako ok. I jos me zanima dali je ok poslije stack inicijalizacije staviti kod za upis u SRAM vrijednosti 7SEG Displaya? Posto citam da nekvi kazu na forumima da treba da se inicijalizira i upisuje u .DSEG direktivi?


Evo koda i slike iz simulatora pa ako moze da se pogleda i vidi dali je to ok ili ne...pa da kad bude ok da onda krenem dalje na pisanje koda citanja MAX6675.






.rar   Projects.rar (Size: 1,48 KB / Downloads: 1)
Reply
Ukoliko je asm kod mali možeš predvideti da ti sve promenljive stanu u registre. Tada za sve ovo:

    ; Increment Segment Counter + 1
    lds        R17, segmt
    ldi        R16, 0x01
    add        R16, R17
    sts        segmt, R16


možeš koristiti naredbu INC

Probaj, takođe da ovo:

    ldi        R17, 0x01
    cp        R16, R17


Zameniš sa CPI.
Zaboravio sam sve asemblerske naredbe treba da može.

Registrima možeš dodeliti imena (na početku si čini mi se tako radio) pa će ti biti lakše za čitanje programa.
Kodirane vrednosti za segmente su po prirodi konstante i smeštaju se u CSEG. Taj jedan instrukcijski ciklus koji pre pročitaš iz DSEG nego iz CSEG ti ne znači ama baš ništa. Mnogo je važnije da ti je softver regularan. Ne juri ni brzinu ni totalno optimizovan kod po pitanju veličine hex fajla. Mikrokontroleri sada imaju toliko flash memorije i jure na toliko megaherca da su ti te dve stvari manje važne od činjenice da sutra to što si napisao možeš i da pročitaš. I ne samo ti već i neko kome budeš prodao svoj kod.
Reply
U prilogi novi kod sa izmjenama kako je gorankg predlozio...nadam se da je sada ok...promjene su sljedece:

- kodirane vrijednosti za segmente stavljene u FLASH i citanje iz FLASHa (sada sam morao da koristim Z registar jer on je zaduzen za citanje iz flasha)
- startnu adresu 0x0000 sam morao da stavim 0x0005 iz razloga sto sam radio gore spomenuto spremanje konstanti u flash...postu su konstante duge 10 bytova a velicina dva byte zauzima 1 mjesto u flashu, racunicom 10 byte / 2 mjesta dodje 5 kao slobodna pocetna pozicija..ili lakse kazano:

konstante su zapisane na pocetku flasha dakle na adresi 0x0000 i idu do adrese 0x0004 (dakle 0000 0001 0002 0003 0004) i nakon te adrese ide nas kod koji sam napisao da se izvrsava. Ovime je puuno manje zauzece i bolji kod (proje 104 Worda sada 78 Worda), jedina mana je citanje iz FLASHA 1 ciklus vise naspram RAM-a ali to sada nije toliko ni bitno jer se ne radi o ultra preciznom PWM ili nekvom drugom sklopu gdje je brzina od presudne vaznosti.

- zamjenjene dugacke instrukcije sa cpi i inc brojaca, te se tu ustedjelo puno u programu i brze ce se program da se izvrsava
- umjesto lp stavljeno lpm jer sada citamo iz FLASH-a a ne iz SRAM-a pa mora da se koristi drugačiji mnemonik.
- frekvencija osvjezavanja stavljena na 5ms (200Hz), to kad se podijeli na 3 segmenta ispadne 66,66Hz realna frekvencija osvjezavanja stip ce se fino podesiti kada stignu displeyi.

Evo koda:


.rar   Segment_New.rar (Size: 1,29 KB / Downloads: 1)
Reply
Odlično tebi ovo ide. Samo napred!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)