AVR Assembler Övningsexempel 4 (2 / 9 steg)
Steg 2: Första utkast till koden
Den första versionen av koden vi ska skriva att köra denna krets kallas "brute force" metod. Vi kommer bara skriva ett program som fungerar och inte oroa dig ännu om att göra den kompakt och "vacker". Vi kommer att göra det mer elegant senare. Det sättet jag gör saker är att se till att du kan få ditt program arbetar och gör vad den gör utan att införa alltför många nya begrepp. En gång du har den arbetande, då vi kommer att justera saker med nya koncept en bit i taget så att programmet fungerar fortfarande korrekt på varje iteration. Så om något går fel, vet du exakt var problemet kommer ifrån.
Så låt oss börja med följande program att rulla tärningarna. Du bör sätta ihop det, ladda upp den och se till att det fungerar på din mikroprocessor.
;********************************
; Skrivet av: 1o_o7
; datum: < 2014|11|01 >
; version: 1.0
; filen sparas som: paradise1.asm
; för AVR: atmega328p
; klockfrekvens: 16MHz
;********************************
; Programmera funcion:---
;
; En tärning roller
;
; Lysdioderna på PC0 till 5
; och en center på PB1
; Knappen på PB0
; anoder på PB4 och PB5
;
;--------------------------------
.nolist
.include ". / m328Pdef.inc"
.lista
;=================
; Förklaringar:
.def temp = r16
.def flödar över = r17
def die1 = r18
def die2 = r19
.def millisekunder = r20
.def utsäde = r21
;=================
; Början av Program
.org 0x0000
rjmp Reset
.org 0x0020; Timer0 spill handler
rjmp overflow_handler
;=================
Reset:
LDI temp, 0b00000011
ut TCCR0B, temp; TCNT0 i FCPU/64-läge, så 250000 cnts/SEK
LDI temp, 249
ut OCR0A, temp; toppen av disk på 250 räknas/spill
; så Buffertspill inträffar varje 1/1000 SEK
; Detta innebär ett dataspill varje 1ms
LDI temp, 0b00000010
ut TCCR0A, temp; återställa TCNT0 på värdet i OCR0A
STS TIMSK0, temp; Aktivera timern Overflow avbryter
SEI; Aktivera global avbryter
LDI temp, 0b11111110
ut DDRB, temp; PB0 ingång resten utdata
LDI temp, 0b11111111
ut DDRC, temp; PortC alla utgång
viktigaste:
ser temp
ut PORTB, temp; alla PortB på 5V
ut PORTC, temp; alla PortC på 5V
rcall button_push; vänta tills knappen
rcall random; få rand tal die1, die2
rcall dice; Ställ in tärningarna lysdioder
ser härda; Set temp för cykel
rcall cykel. Animera tärningar kasta
rcall displayen. Visa resultatet
rjmp huvudsakliga
button_push:
sbic PINB, 0; hoppa över om PB0 är GND
rjmp button_push
ret
Random:
; att generera slumptal
Lägg till die1, utsäde
swap utsäde
rcall fördröjning
Lägg till die2, utsäde
CLC
D1:
CPI die1, 6. Jämför die1 med 5
brlo d2; om die1 < 6 rulla sedan
Johan die1, 6. annars subtrahera 6
rjmp d1; gå tillbaka och jämföra igen
D2:
CPI die2, 6. Jämför die2 med 6
brlo rullen. om die < 6 då rulla
Johan die2, 6. annars subtrahera 6
rjmp d2; gå tillbaka och jämföra igen
rulle:
Inc die1; Lägg till 1 så mellan 1 och 6
Inc die2
ret
Dice:
CPI die1, 1. Jämför die1 med 1
brne PC + 2. om inte lika inte ställa in die1
LDI die1, 0b01111111; 7th bit iväg betecknar en 1
CPI die2, 1. Jämför die2 med 1
brne PC + 2. om inte lika inte ställa in die2
LDI die2, 0b01111111
CPI die1, 2
brne PC + 2
LDI die1, 0b11011110
CPI die2, 2
brne PC + 2
LDI die2, 0b11011110
CPI die1, 3
brne PC + 2
LDI die1, 0b01011110
CPI die2, 3
brne PC + 2
LDI die2, 0b01011110
CPI die1, 4
brne PC + 2
LDI die1, 0b11010010
CPI die2, 4
brne PC + 2
LDI die2, 0b11010010
CPI die1, 5
brne PC + 2
LDI die1, 0b01010010; en 4 bitar med 7: e lite off så 5
CPI die2, 5
brne PC + 2
LDI die2, 0b01010010
CPI die1, 6
brne PC + 2
LDI die1, 0b11000000
CPI die2, 6
brne PC + 2
LDI die2, 0b11000000
ret
cykel:
rol härda; Shift bitar kvar med sjal runt omkring
LDI millisekunder, 100. fördröjning (upp till 250 ms)
rcall fördröjning
SEK; SREG bär flaggan
ut PORTC, temp; PortC börjar som 0b11111110
sbrc temp, 6. hoppa över om bit 6 rensas
rjmp cykel. annars loop tillbaka upp
ret
display:
SBI PORTB, 0; SET-knappen off
SBI PORTB, 1. stänga av centrera ledde
LDI millisekunder, 2. ställa in en kort fördröjning
SBI PORTB, 4. Aktivera die1
CBI PORTB, 5. stänga av die2
SBRs die1, 7. hoppa över om center ledde bort
CBI PORTB, 1. slå på center ledde om det behövs
ut PORTC, die1; slå på andra
rcall försening. kort fördröjning
SBI PORTB, 1. stänga av centrera ledde
CBI PORTB, 4. stänga av die1
SBI PORTB, 5. Aktivera die2
SBRs die2, 7. hoppa över om center ledde bort
CBI PORTB, 1. slå på center ledde om det behövs
ut PORTC, die2; slå på andra
rcall försening. kort fördröjning
sbic PINB, 0; utgång till main om knappen trycker
rjmp displayen. slinga till toppen
ret
fördröjning:
CLR svämmar över
sec_count:
cpse flödar över, millisekunder
rjmp sec_count
ret
overflow_handler:
Inc översvämningar; ökar värdet 1000 gånger / SEK
Lägg till utsäde, svämmar över
Reti