Stap 8: Codering de slaaf
Voordat we in de TWI-subroutine, die in het geval van de slaaf een interrupt handler is, instellen we eerst de rest van de code om het te gebruiken. Allereerst moeten we voegen de interrupt (gedefinieerd in tabel 12-6 op pagina 65):
.org 0x0000
jmp Reset
.org 0x0020
jmp timer_overflow_int
.org 0x0030
jmp tw_int
Dit zegt dat deze regel op locatie 0x0030 zal worden uitgevoerd als globale interrupts zijn ingeschakeld door de instelling ik beet in SREG 1, en wordt, in de TWCR, de TWIE bit een 1 en de TWI interrupt-vlag ingesteld is.
We duidelijke opnieuw de TWI en de bits Timer/Counter0 in de macht vermindering registreren PRR zoals we hebben gedaan met de meester. Het is niet nodig de bitsnelheid instellen op de slaaf aangezien de meester de SCL-frequentie bepaalt en de slave alleen hierop reageert.
LDS temp, PRR
Andi temp, 0b01011111
St PRR, temp ldi temp, 0b10100001
St TWAR, temp
Boven, initialiseren we (per pagina 223) we het adres van de slaaf in de TW adres registreren, TWAR laden. Het laatste stukje is een 1, wat betekent dat de slaaf op algemene oproepen reageren zal. We zijn niet met behulp van algemene gesprekken hier maar kunnen we willen hen later gebruiken wanneer er meer dan één slave.
LDI temp, (1--TWEA) | (1--TWEN) | (1--TWIE)
St TWCR, temp
Vervolgens maken wij de beoordelen bit (zodat overdracht zal worden gereageerd door te trekken langs de lijn van de SDA na ontvangst van de gegevens), waardoor de TWI, en de TWI onderbreekt (TWIE). TWI interrupts inschakelt, dat onze interrupt handler op .org 0x0030 zullen worden aangeroepen wanneer TWINT is ingesteld op 1 door hardware (dat wil zeggen de vlag is ingeschakeld).
CBI DDRC, 4
SBI PORTC, 4
CBI DDRC, 5
SBI PORTC, 5
De bovenstaande regels wordt onze SDA en SCL pennen gestoken door invoermodus met interne pullups.
Ten slotte komen we bij onze slaaf TWI interrupt handler:
tw_int:
Push temp
Het is altijd verstandig om op te slaan uw tijdelijke registers bij het invoeren van een interrupt. Je weet niet wanneer een interrupt zal worden genoemd en gebruikt u 'temp' in de interrupt naar uw belangrijkste code met vuilnis in het terugkeren zal. Dus het hier push en pop het terug aan het eind.
rcall display_off
Onderaan ziet u wat ik heb voor de display_off-subroutine. Het eigenlijk uitschakelt gewoon als de 4-cijferige displays totdat de nieuwe getallen weergeven door deze handler worden geladen.
LDS temp, TWSR
CPI temp, 0x60
Brně fout
Tabel 22-4 geeft de statuscodes voor een slaaf in de modus van de ontvanger. Hier zijn we gewoon de controle om te zien dat het ons adres en een beetje schrijven die kwam uit de lijn en veroorzaakt deze interrupt was.
LDI temp, (1--TWINT) | (1--TWEA) | (1--TWEN)
St TWCR, temp
rcall tw_wait
LDS temp, TWSR
CPI temp, 0x80
Brně fout
Vooral wij duidelijk de TWI interrupt-vlag met (1--TWINT), de anderen zijn gewoon om hen te houden op het wanneer wij temp in TWCR laden. Als we niet hebben (1--TWEA) en (1--TWEN) dan zij zou worden ingesteld op nul in het register van de TWCR in de volgende regel. Dan wachten we totdat de TWI is voltooid en weer beschikbaar is. We controleren vervolgens het register van de status om te zien dat de gegevensbyte is ontvangen, opgeslagen in TWDR en er is een acknowledge terug gestuurd.
LDS-playercashH, TWDR
Dit laadt de gegevensbyte die we van de regel in het register van onze playercashH kregen.
LDI temp, (1--TWINT) | (1--TWEA) | (1--TWEN)
St TWCR, temp
rcall tw_wait
LDS temp, TWSR
CPI temp, 0x80
Brně fout
Precies zoals hierboven, wij ontvangen een gegevensbyte, erkennen en controleren van de status.
LDS-playercashL, TWDR
Ditmaal slaan we de gegevensbyte in playercashL. Hierin zal onze totale met de dobbelstenen.
LDI temp, (1--TWINT) | (1--TWEA) | (1--TWEN)
St TWCR, temp
rcall tw_wait
LDS temp, TWSR
CPI temp, 0xA0
Brně fout
rjmp tw_return
Inschakelen van de TWI, krijgen de volgende gegevensbyte, controleert u de status om ervoor te zorgen is het STOP signaal en ten slotte Spring naar onze label opruimen en afsluiten.
FOUT:
LDI playercashH,high(1111)
LDI playercashL,low(1111)
tw_return:
Onze foutafhandelingsroutine doet niets, maar alle 1's laden in het display tonen ons dat iets misgegaan en daarna opnieuw van de interrupt.
Nu dat we onze display "playercash" registreert geladen, noemen we de "loadcash"-routine die zal hen omzetten in decimale cijfers en weer te geven.
LDI temp, (1--TWINT) | (1--TWEA) | (1--TWEN) | (1--TWIE)
St TWCR, temp
rcall loadcash
pop temp
Sei
Réti
Het bovenstaande wordt opnieuw ingeschakeld de TWIE zodat het opnieuw van de interrupt handler op 0x0030 uitvoeren zal wanneer er een interrupt TWI optreedt. Vervolgens wij pop onze temp terug uit de stack, global interrupts re-toe te laten en terug te keren naar waar we werden genoemd. Het volgende is onze tw_wait-subroutine die identiek is aan die wordt gebruikt in de Master code:
tw_wait:
LDS temp, TWCR
SBRs temp, TWINT
rjmp tw_wait
RET
Tot slot, hier is onze display_off-routine die zichzelf:
display_off:
CBI PortC, 0
CBI PortC, 1
CBI PortC, 2
CBI PortC, 3
RET
In de volgende stap geef ik de code en de video van de operatie.