Diskuze: Diody na 2 portech
V předchozím kvízu, Online test znalostí Assembler, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 16 zpráv z 16.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí Assembler, jsme si ověřili nabyté zkušenosti z kurzu.
tak si je seřadíš, tak aby odpovídaly "indexy" na portu a pak to nastavíš obou portům stejné.
// u atmelu např.
PORTA = PORTB = b00000001;
P.S vycházím že porty jsou osmibitové.
nebo pokud máš nějaké šestnáctibitové porty tak to můžeš udělat rovnou. To postupné problikávání pak asi nejjednodušeji vyřeší ROLem (rotate left) (na x86 by to mělo být SHL; shift left).
Šlo by to i nějak takto ?
.INCLUDE "m8def.inc"
.CSEG
.DEF REG=R16
.EQU DDR=DDRD
.EQU PORT=PORTD
LDI REG,$FF
OUT DDR,REG
LDI REG,LOW(RAMEND)
OUT SPL,REG
LDI REG,HIGH(RAMEND)
OUT SPH,REG
CLC ;0 do D
LDI REG,0b111111111
LOOP:
OUT PORT,REG
RCALL DLY1
ROL REG
RJMP LOOP
DLY1:
LDI R17,14
LDI R18,0
LDI R19,0
DLY2:
DEC R19
BRNE LOOP
DEC R18
BRNE LOOP
DEC R17
BRNE LOOP
RET
LDI REG,0b111111111
Tady máš jaksi devět jedniček, max. půjde osm. Také si nejsem jistý, zda-li správná syntax toho čísla není 11111111b. Instrukce ROL navíc rotuje přes příznak carry, takže během čekání bys neměl hodnotu tohoto příznaku.
V kódu nevidím pokus o zápis hodnot na nějaký jiný port než PORTD, takže na dvou portech fungovat nebude. Také jsi nespecifkoval, jakým způsobem chceš ty dvě diody rozsvěcovat (vůči sobě).
Co se týče
DLY2:
DEC R19
BRNE LOOP
DEC R18
BRNE LOOP
DEC R17
BRNE LOOP
RET
měl bys skákat na DLY2, ne na LOOP, protože jinak provádíš nekonečnou smyčku a bude docházet k přetečení zásobníku. I když to opravíš na LOOP, nejsem si jistý, zda-li taková procedura bude čekat dostatečně dlouho, aby to bylo pozorovatelné lidským okem.
zápis čísla má správně, ale má tam jednu jedničku navíc, no.
No, jestli chce rozsvítit jen jednu diodu v každém okamžiku, tak by tam neměl psát samé jedničky podle mě.
No, jestli to teda dobře chápu, tak potřebuješ mít vždy rozsvícenou jednu diodu a "posouvat" ji přes dva porty (tedy přes 16 pozic). Což můžeš řešit tak, že si uděláš cyklus, který projde jednou tou diodou po jednom portu a pro druhý port jej prostě zopakuješ. Něco na tento způsob:
LDI r18, 1
LOOP:
OUT, PORTD, r18 ; Zapis r18 na port (rozsviti diodu a zhasne predchozi)
(R)CALL DELAYX ; Cekej
LSL r18 ; Posun r18 o bit doleva (nova pozice diody)
BRNE LOOP ; Pokud r18 = 0, znamena to, ze jsme dorazili na konec portu
OUT PORTD, r1 ; V r1 predpokladame nulovou hodnotu
Konvence Cčkových překladačů je v r1 držet vždy nulu a je dobré se toho držet i v Assembleru, protože nula se vždycky hodí. Tudíž si ji tam můžeš někde na začátku kódu nastavit. Můj kód také předpokládá, že procedura DELAYX nezmění hodnotu r18.
hm a není tedy problém vyřešit elektronicky? Sériovým/paralelním zapojením diod?
V takovém případě by mohlo za instrukci
OUT PORTD, r18
zapsat instrukci zapisující r18 na jiný tebou vybraný port. Pak to bude splňovat tvé zadání, jestli jej dobře chápu. Samozřejmě je třeba dodělat nějakou tu inicializaci.
elektronicky
To by určitě šlo, ale myslím, že to není způsob, kterým by se měl ten domácí úkol řešit .
Zobrazeno 16 zpráv z 16.