AVR Assembler handledning 10 (8 / 10 steg)
Steg 8: Kodning slav
Innan vi går in TWI subrutinen, som i fallet med slav är en avbrottshanterare, lägga vi först upp resten av koden att använda den. Först måste vi lägga till avbrottet (definieras i tabell 12-6 på sidan 65):
.org 0x0000
JMP Reset
.org 0x0020
JMP timer_overflow_int
.org 0x0030
JMP tw_int
Detta säger att denna linje på plats 0x0030 kommer att genomföras om globala avbryter aktiveras av inställningen jag bet i SREG 1, och om, i TWCR, TWIE bit är en 1 och TWI avbrott flaggan är inställd.
Det tydliga igen det tolerabla VECKOINTAGET och Timer/Counter0 bitar i makt minskade registrera PRR som vi gjorde med befälhavaren. Det är inte nödvändigt att ange bithastigheten på slaven eftersom befälhavaren styr SCL frekvensen och slaven bara svarar på det.
LDS temp, PRR
Andi temp, 0b01011111
STS PRR, temp ldi temp, 0b10100001
STS TWAR, temp
Ovan, vi initiera (enligt sidan 223) vi ladda slavadress i TW adress registrera, TWAR. Den sista biten är en 1 vilket innebär att slaven svarar på allmänna samtal. Vi använder inte allmänna samtal här men vi kanske vill använda dem senare när vi har mer än en slav.
LDI temp, (1--TWEA) | (1--TWEN) | (1--TWIE)
STS TWCR, temp
Nästa vi aktiverar bekräfta lite (så att överföringen kommer att besvaras genom att dra ner på SDA linjen efter att ha fått data), aktivering av det tolerabla VECKOINTAGET och TWI avbryter (TWIE). Att aktivera TWI avbryter innebär att våra avbrottshanterare på .org 0x0030 kommer att anropas när TWINT är satt till 1 av hårdvara (dvs. flaggan är på).
CBI DDRC, 4
SBI PORTC, 4
CBI DDRC, 5
SBI PORTC, 5
Ovanstående rader sätta våra SDA och SCL stift i inmatningsläge med inre pullups.
Slutligen kommer vi till vår slav TWI avbrottshanterare:
tw_int:
Tryck temp
Det är alltid god praxis att lagra din temp register när du anger ett avbrott. Du vet inte när ett avbrott kommer att kallas och om du använder "temp" i avbrottet den kommer tillbaka till din huvudsakliga koden med sopor i den. Så tryck in det här och pop det tillbaka i slutet.
rcall display_off
Längst ner ser du vad jag har för display_off-subrutin. Det i princip stänger bara av de 4-siffriga displayerna tills de nya Visa tal läses av denna handler.
LDS temp, TWSR
CPI temp, 0x60
brne fel
Tabell 22-4 ger statuskoder för en slav i mottagaren läge. Här vi bara kontroll för att se att det var vår adress och lite skriva som kom från linjen och orsakade detta avbrott.
LDI temp, (1--TWINT) | (1--TWEA) | (1--TWEN)
STS TWCR, temp
rcall tw_wait
LDS temp, TWSR
CPI temp, 0x80
brne fel
Framför vi tydliga flaggan TWI avbrott med (1--TWINT), de andra är bara för att hålla dem på när vi läsa in temp i TWCR. Om vi inte hade (1--TWEA) och (1--TWEN) då de skulle sättas till noll i TWCR register på raden. Vi vänta sedan tills det tolerabla VECKOINTAGET slutar och blir tillgänglig igen. Sedan kontrollerar vi statusregistret för att se att byten som data har tagits emot, lagras i TWDR och en kvittering har skickats tillbaka.
LDS playercashH, TWDR
Detta laddar databyte som vi fick från linjen i vårt playercashH register.
LDI temp, (1--TWINT) | (1--TWEA) | (1--TWEN)
STS TWCR, temp
rcall tw_wait
LDS temp, TWSR
CPI temp, 0x80
brne fel
Precis som ovan, vi får en databyte, erkänna det, och kontrollera status.
LDS playercashL, TWDR
Denna gång vi lagrar databyte på playercashL. Denna kommer att innehålla vår totala tärningskast.
LDI temp, (1--TWINT) | (1--TWEA) | (1--TWEN)
STS TWCR, temp
rcall tw_wait
LDS temp, TWSR
CPI temp, 0xA0
brne fel
rjmp tw_return
Aktivera det tolerabla VECKOINTAGET, få den nästa databyte, kontrollera status att se till att det är stopp-signal och slutligen hoppa till vår rensning och exit etikett.
FEL:
LDI playercashH,high(1111)
LDI playercashL,low(1111)
tw_return:
Våra fel hanterare gör ingenting men ladda alla 1 i displayen att visa oss något gick fel och sedan återvända från avbrottet.
Nu när vi har våra display "playercash" registrerar lastade, vi kallar den "loadcash" rutin som kommer att konvertera dem till decimaler och visa dem.
LDI temp, (1--TWINT) | (1--TWEA) | (1--TWEN) | (1--TWIE)
STS TWCR, temp
rcall loadcash
pop temp
SEI
Reti
Ovanstående återaktiverar TWIE så att den kommer återigen att köra avbrottshanterare på 0x0030 när en TWI avbrott inträffar. Sedan vi pop vår temp backa stacken, re-möjliggöra globala avbrott och gå tillbaka till där vi var kallade. Följande är våra tw_wait subrutin som är identisk med den som används i Master koden:
tw_wait:
LDS temp, TWCR
SBRs temp, TWINT
rjmp tw_wait
ret
Slutligen, här är vår display_off rutin som är självförklarande:
display_off:
CBI PortC, 0
CBI PortC, 1
CBI PortC, 2
CBI PortC, 3
ret
I nästa steg ger jag koden och video av operation.