Exempel kod till en led-matris
Exempel kod till en led-matris
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.
- Greensilver
- Inlägg: 1305
- Blev medlem: 21 januari 2005, 21:24:57
- Ort: Sverige
- Kontakt:
Jag gjorde en liten LED-matris och drev den med en tiny22, här är koden till den:
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:
Jag undrar varför det ska sitta så långt inne när du till och med blir frågad om hårdvaran....
Den kod som kom från Greensilver är inte BASIC, det är assembler. Om du inte kan förstå den kod som till och med har bra med kommentarer och överföra det till C är jag faktisk lite tveksam till dina kundskaper till att få det att fungera i det hela tagit.
Den kod som kom från Greensilver är inte BASIC, det är assembler. Om du inte kan förstå den kod som till och med har bra med kommentarer och överföra det till C är jag faktisk lite tveksam till dina kundskaper till att få det att fungera i det hela tagit.
okej, jag har inte haft så mycket med assambler och göra, alltså är det inte bara att kolla på koden och fatta precis.. eller hur?
nå, jag ska till fjällen i morgon så det blir väll inte så mycket gjort i nästavecka.. men sen så kanske jag ska ängna projektet lite mer tid..
det jag frågade efter frånböjan var bara en liten kodsnutt så att jag fattade hur jag ska skriva för att få tillexempel en rad att lysa eller nått, bara så att jag fattar principen..
men som det nu ser ut så får jag väll lära mig lite assambler(vilket värkar självkart att man kan?) och "översätta" koden..
Edit: skilnaderna mällan assambler och c är ganska stora om jag inte misstar mig, assamber är ett "lågnivåspråk" och c är väll ett "högnivåspråk" men, det är kanske superlätt att översätta skiten ändå..
hmm, när har jag klagat på hans kod? jag tackade för det och tänkte kolla vidare på de, men det var som sagt c jag var ute efter.. det hade ju gjort saken lättare att få de i rätt språk direkt.. men men.. jag tackar väll en gång till och säjer att jag kommer troligen ha stor nytta av denna koden..
TACK!
nå, jag ska till fjällen i morgon så det blir väll inte så mycket gjort i nästavecka.. men sen så kanske jag ska ängna projektet lite mer tid..
det jag frågade efter frånböjan var bara en liten kodsnutt så att jag fattade hur jag ska skriva för att få tillexempel en rad att lysa eller nått, bara så att jag fattar principen..
men som det nu ser ut så får jag väll lära mig lite assambler(vilket värkar självkart att man kan?) och "översätta" koden..
Edit: skilnaderna mällan assambler och c är ganska stora om jag inte misstar mig, assamber är ett "lågnivåspråk" och c är väll ett "högnivåspråk" men, det är kanske superlätt att översätta skiten ändå..
hmm, när har jag klagat på hans kod? jag tackade för det och tänkte kolla vidare på de, men det var som sagt c jag var ute efter.. det hade ju gjort saken lättare att få de i rätt språk direkt.. men men.. jag tackar väll en gång till och säjer att jag kommer troligen ha stor nytta av denna koden..
TACK!
busenkel variant:
KolumnData förslagsvis en pekare till en bytearray innehållande vad som ska visas på displayen.
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);
}
}