;--------------------------------------------------------------------------
; Titel : Beleuchtungsplatine BEL5
;--------------------------------------------------------------------------
; Funktion : Steuert 5 LED mit unterschiedlichen Ein- und Auszyklen an
; : Der Kanal 4 flackert und soll einen Fernseher darstellen.
; : Die Daten fürs Flackern sind im EEPROM abgelegt und füllen dieses zur Gänze aus.
; Schaltung : Port B.0 bis Port B.4=LED
;--------------------------------------------------------------------------
; Prozessor : ATtiny45
; Takt : 1 Mhz
; Sprache : Assembler
; Datum : 09.05.2013
; Version : 0.1
; Autor : Manfred Stinakovits
; Programmer : mySmartUSB MK2
; Port : com3
; EEPROM : test.eep
;---------------------------------------------------------------------------
.equ SPL,0x3D ; Stack Pointer Register Low
.equ SPH,0x3E ; Stack Pointer Register High
.equ TimeLowByte,24 ; Abgelaufene Zeit, Lowbyte, vom SRAM ins Register r24
.equ TimeHighByte,25 ; Abgelaufene Zeit, Highbyte, vom SRAM ins Register r25
.equ ZregLow,30 ; Z-Register Lowbyte
.equ ZregHigh,31 ; Z-Register Highbyte
.equ ConfigReg,23 ; Das Configurationsbyte wird ausgelesen und in r23 zur weiteren Verwendung gespeichert
;.equ DDRB,0x17 ; PORT B Data Direction Register
;.equ PORTB,0x18 ; PORT B
;.equ TCCR0B,0x33 ; Timer/Counter 0 Control Register B
;.equ TIMSK0,0x39 ; Timer/Counter 0 Interrupt Mask Register
;.equ OCR0A,0x36 ; Timer/Counter 0 Output Compare Register A
;.equ EEARL,0x1E ; EEPROM Adress Register
;.equ EEDR,0x1D ; EEPROM Data Register
;.equ EECR,0x1C ; EEPROM Controlregister
;.equ MCUCR,0x35 ; MCU Control Register (Einstellung für sleep)
.equ F_CPU, 1000000
.include "AVR.H"
;---------------------------------------------------------------------------
; Reset and Interrupt vector Beschreibung
begin: rjmp main ;1 POWER ON RESET
reti ;2 External Interrupt 0
reti ;3 Pin Change Interrupt Request 0
reti ;4 Timer/Counter1 Compare Match A
rjmp onTC1 ;5 Timer/Counter1 Overflow
rjmp onTC0 ;6 Timer/Counter0 Overflow
reti ;7 EEPROM Ready
reti ;8 Analog Comperator
reti ;9 ADC Conversion Complete
reti ;10 Timer/Counter1 Compare Match B
reti ;11 Timer/Counter0 Compare Match A
reti ;12 Timer/Counter0 Compare Match B
reti ;13 Watchdog Time-out
reti ;14 USI START
reti ;15 USI_OVF
;---------------------------------------------------------------------------
; Start, Power ON, Reset
main:
ldi r16,lo8(RAMEND)
out SPL,r16 ;Init Stackpointer LO
ldi r16,hi8(RAMEND)
out SPH,r16 ;Init Stackpointer HI
ldi r16,0b00011111
out DDRB,r16 ;Alle 5 Ports auf Ausgang geschalten
ldi r16,0b00000011
out TCCR0B,r16 ; Timer0, Takt: 15625Hz (1.000.000/64(Vorteiler)) = 0,064ms
ldi r16,0b00001101
out TCCR1,r16 ; Timer1, Takt: 244,140625Hz (1.000.000/4096(Vorteiler)) = 4,096ms
ldi r16,0b00000100
out TIMSK,r16 ; Interrupt Timer0 bei overflow (Bit1)[Beim Programmstart ausgeschalten] + Interrupt Timer1 bei overflow (Bit2)
;
ldi ZregLow,lo8(CONFIG-begin)
ldi ZregHigh,hi8(CONFIG-begin)
lpm
mov ConfigReg,r0
;
cbi EECR,4
cbi EECR,5
ldi r16,0 ; EEPROM Adresse 0, Einschalten
ldi r18,5 ; Ein Wert von 61 entspricht etwa 1 Sekunde
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,15
rcall eeWrite
inc r16 ; Einschalten
ldi r18,5
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,30
rcall eeWrite
inc r16 ; Einschalten
ldi r18,9
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,6
rcall eeWrite
inc r16 ; Einschalten
ldi r18,6
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,12
rcall eeWrite
inc r16 ; Einschalten
ldi r18,9
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,22
rcall eeWrite
inc r16 ; Einschalten
ldi r18,25
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,9
rcall eeWrite
inc r16 ; Einschalten
ldi r18,4
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,18
rcall eeWrite
inc r16 ; Einschalten
ldi r18,7
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,40
rcall eeWrite
inc r16 ; Einschalten
ldi r18,18
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,55
rcall eeWrite
inc r16 ; Einschalten
ldi r18,4
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,60
rcall eeWrite
inc r16 ; Einschalten
ldi r18,7
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,11
rcall eeWrite
inc r16 ; Einschalten
ldi r18,12
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,6
rcall eeWrite
inc r16 ; Einschalten
ldi r18,5
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,11
rcall eeWrite
inc r16 ; Einschalten
ldi r18,1
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,17
rcall eeWrite
inc r16 ; Einschalten
ldi r18,3
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,20
rcall eeWrite
inc r16 ; Einschalten
ldi r18,2
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,33
rcall eeWrite
inc r16 ; Einschalten
ldi r18,19
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,120
rcall eeWrite
inc r16 ; Einschalten
ldi r18,10
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,55
rcall eeWrite
inc r16 ; Einschalten
ldi r18,22
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,5
rcall eeWrite
inc r16 ; Einschalten
ldi r18,10
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,6
rcall eeWrite
inc r16 ; Einschalten
ldi r18,5
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,18
rcall eeWrite
inc r16 ; Einschalten
ldi r18,5
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,12
rcall eeWrite
inc r16 ; Einschalten
ldi r18,10
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,16
rcall eeWrite
inc r16 ; Einschalten
ldi r18,2
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,155
rcall eeWrite
inc r16 ; Einschalten
ldi r18,5
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,39
rcall eeWrite
inc r16 ; Einschalten
ldi r18,8
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,16
rcall eeWrite
inc r16 ; Einschalten
ldi r18,11
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,10
rcall eeWrite
inc r16 ; Einschalten
ldi r18,5
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,138
rcall eeWrite
inc r16 ; Einschalten
ldi r18,4
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,5
rcall eeWrite
inc r16 ; Einschalten
ldi r18,2
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,2
rcall eeWrite
inc r16 ; Einschalten
ldi r18,5
rcall eeWrite
inc r16 ; Ausschalten
ldi r18,88
rcall eeWrite
inc r16 ; Einschalten
ldi r18,88
rcall eeWrite
inc r16 ; EEPROM Adresse 0x3F, Ausschalten
ldi r18,80
rcall eeWrite
;
rcall KonstAdressenLaden
sei
;------------------------------------------------------------------------
; Hauptprogramm
;------------------------------------------------------------------------
mainloop: wdr
rjmp mainloop
;------------------------------------------------------------------------
; Interrupt: Timer 1
; Interruptprogramm: onTC1
; Timerüberlauf 4,096ms(Takt) x 256(Timerüberlauf) = 1,048576s
;------------------------------------------------------------------------
onTC1: cli
lds TimeLowByte,0x60 ; Sekunden Lowbyte aus SRAM Adresse 0x60 holen
inc TimeLowByte ; Um 1 erhöhen
brne onTC11
lds TimeHighByte,0x61 ; Sekunden Highbyte aus SRAM Adresse 0x61 holen
inc TimeHighByte ; Um 1 erhöhen
sts 0x61,TimeHighByte ; Und wieder abspeichern. Sekunden Highbyte
onTC11: sts 0x60,TimeLowByte ; Und wieder abspeichern. Sekunden Lowbyte
lds ZregLow,0x62 ; Ab hier werden die Daten für Kanal 0 voreingestellt.
lds ZregHigh,0x63
mov r28,ZregLow
mov r29,ZregHigh
ldi r18,0
rcall LED
sts 0x62,ZregLow
sts 0x63,ZregHigh
lds ZregLow,0x64 ; Ab hier werden die Daten für Kanal 1 voreingestellt.
lds ZregHigh,0x65
mov r28,ZregLow
mov r29,ZregHigh
ldi r18,1
rcall LED
sts 0x64,ZregLow
sts 0x65,ZregHigh
lds ZregLow,0x66 ; Ab hier werden die Daten für Kanal 2 voreingestellt.
lds ZregHigh,0x67
mov r28,ZregLow
mov r29,ZregHigh
ldi r18,2
rcall LED
sts 0x66,ZregLow
sts 0x67,ZregHigh
lds ZregLow,0x68 ; Ab hier werden die Daten für Kanal 3 voreingestellt.
lds ZregHigh,0x69
mov r28,ZregLow
mov r29,ZregHigh
ldi r18,3
rcall LED
sts 0x68,ZregLow
sts 0x69,ZregHigh
ldi r18,4 ; Ab hier werden die Daten für Kanal 4 voreingestellt.
sbrc ConfigReg,1 ; Überspringe den nächsten Befehl wenn das Bit 1 im Configurationsregister(r23) gelöscht ist.
ldi r18,5 ; 5 im r18 = Fernseher oder Schweißlicht aktiv
lds ZregLow,0x6A
lds ZregHigh,0x6B
mov r28,ZregLow
mov r29,ZregHigh
rcall LED
sts 0x6A,ZregLow
sts 0x6B,ZregHigh
;
ldi ZregLow,lo8(Timerlfzt-begin) ; Die Lowadresse von der Timer Laufzeit (Highbyte) ins Z-Register laden
ldi ZregHigh,hi8(Timerlfzt-begin) ; Die Highadresse von der Timer Laufzeit (Highbyte) ins Z-Register laden
lpm
mov r16,r0
cp r16,TimeHighByte
brne onTC1end
adiw ZregLow,1 ; Die Adresse im Z-Register um 1 erhöhen, um Das Lowbyte von der Timer Laufzeit zu laden.
lpm
mov r16,r0
cp r16,TimeLowByte
brne onTC1end
sbrc ConfigReg,0 ; Überspringe den nächsten Befehl wenn das Bit 0 im Configurationsregister(r23) gesetzt ist.
rjmp onTC1noSleep
in r16,MCUCR
ldi r17,0b00110000
or r16,r17
out MCUCR,r17
sleep
onTC1noSleep:
rcall KonstAdressenLaden
onTC1end: sei
reti
;------------------------------------------------------------------------
; Interrupt: Timer 0
; Interruptprogramm: onTC0
; Timerüberlauf 0,064ms(Takt) x 256(Timerüberlauf) = 16,384ms
;------------------------------------------------------------------------
onTC0:
cli
lds ZregLow,0x6C ; Die aktuelle EEPROM Adresse (es gibt nur ein Lowbyte) holen
rcall eeRead ; EEPROM lesen
lds r17,0x6D ; Die vergangene Anzahl von 16,384ms holen
cp r16,r17 ; Vergleiche die bereits vergangene Anzahl der 16,384ms (r17) mit der zu vergehenden Anzahl (r16)
breq onTC0LEDschalten ; Wenn beide gleich sind, weiter zum schalten der LED
inc r17 ; Die vergangene Anzahl von 16,384ms inkrementieren
sts 0x6D,r17 ; Und speichern
rjmp onTC0end
onTC0LEDschalten:
in r16,PORTB ; Lese PORTB
sbrs r16,4 ; Überspringe nächste Befehl wenn das Bit im PORTB gesetzt ist
sbi PORTB,4 ; Setze das Bit im PORTB
sbrc r16,4 ; Überspringe nächste Befehl wenn das Bit im PORTB gelöscht ist
cbi PORTB,4 ; Lösche das Bit im PORTB
ldi r16,0
sts 0x6D,r16 ; Die vergangene Anzahl von 16,384ms auf 0 zurücksetzen
inc ZregLow ; Die aktuelle EEPROM Adresse (es gibt nur ein Lowbyte) inkrementieren
sts 0x6C,ZregLow ; Die inkrementierte EEPROM Adresse (es gibt nur ein Lowbyte) speichern
cpi ZregLow,0x40 ; Die inkrementierte EEPROM Adresse (es gibt nur ein Lowbyte) mit 0x40 vergleichen (Ende der Daten im EEPROM + 1)
brne onTC0end ; Springe wenn das Ende der eingegebenen Daten noch nicht erreicht ist.
sts 0x6C,r16 ; Die Speicherstelle für den Start der Daten im EEPROM zurücksetzen (In der Regel immer 0)
onTC0end: sei
reti
;----------------------------------------------------------------------
; Unterprogramm: eeWrite
; Daten in EEPROM schreiben, r16 = Adresse, r18 = Wert für EEPROM
;----------------------------------------------------------------------
eeWrite: out EEARL,r16 ;Adresse
out EEDR,r18 ;Daten
sbi EECR,2 ;set EEPROM Write Enabled
sbi EECR,1 ;set EEPROM Write Enabled
waitEEW: sbic EECR,1 ;wait for Handshake
rjmp waitEEW
ret ;zurück zum Hauptprogramm
;----------------------------------------------------------------------
; Unterprogramm: eeRead
; Daten aus EEPROM lesen, ZregLow = Adresse, r16 = Wert aus EEPROM
;----------------------------------------------------------------------
eeRead: out EEARL,ZregLow ;Adresse
sbi EECR,0 ;Leseaufforderung
waitEER: sbic EECR,0 ;warte auf Fertigmeldung
rjmp waitEER
in r16,EEDR ;Daten übernehmen
ret ;zurück zum Hauptprogramm
;----------------------------------------------------------------------
; Unterprogramm: KonstAdressenLaden
; Hier wird alles neu initialisiert, was notwendig ist, wenn der Programmzyklus sich wiederholen soll.
; Die Beginn-Adressen der Konstanten über das Z-Register in den SRAM laden
; 0x60 + 0x61 = Sekunden. Wird vom Timer1 jede Sekunde inkrementiert.
; 0x62 + 0x63 = Adresse der Ein- Auszeiten von LED 0
; 0x64 + 0x65 = Adresse der Ein- Auszeiten von LED 1
; 0x66 + 0x67 = Adresse der Ein- Auszeiten von LED 2
; 0x68 + 0x69 = Adresse der Ein- Auszeiten von LED 3
; 0x6A + 0x6B = Adresse der Ein- Auszeiten von LED 4
; 0x6C = Adresse der Ein- Auszeiten für Fernseher oder Schweißlicht im EEPROM (In der Regel ist das 0)
; 0x6D = 16,384 Millisekunden. Wird vom Timer0 jede 13,384ms inkrementiert.
; Verwendete Register: ZregLow(r30),ZregHigh(r31) Z Register
; r16 Allgemeines Register
; Übernommene Register:
; Zurück gegebene Register:
;----------------------------------------------------------------------
KonstAdressenLaden:
cbr r16,0xFF ; Lösche alle Bits im Register
sts 0x61,r16 ; Sekunden Highbyte auf 0 setzen
sts 0x60,r16 ; Sekunden Lowbyte auf 0 setzen. Wird vom Timer1 jede Sekunde inkrementiert.
ldi ZregLow,lo8(LED0cyc-begin)
ldi ZregHigh,hi8(LED0cyc-begin)
sts 0x62,ZregLow
sts 0x63,ZregHigh
ldi ZregLow,lo8(LED1cyc-begin)
ldi ZregHigh,hi8(LED1cyc-begin)
sts 0x64,ZregLow
sts 0x65,ZregHigh
ldi ZregLow,lo8(LED2cyc-begin)
ldi ZregHigh,hi8(LED2cyc-begin)
sts 0x66,ZregLow
sts 0x67,ZregHigh
ldi ZregLow,lo8(LED3cyc-begin)
ldi ZregHigh,hi8(LED3cyc-begin)
sts 0x68,ZregLow
sts 0x69,ZregHigh
ldi ZregLow,lo8(LED4cyc-begin)
ldi ZregHigh,hi8(LED4cyc-begin)
sts 0x6A,ZregLow
sts 0x6B,ZregHigh
sts 0x6C,r16
sts 0x6D,r16 ; 16,384 Millisekunden Lowbyte auf 0 setzen. Wird vom Timer0 jede 13,384ms inkrementiert.
ret
;----------------------------------------------------------------------
; Unterprogramm: LED
; LED ein- und ausschalten für Kanal 1, 2 und 3
; Im Kanal 4 flackert die LED dauernd wenn die Konstante FSon auf 1 steht. Es wird der Timer0 Interrupt statt der LED ein- und ausgeschalten.
; Verwendete Register: r16,r17 Zur allgemeinen Verwendung
; r18 Kanalnummer [darf hier nicht verändert werden]
; TimeLowByte(r24) Timer Lowbyte [darf hier nicht verändert werden]
; TimeHighByte(r25) Timer Highbyte [darf hier nicht verändert werden]
; r22 PORTB oder TIMSK0 wird da reinkopiert
; ZregLow(r30), ZregHigh(r31) Z-Register
; r28,r29 Y-Register als Kopie des Z-Registers um das Z-Register wieder her zu stellen
; Übernommene Register: r18, TimeHighByte(r25), TimeLowByte(r24), r28, r29, ZregLow(r30), ZregHigh(r31)
; Zurück gegebene Register: ZregLow(r30), ZregHigh(r31)
;----------------------------------------------------------------------
LED: lpm ; Daten aus Flash auslesen (wird im r0 gespeichert)
mov r17,r0
cpi r17,0xFF ; Die aus dem Flash gelesenen Daten auf 255 prüfen (255 = Ende der Ein/Aus Cyclen)
breq LED255 ; Springe wenn das Datenende erreicht ist.
adiw ZregLow,1 ; Erhöhe das Z-Register (Indirekte Adresse in r30 und r31) um 1.
lpm ; Daten aus Flash auslesen (wird im r0 gespeichert)
mov r16,r0
cp TimeLowByte,r16 ; Vergleiche die ausgelesenen Daten in r16(Lowbyte) mit den vergangenen Sekunden in r24(Lowbyte)
brne LEDvorend ; Springe wenn die beiden Register ungleich sind ans Ende
cp TimeHighByte,r17 ; Vergleiche die ausgelesenen Daten in r17(Highbyte) mit den vergangenen Sekunden in r25(Highbyte)
brne LEDvorend ; Springe wenn die beiden Register ungleich sind ans Ende
in r22,PORTB ; Hole den PortB ins R22
cpi r18,0 ; Kanal 0 voreinstellen
breq LED0sch ; Springe um Kanal 0 zu behandeln
cpi r18,1 ; Kanal 1 voreinstellen
breq LED1sch ; Springe um Kanal 1 zu behandeln
cpi r18,2 ; Kanal 2 voreinstellen
breq LED2sch ; Springe um Kanal 2 zu behandeln
cpi r18,3 ; Kanal 3 voreinstellen
breq LED3sch ; Springe um Kanal 3 zu behandeln
cpi r18,4 ; Kanal 4 voreinstellen
breq LED4sch ; Springe um Kanal 4 zu behandeln
cpi r18,5 ; Kanal 4 als Fernseher voreinstellen
breq LED4schFS ; Springe um Kanal 4 zu behandeln
LED0sch: sbrc r22,0 ; Skip wenn Bit in Register gelöscht
cbi PORTB,0 ; Lösche das Bit im PortB
sbrs r22,0 ; Skip wenn Bit in Register gesetzt
sbi PORTB,0 ; Setze das Bit im PortB
rjmp LEDweiter
LED1sch: sbrc r22,1 ; Skip wenn Bit in Register gelöscht
cbi PORTB,1 ; Lösche das Bit im PortB
sbrs r22,1 ; Skip wenn Bit in Register gesetzt
sbi PORTB,1 ; Setze das Bit im PortB
rjmp LEDweiter
LED2sch: sbrc r22,2 ; Skip wenn Bit in Register gelöscht
cbi PORTB,2 ; Lösche das Bit im PortB
sbrs r22,2 ; Skip wenn Bit in Register gesetzt
sbi PORTB,2 ; Setze das Bit im PortB
rjmp LEDweiter
LED3sch: sbrc r22,3 ; Skip wenn Bit in Register gelöscht
cbi PORTB,3 ; Lösche das Bit im PortB
sbrs r22,3 ; Skip wenn Bit in Register gesetzt
sbi PORTB,3 ; Setze das Bit im PortB
rjmp LEDweiter
LED4sch: sbrc r22,4 ; Skip wenn Bit in Register gelöscht
cbi PORTB,4 ; Lösche das Bit im PortB
sbrs r22,4 ; Skip wenn Bit in Register gesetzt
sbi PORTB,4 ; Setze das Bit im PortB
rjmp LEDweiter
LED4schFS: in r22,TIMSK ; Interrupt Timer0 (Bit1) nachschauen
ldi r16,0b00000100
sbrc r22,1 ; Skip wenn Bit 1 in Register gelöscht
rjmp LED4LEDaus
ldi r16,0b00000110
sbrs r22,1 ; Skip wenn Bit 1 in Register gesetzt
out TIMSK,r16
rjmp LEDweiter
LED4LEDaus: out TIMSK,r16
cbi PORTB,4 ; Die LED extra ausschalten, denn sie könnte gerade eingeschalten sein wenn der Interrupt still gelegt wird.
rjmp LEDweiter
LEDweiter: adiw ZregLow,1
rjmp LEDend ; Springe
LED255: mov ZregLow,r28
mov ZregHigh,r29
rjmp LEDend ; Springe
LEDvorend: sbiw ZregLow,1
LEDend: ret
;-----------------------------------------------------------------------------------
; Konstanten
;-----------------------------------------------------------------------------------
CONFIG: .byte 0b00000111
; Bit 0 ... Programm-Ablaufzyclus
; 0=Programmablauf nicht wiederholen
; 1=Programmablauf wiederholen
; Bit 1 ... Fernseher/Schweißlicht
; 0=LED flackern aus (LED arbeitet wie alle anderen)
; 1=LED flackert wenn Kanal 4 eingeschalten ist
; Bit 2 ... Kanal 2, Ein- Ausgang
; 0=Kanal 2 (PORTB2) arbeitet als Ausgang
; 1=Kanal 2 (PORTB2) arbeitet als Steuereingang
Ablaufcyc: .byte 1 ; 0 = Keine Wiederholung/Schleife des Ablaufes. 1 = Ablauf wiederholen
Timerlfzt: .byte 0x00,123 ; Timer Laufzeit bis Wiederholung oder Abbruch. (2x256 + 5x16 + 8 = 600 Sekunden)
FSon: .byte 1 ; Fernseher auf Kanal 4 ein- oder ausschalten. (Wenn 0 müsste das EEPROM nicht beladen sein!)
LED0cyc: .byte 0,1,0,30,0,36,0,60,0,100,0,121,255
LED1cyc: .byte 0,25,0,28,0,30,0,54,0,110,0,119,255
LED2cyc: .byte 0,27,0,55,0,58,0,61,0,98,0,105,255
LED3cyc: .byte 0,12,0,35,255
LED4cyc: .byte 0,2,0,68,255