; ; Namen : Vanderhaegen Bart & Vandermeersch David ; Vak : Labo Microcomputers 3 ELE ; ; Titel : Digitale Lichtcomputer ; Definiëren van de gebruikte symbolen SCL bit P1.0 ; SCL Bus SDA bit P1.1 ; SDA Bus IADDR equ R0 ; Adres Byte IBYTE equ R1 ; Data Byte ; Begin van het programma CSEG AT 8500H ; Initialiseer de knoppen MOV IADDR,#01110000B ; Adres Schakelaars = 70H MOV IBYTE,#11111111B ; Stel de te schrijven byte in CALL SENDBYTE MOV R4,#00H ; Wis de effect teller ; Hoofdlus van het programma LUS: ; Lees het knoppengeheugen in. Een verandering van het ; effect moet worden gedetecteerd, zodat de effectteller ; dan kan worden gereset. Dit gebeurt door te controleren ; of de schakelaars gewijzigd zijn sinds de vorige cyclus. MOV IADDR,#01110000B ; Adres Schakelaars = 70H CALL GETBYTE ; Lees een Byte in MOV R5,A ; Onthou tijdelijk het resultaat ANL A,#11110000B ; Hou enkel rekening met schakelaars CJNE A,06H,ModeChange ; Verandering? -> ModeChange JMP NoModeChange ; Geen Verandering? -> NoModeChange ModeChange: MOV R4,#00H ; Reset de effect teller NoModeChange: MOV R6,A ; Onthou de data voor volgende cyclus MOV A,R5 ; Zet de originele inlees-data terug ; Bepaal de waarde van de verschillende schakelaars. Dit ; gebeurt door de inlees-data te verschuiven, zodat telkens ; een bit in de carry terecht komt. ; STAP 1: LEES DE ON/OFF STATUS RRC A ; verschuif on/off status in carry JNC SysteemAan ; byte 1 = 0? -> SysteemAan ; Schakel Ledbar Uit MOV DPTR,#4000H ; Stel het adres v/d ledbar in MOV A,#00H ; Stel de te schrijven data in MOVX @DPTR,A ; Schrijf de gegevens naar de ledbar ; schakel I²C bar Uit MOV IADDR,#01110010B ; Adres Leds = 72H MOV IBYTE,#00000000B ; Te schrijven data = alle leds uit CALL SENDBYTE ; Verstuur de byte via I²C ; Voer volgende commando's niet uit JMP LUS ; Keer terug naar begin ; STAP 2: LEES DE LEDBAR STATUS SysteemAan: RRC A ; verschuif ledbar status in carry MOV P1.2,C ; zet ledbar status tijdelijk op P1.2 ; STAP 3: LEES DE LED BOARD STATUS UIT CheckI2C: RRC A ; verschuif led board status in carry MOV P1.3,C ; zet status tijdelijk op P1.3 ; STAP 4: LEES DE SNELHEID STATUS UIT MOV R7,#00H ; Stel standaard snelheid in RRC A ; verschuif snelheid status in carry JNC TrageMode ; Status = 0? -> TrageMode MOV R7,#128D ; Status = 1, Stel snelle mode in TrageMode: ; STAP 5: LEES EFFECT1 STATUS UIT MOV R5,#00H ; Zet de schakelaar=aan teller op 0 CheckE1: RRC A ; plaats effect1 schakelaar in carry JC CheckE2 ; schakelaar=1? -> CheckE2 INC R5 ; schakelaar=0, verhoog de s-teller MOV DPTR,#9000H ; schakelaar=0, stel effecttabel in ; STAP 6: LEES EFFECT2 STATUS UIT CheckE2: RRC A ; plaats effect2 schakelaar in carry JC CheckE3 ; schakelaar=1? -> CheckE3 INC R5 ; schakelaar=0, verhoog de s-teller MOV DPTR,#9010H ; schakelaar=0, stel effect tabel in ; STAP 7: LEES EFFECT3 STATUS UIT CheckE3: RRC A ; plaats effect3 schakelaar in carry JC CheckE4 ; schakelaar=1 -> CheckE4 INC R5 ; schakelaar=0, verhoog de s-teller MOV DPTR,#9020H ; schakelaar=0, stel effect tabel in ; STAP 8: LEES EFFECT4 STATUS UIT CheckE4: RRC A ; plaats effect4 schakelaar in carry JC CheckNext ; schakelaar=1 -> CheckDone INC R5 ; schakelaar=0, verhoog de s-teller MOV DPTR,#9030H ; schakelaar=0, stel effect tabel in ; Controleer, na het inlezen van de schakelaars, of er maar ; één schakelaar werd aangezet. Zoniet moet een foutmelding ; gebeuren. CheckNext: CJNE R5,#01D,FoutEffect ; R5 <> 1 -> FoutEffect JMP GoedEffect ; R5 == 1 -> GoedEffect FoutEffect: MOV DPTR,#9040H ; Stel tabel effectfout in ; Laad een effect uit de geselecteerde tabel in GoedEffect: MOV A,R4 ; Plaats de offset in de ACCU MOVC A,@A+DPTR ; Laad de tabel+offset waarde in INC R4 ; verhoog de effect fout CJNE A,#11110101B,NoEnd ; Byte <> EindMarkering -> NoEnd MOV R4,#00H ; Byte == EindMarkering,wis effect JMP LUS ; Byte == EindMarkering, herstart lus NoEnd: ; Controleer of LEDBAR status AAN/UIT is. Deze informatie ; was opgeslagen in P1.2 MOV DPTR,#4000H ; Stel het adres v/d ledbar in MOV C,P1.2 ; Plaats de infobit in de carry JC NoLedBar ; LedBar=1 -> NoLedBar MOVX @DPTR,A ; LedBar=0, schrijf effect weg JMP DoI2CSend ; Ledbar=0, ga naar I²C gedeelte NoLedBar: MOV R5,A ; onthou de led waarden tijdelijk MOV A,#00H ; te schrijven byte = alle leds uit MOVX @DPTR,A ; schrijf de data weg MOV A,R5 ; laad de led waarden terug in DoI2CSend: ; Controleer of de I²C LEDBAR status AAN/UIT is. Deze info ; was opgeslagen in P1.3 MOV C,P1.3 ; plaats de infobit in de carry JC NoI2C ; LedBar=0 -> NoI2C MOV IADDR,#01110010B ; LedBar=1, Adres Ledbar Instellen MOV IBYTE,A ; LedBar=1, Te sturen data instellen CALL SENDBYTE ; LedBar=1, verstuur I²C commando CALL VT ; LedBar=1, roep vertraging op JMP LUS ; LedBar=1, spring naar begin NoI2C: MOV IADDR,#01110010B ; LedBar=0, LedBar Adres Instellen MOV IBYTE,#00000000B ; LedBar=0, "alles doven" instellen CALL SENDBYTE ; LedBar=0, verstuur I²C commando CALL VT ; LedBar=0, roep vertraging op JMP LUS ; LedBar=0, spring naar begin ; *********************** ; LichtEffect Bibliotheek ; *********************** ORG 9000H DB 00000001B ; effect 1 DB 00000010B DB 00000100B DB 00001000B DB 00010000B DB 00100000B DB 01000000B DB 10000000B DB 11110101B ; einde markering ORG 9010H DB 10000001B ; effect 2 DB 01000010B DB 00100100B DB 00011000B DB 00100100B DB 01000010B DB 10000001B DB 11110101B ; einde markering ORG 9020H DB 00000000B ; effect 3 DB 00000001B DB 00000011B DB 00000111B DB 00001111B DB 00011111B DB 00111111B DB 01111111B DB 11111111B DB 11110101B ; einde markering ORG 9030H DB 10101010B ; effect 4 DB 10101010B DB 10101010B DB 01010101B DB 01010101B DB 01010101B DB 11110101B ; einde markering ORG 9040H DB 00000000B ; effect "fouteffect" DB 00000001B DB 11110101B ; einde markering VT: AA: DJNZ R5,$ ; wacht een bepaalde tijd DJNZ R7,AA ; wacht een bepaalde tijd (afh. van snelheid inst) RET ; verlaat subroutine JMP LUS; ; ********************************************************************* ; I²C routine bibliotheek ; ; functie GETBYTE : verkrijg een byte naar een I²C bus device ; functie SENDBYTE : stuur een byte naar een I²C bus device ; ********************************************************************* ; SENDBYTE: ; * STUUR DATA OP DE LIJN * CALL START ; genereer een i²c startconditie MOV A,IADDR ; laad het device startadres in CALL WRBYT ; stuur het device adres op de bus CALL ACK ; wacht op een bevestiging v/d slave MOV A,IBYTE ; laad de te schrijven byte in CALL WRBYT ; stuur de databyte op de bus CALL ACK ; wacht op een bevestiging v/d slave CALL STOP ; genereer een I²C stopconditie RET ; verlaat de subroutine GETBYTE: ; * VERKRIJG DATA VAN DE LIJN * call start ; genereer een i²C startconditie mov a,IADDR ; laad het device startadres in xrl a,#00000001B ; stel de i²c schrijfmode in call wrbyt ; stuur het device adres op de bus call ack ; wacht op een bevestiging v/d slave call rdbyt ; lees de byte die de slave terug stuurt call nack ; stuur een acknowledge bericht terug call stop ; stop de bus ret ; verlaat de subroutine ; <--------------------------- I²C subroutines ------------------------> wrbyt: clr c ; wis de carry bit mov R5,#08h ; zet 08 in de count variabele (aantal bits) loopo: rlc a ; plaats de MSB v/d accu in de carry mov sda,c ; zet de te schrijven bit op de DATA lijn call clock ; genereer de klokpuls djnz R5,loopo ; verwerk de volgende bit ret ; verlaat de subroutine rdbyt: clr c ; wis de carry bit setb sda ; maak de datalijn hoog mov R5,#08H ; zet 08 in de count variabele (aantal bits) loopi: call clock ; genereer een klokpuls (sda komt in carry) rlc a ; schuif de accu op (carry in de MSB) djnz R5,loopi ; herhaal dit 8 keer (8 bits inlezen) ret ; verlaat de subroutine nack: setb sda ; maak de datalijn hoog call clock ; genereer een klokpuls ret ; verlaat de subroutine delay: nop ; wacht 1 µs nop ; wacht 1 µs nop ; wacht 1 µs nop ; wacht 1 µs RET ; verlaat de subroutine stop: clr sda ; wis de serial data setb scl ; zet de serial clock call delay ; vertraag de lijn voor 4 µs setb sda ; set de serial data ret ; verlaat de subroutine start: setb sda ; zet de serial data setb scl ; zet de serial clock call delay ; vertraag de lijn voor 4 µs clr sda ; wis de serial data call delay ; vertraag de lijn voor 4 µs clr scl ; maak de serial clock laag ret ; verlaat de subroutine ack: setb sda ; zet de serial data hoog setb scl ; zet de serial clock call delay ; wacht 4 µs nop ; wacht 1 µs jnb sda,endack ; de ACK puls is aanwezig, verlaat routine jb sda,$ ; wacht alsnog op de ACK puls endack: clr scl ; wis de kloklijn ret ; verlaat de subroutine clock: setb scl ; maak de clocklijn hoog call delay ; wacht 4 µs mov c,sda ; plaats de status van SDA in de carry clr scl ; wis de clocklijn ret ; verlaat de subroutine end