Exempel kod till en led-matris
Postat: 19 mars 2005, 10:35:53
hejsan.
Är det någon som har en liten kodstump att dela med sig av? språket ska vara c.
Är det någon som har en liten kodstump att dela med sig av? språket ska vara c.
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Kod: Markera allt
; ===============================================================================
; = DRIVKRETS FÖR LEDMATRIS 3x4
; = version 1.01. - 20050301
; = Slingan av tecken (Chars) kan köras antingen varje gång RESET hålls låg
; = längre än en mikrosekund eller som en oändlig loop.
; ===============================================================================
;
; Pin Port
; 1 Reset -
; 4 GND 0V
; 8 VCC +5V
; 3 P4 Multiplexer y (MSB)
; 2 P3 Multiplexer y (LSB)
; 7 P2 x0
; 6 P1 x1
; 5 P0 x2
;
; P4 P3 P2 P1 P0
; y3 0 0
; y2 0 1
; y1 1 0
; y0 1 1
; x0 x1 x2
;
; ===============================================================================
; = KONSTANTER I KOD
; ===============================================================================
; MaxChar - Antal Chars lagrade i EEPROM (32)
; BpCHAR - Bytes per Char (4)
; Delay - Antal Cykler som Char skall visas (48)
; ===============================================================================
; = INITIERING
; ===============================================================================
.include "tn22def.inc" ; Includera variabelnamn och definitioner
.org $0000 ; Börja skriva på första positionen
rjmp RESET ; Resetvektor
rjmp EX_INT0 ; Externinterruptvektor
rjmp TIMER ; Timer/Countervektor
.def Temp = r16 ; Temporärregister
.def Time = r17 ; Räknar antalet gånger som Timer overflow inträffat
.def Char = r18 ; Tecken som visas på matrisen
.def Read = r19 ; Läsadress i EEPROM.
.def y0 = r20 ; Data för rad y0
.def y1 = r21 ; Data för rad y1
.def y2 = r22 ; Data för rad y2
.def y3 = r23 ; Data för rad y3
.def Cntr = r24 ; Temporär räknevariabel
.def Ctrl = r25 ; Styr vad som skall göras vid givet Timeranrop
; ===============================================================================
; = RESETVEKTOR - körs efter Power Off och Reset
; ===============================================================================
RESET:
; Initiera stacken:
ldi Temp, low(RAMEND) ; Initiera stacken med den sista SRAM adressen på chipet
out SPL, Temp ; SPL är stackpointer som pekar på returnvärdet från sub eller int
; Ställ in Timerfrekvens
ldi Temp,$02 ; xxxx x001 - CS02, CS01, CS00 (000 - stop, 001 - CK, 010 - CK/8, 011 - CK/64, 100 - CK/256, 101 - CK/1024, 110 - External Pin T0 Falling Edge, 111 - External Pin T0 Rising Edge)
out TCCR0,Temp ; TCCR0 Timer/Counter0 Control Register
; Nollställ variabler
ldi y0,$00
ldi y1,$00
ldi y2,$00
ldi y3,$00
ldi Time,$00
ldi Char,$00
ldi Cntr,$00
ldi Ctrl,$00
; Konfigurera PortB för Output
ldi Temp,$FF ; xxx1 1111 - DDBn (4<= n <= 0)
out DDRB,Temp ; DDRB Data Direction Register port B, alla pins till output
out PORTB,Temp ; PORTB Port B, alla pins till logisk 1 = alla LED släckta
; Enabla sleep-kommando
ldi Temp,$20 ; xx10 xx00 - SE Sleep Enabled, SM SleepMode, ISC01, ISC00
out MCUCR, Temp ; MCU Control Register
; Initiera matrisen/hämta data:
rcall GETCHAR
; Starta timer:
ldi Temp,$02 ; xxxx xx1x - TOIE, Timer/counterOverflowInterruptEnabled
out TIMSK,Temp ; Timer/counterInterruptMaskRegister
; Aktivera interrupter:
sei ; Set global interrupt flag (Bit 7) i SREG, samma sak som bset 7
; ===============================================================================
; = MAIN - Huvudloop, systemets väntefunktion
; ===============================================================================
MAIN:
sleep
rjmp MAIN
; ===============================================================================
; = TIMER/COUNTER OVERFLOW - Anropas vid varje overflow på Timer/Counter
; ===============================================================================
TIMER:
cpi Ctrl,$02 ; 20
brne UPDy2 ; Om Ctrl<>0 hoppa över
out PORTB,y3
UPDy2:
cpi Ctrl,$04 ; 40
brne UPDy1 ; Om Ctrl<>64 hoppa över
out PORTB,y2
UPDy1:
cpi Ctrl,$06 ; 60
brne UPDy0 ; Om Ctrl<>80 hoppa över
out PORTB,y1
UPDy0:
cpi Ctrl,$08 ; 80
brne UPDTime ; Om Ctrl<>172 hoppa över
out PORTB,y0
UPDTime:
cpi Ctrl,$0A ; 100
brne UPDnone ; Om Ctrl<>255 hoppa över
inc Time ; Öka Time
ldi Ctrl,$00
UPDnone:
inc Ctrl ; Öka Ctrl
cpi Time,$08 ; Jämför Time med 8 (Delay - tid som varje Char visas)
brne NOCHANGE ; Om Time < 255 hoppa till NOCHANGE
; Time = Delay
ldi Time,$00 ; Nollställ Time
inc Char ; Öka Char
rcall GETCHAR ; Hämta ny Char-data från EEPROM
cpi Char,$20 ; Jämför Char med MaxChar (max antal tecken i EEPROM)
brne NOCHANGE ; Hoppa över om Char < MaxChar
; Time = Delay och Char = MaxChar
ldi Char,$00 ; Nollställ Char
; ================================================================
; = HÄR VÄLJS OM CHARSLINGAN SKALL VISAS I EN LOOP =
; = ELLER ENBART EN GÅNG =
; ================================================================
; =
cli ; INAKTIVERAR ALLA INTERRUPTFUNKTIONER =
ldi Temp,$30 ; xx11 xx00 - SE, SM =
out MCUCR, Temp ; MCU Control Register =
sleep ; AKTIVERAR POWERDOWN SLEEP, ENBART EXTERN RESET =
; AKTIVERAR KRETSEN ÄNNU EN GÅNG =
; ================================================================
NOCHANGE:
reti
; ===============================================================================
; = Sub GETCHAR - Hämtar matrisdata för Char från EEPROM
; ===============================================================================
GETCHAR:
ldi Read,$00
ldi Temp,$00
ldi Cntr,$00
cpi Char,$00 ; Jämför Char och 0.
breq GETDATA ; Om dom är lika, hoppa över ADDTHREE.
ldi Temp,$04 ; Lagra fyra i Temp, BpCHAR (fyra bytes per Char)
ADDTHREE:
add Read,Temp ; Öka läsadressen med fyra
inc Cntr ; Öka Cntr
cp Cntr, Char ; Jämför Cntr och Char
brne ADDTHREE ; Om dom inte är lika, loopa.
ldi Cntr,$00 ; Nollställ Cntr
GETDATA:
mov y3,y2 ; Kopiera y2 till y3
mov y2,y1 ; Kopiera y1 till y2
mov y1,y0 ; Kopiera y0 till y1
ldi Temp,$08 ; Lagra 8 till temp
add y1,Temp ; Addera Temp till y1: xxx0 1yyy
add y2,Temp ; Addera Temp till y2: xxx1 0yyy
add y3,Temp ; Addera Temp till y2: xxx1 1yyy
out EEAR,Read ; Lagra läsadress i EEPROM Adress register (0-128)
ldi Temp,$01 ; xxxx x001, EEMWE - Master Write Enable, EEWE - Write Enable, EERE - Read Enable
out EECR,Temp ; EECR - EEPROM Control register
in y0,EEDR ; Hämta data från EEPROM Data Register till y0
ldi Temp,$07 ; 0000 0111, skapar inverteringsmask
eor y0,Temp ; XOR med masken inverterar data i y0, detta tänder LED vid etta i EEPROM
inc Cntr ; Öka Cntr
inc Read ; Öka läsadressen
cpi Cntr,$04 ; Jämför Cntr och 4 BpCHAR (fyra bytes per Char)
brne GETDATA ; Om dom inte är lika, läs en adress till
ldi Cntr,$00 ; Nollställ Cntr
ret
; ===============================================================================
; = EX_INT0 - Extern interrupt, används ej
; ===============================================================================
EX_INT0:
Kod: Markera allt
while(1)
{
for(i = 0; i < ANTAL_KOLUMNER; i ++){
tänd_kolumn(i);
vad_som_ska_ut_på_kolumen(*(KolumnData+i));
fördröjning(LAGOM_LÅNG_TID);
}
}