; *************************************************************** ; * ; * LED-PWM-Dimmer fr atmolight (vdr) ; * ; * Externe Beschaltung: ; * PORTA0-A5: RGB RGB ; * ; * PB0..PB2 : Startadresse 1. RGB Kanal (invertiert) ; * PD5..PD7 : Startadresse 2. RGB Kanal (invertiert) ; * Wenn eine Adresse auf 0x07 steht, wird sie aus dem EEPROM ; * gelesen, Format siehe Ende dieser Datei! ; * ; * Quarz 14,7456MHz an XTAL1/XTAL2 ; * MAX232 soll von der RS232 lesen und an Pin2=RXD liefern ; * ; * Version 0.0.1-15 ; * Simon Canins ; * ; *************************************************************** .NOLIST .INCLUDE "m8def.inc" .LIST ; ; ; Register: ; .DEF addr=R0; Benutzt zum Auslesen der Startadresse .DEF buffer=R1; Zeichenpuffer serielle Kommunikation ; ;------Sollwerte der Farben .DEF R1L=R2 .DEF R1H=R3 .DEF G1L=R4 .DEF G1H=R5 .DEF B1L=R6 .DEF B1H=R7 .DEF R2L=R8 .DEF R2H=R9 .DEF G2L=R10 .DEF G2H=R11 .DEF B2L=R12 .DEF B2H=R13 .DEF temp=R16; Temp-Register f. Hauptprogramm .DEF temp2=R17; Temp-Register und Parameter fr Gamma-Funktion .DEF sreg_buffer=R18 ; Zum zwischenspeichern von SREG im Interrupt .DEF itemph=R20; Temp-Register f. Interruptroutine .DEF itempl=R21 .DEF itemp2=R22 .DEF rs232state=R23; Statemachine RS232 Kommunikation .DEF pwmH=R24 ; Rckgabewert der Gamma-Funktion H .DEF pwmL=R25 ; Rckgabewert der Gamma-Funktion L ; X=R26/27: Z�ler fr PWM ; Y=R28/29: Adressen ; Z=R30/31: Pointer zum Auslesen der Gamma-Tabelle ; ; Konstanten ; ;.EQU freq=11059200; Taktfrequenz .EQU freq= 14745600; Taktfrequenz ;.EQU freq=16000000; Taktfrequenz ;.EQU freq=8000000; Taktfrequenz .EQU baud=38400; Baudrate fuer RS232 //.EQU baud=19200; Baudrate fuer RS232 .EQU bddiv=(freq/(16*baud))-1; Baudratenteiler .EQU AusgPort=PORTC ; Welcher Port soll zur Ausgabe verwendet werden? (6bits) .EQU AusgDDR=DDRC ; ; Code segment startet hier ; .CSEG ; ; Reset- und Interrupt-Vektoren ; rjmp Start; RESET reti; reti; reti; reti; reti; rjmp TIMER1COMPA; TIMER1 OCIE1A reti; reti; rjmp TIMER0OVL; reti; reti; reti; reti; reti; reti; reti; reti; reti; reti; ;***************************** ; Interruptroutinen ;***************************** ;------------------------------------------------------------------------------- ; PWM Erzeugung TIMER1COMPA: in sreg_buffer,SREG ; SREG sichern ldi itemph, 0; Timer1 wieder auf 0 stellen out TCNT1H, itemph out TCNT1L, itemph sbiw XL, 2; PWM Counter um 1 erniedrigen ldi itemp2, 0xFF; Byte, das sp�er auf Port ausgegeben werden soll vorbereiten ; R1--------------------------------------- cp XL, R1L; Sollwert mit PWM Counter vergleichen cpc XH, R1H brlo pwmR1 cbr itemp2, 1 ; Wenn Z�ler gr�er, dann Bit setzen pwmR1: ; G1--------------------------------------- cp XL, G1L; Sollwert mit PWM Counter vergleichen cpc XH, G1H brlo pwmG1 cbr itemp2, 2 ; Wenn Z�ler gr�er, dann Bit setzen pwmG1: ; B1--------------------------------------- cp XL, B1L; Sollwert mit PWM Counter vergleichen cpc XH, B1H brlo pwmB1 cbr itemp2, 4 ; Wenn Z�ler gr�er, dann Bit setzen pwmB1: ; R2--------------------------------------- cp XL, R2L; Sollwert mit PWM Counter vergleichen cpc XH, R2H brlo pwmR2 cbr itemp2, 8 ; Wenn Z�ler gr�er, dann Bit setzen pwmR2: ; G2--------------------------------------- cp XL, G2L; Sollwert mit PWM Counter vergleichen cpc XH, G2H brlo pwmG2 cbr itemp2, 16 ; Wenn Z�ler gr�er, dann Bit setzen pwmG2: ; B2--------------------------------------- cp XL, B2L; Sollwert mit PWM Counter vergleichen cpc XH, B2H brlo pwmB2 cbr itemp2, 32 ; Wenn Z�ler gr�er, dann Bit setzen pwmB2: out AusgPort, itemp2; auf Port ausgeben cpi XL, 0 brne int_weiter1; wenn noch nicht 0, dann weiter, sonst wieder auf max.Wert setzen cpi XH, 0 brne int_weiter1; wenn noch nicht 0, dann weiter, sonst wieder auf max.Wert setzen ldi XH, HIGH(2047); Wenn Counter auf 0 abgelaufen, dann wieder auf ldi XL, LOW(2047); Maximalwert setzen int_weiter1: ldi itempl, 1 ; Prfen, ob PWM Counter den Wert 2 erreicht hat ldi itemph, 0 cp itempl, XL cpc itemph, XH brne int_weiter2; Wenn ja, dann auf 2047 setzen, so werden 2 Counterdurchl�ft ; erreicht, einer mit geraden Zahlen, einer mit ungeraden ; das verringert das Flimmern ldi XH, HIGH(2046) ldi XL, LOW(2046) int_weiter2: out SREG,sreg_buffer ; SREG wiederherstellen reti ;-------------------------------------------------------------------------------- ; RS232 Timeout TIMER0OVL: clr rs232state ; Statemachine wieder auf Anfang setzen reti ;***************************** ; Hauptprogramm ;***************************** Start: ; ; Stack initialisieren ; ldi temp,HIGH(RAMEND) out SPH,temp ldi temp,LOW(RAMEND) out SPL,temp ; ; Ports initialisieren ; ldi temp,0xFF; Port als Ausgang festlegen (PWM-Ausgabe) out AusgDDR,temp ldi temp, 0x00; Port auf 0 setzen out AusgPort, temp ldi temp, 0xF8 out DDRB, temp; Port als Eingang festlegen (Adresseinstellung RGB1) ldi temp, 0x07 out PORTB, temp;Pullups aktivieren ldi temp, 0x1F out DDRD, temp; Port als Eingang festlegen (Adresseinstellung RGB2) ldi temp, 0xE0 out PORTD, temp;Pullups aktivieren ; ; Sollwerte initialisieren ; ldi temp, 0x00 mov R1L, temp mov R1H, temp mov G1L, temp mov G1H, temp mov B1L, temp mov B1H, temp mov R2L, temp mov R2H, temp mov G2L, temp mov G2H, temp mov B2L, temp mov B2H, temp ; ; USART initialisieren ; ldi temp, bddiv; Setze Baudrate out UBRRL, temp ldi temp, 0x00 out UCSRA, temp sbi UCSRB, RXEN; RX einschalten // sbi UCSRB, TXEN ldi temp, (1< Overflow bei 16MHz alle 4,096ms out TCCR0, temp ; ; Timer1 initialisiern (PWM Erzeugung) ; ldi temp, 0 out TCCR1A, temp out OCR1AH, temp; OCR1AH setzen, alle wieviel Take soll der Int aufgerufen werden ldi temp, 70 out OCR1AL, temp ldi temp, (1< Interrupt) out TCNT0, temp in buffer, UDR ; Zeichen lesen ; Statemachine ; Erkennung des Headers ldi temp, 0x00 ;statemachine: Startbyte cp temp, rs232state breq startbyte; ldi temp, 0x01 ;statemachine: StartL cp temp, rs232state breq startL; ldi temp, 0x02 ;statemachine: StartH cp temp, rs232state breq startH ldi temp, 0x03 ;statemachine: LEN cp temp, rs232state breq LEN rjmp state_weiter ; Bearbeiten der gefundenen Bytes startbyte: ldi temp, 0xFF cp buffer, temp breq ok_state1; Wenn richtiges Byte gefunden rjmp fail; Sonst von vorne beginnen startL: ldi temp, 0x0 cp buffer, temp breq ok_state1; Wenn richtiges Byte gefunden rjmp fail; Sonst von vorne beginnen startH: ldi temp, 0x0 cp buffer, temp breq ok_state1; Wenn richtiges Byte gefunden rjmp fail; Sonst von vorne beginnen LEN: ldi temp, 0x0F cp buffer, temp breq ok_state1; Wenn richtiges Byte gefunden // rjmp fail; Sonst von vorne beginnen fail:; Fehler bei der Bearbeitung, -> neu beginnn ldi rs232state, 0x00 rjmp end ok_state1: ; steht nur hier, da branch nicht weit genug kommt rjmp ok ; Verarbeitung mit den Farb-Bytes fortsetzen state_weiter: in YL, PINB ; Startadresse 1. RGB Kanal einlesen in YH, PIND ; Startadresse 2. RGB Kanal einlesen lsr YH ; Startadresse 2. RGB Kanal 5 bits nach rechts schieben lsr YH lsr YH lsr YH lsr YH andi YL, 0x07 ; relevante bits herausfiltern andi YH, 0x07 ; relevante bits herausfiltern cpi YL, 0x07 ; Wenn Adresse == 7, dann aus dem EEPROM lesen brne adr_weiter sbi EECR, EERE ; EEPROM Lesen Vorbereiten in YL, EEDR ; EEPROM lesen andi YL, 0x07 ; relevante Bits herausfiltern adr_weiter: cpi YH, 0x07 ; Wenn Adresse == 7, dann aus dem EEPROM lesen brne adr_weiter2 sbi EECR, EERE ; EEPROM Lesen Vorbereiten in YH, EEDR ; EEPROM lesen lsr YH ; Shift um 3 nach rechts lsr YH lsr YH andi YH, 0x07 ; relevante Bits herausfiltern adr_weiter2: ;--------------------------RGB1---------------------------- ldi temp, 0x04 ;statemachine: R1 cp temp, rs232state brne R1next ; Wenn dieses Byte nicht R1 ist dann Bearbeitung berspringen mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x00 ; 1. RGB Kanal auf Adresse 0 ? brne R1weiter ; wenn nicht, Abspeichern berspringen mov R1L, pwmL ; wenn ja, dort abspeichern mov R1H, pwmH R1weiter: ; wenn 1. RGB Kanal nicht auf Adresse 0 hier weitermachen cpi YH, 0x00 ; 2. RGB Kanal auf Adresse 0 ? brne ok_state2; wenn nicht, Bearbeitung beenden mov R2L, pwmL ; wenn ja, dort abspeichern mov R2H, pwmH rjmp ok ; Bearbeitung beenden R1next: ldi temp, 0x05 ;statemachine: G1 cp temp, rs232state brne G1next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x00 brne G1weiter mov G1L, pwmL mov G1H, pwmH G1weiter: cpi YH, 0x00 brne ok_state2 mov G2L, pwmL mov G2H, pwmH rjmp ok G1next: ldi temp, 0x06 ;statemachine: B1 cp temp, rs232state brne B1next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x00 brne B1weiter mov B1L, pwmL mov B1H, pwmH B1weiter: cpi YH, 0x00 brne ok_state2 mov B2L, pwmL mov B2H, pwmH rjmp ok ok_state2: ; steht nur hier, da branch nicht weit genug kommt rjmp ok ;--------------------------RGB2---------------------------- B1next: ldi temp, 0x07 ;statemachine: R2 cp temp, rs232state brne R2next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x01 brne R2weiter mov R1L, pwmL mov R1H, pwmH R2weiter: cpi YH, 0x01 brne ok_state3 mov R2L, pwmL mov R2H, pwmH rjmp ok R2next: ldi temp, 0x08 ;statemachine: G2 cp temp, rs232state brne G2next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x01 brne G2weiter mov G1L, pwmL mov G1H, pwmH G2weiter: cpi YH, 0x01 brne ok_state3 mov G2L, pwmL mov G2H, pwmH rjmp ok G2next: ldi temp, 0x09 ;statemachine: B2 cp temp, rs232state brne B2next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x01 brne B2weiter mov B1L, pwmL mov B1H, pwmH B2weiter: cpi YH, 0x01 brne ok_state3 mov B2L, pwmL mov B2H, pwmH rjmp ok ok_state3: ; steht nur hier, da branch nicht weit genug kommt rjmp ok ;--------------------------RGB3---------------------------- B2next: ldi temp, 0x0A ;statemachine: R3 cp temp, rs232state brne R3next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x02 brne R3weiter mov R1L, pwmL mov R1H, pwmH R3weiter: cpi YH, 0x02 brne ok_state3 mov R2L, pwmL mov R2H, pwmH rjmp ok R3next: ldi temp, 0x0B ;statemachine: G3 cp temp, rs232state brne G3next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x02 brne G3weiter mov G1L, pwmL mov G1H, pwmH G3weiter: cpi YH, 0x02 brne ok_state3 mov G2L, pwmL mov G2H, pwmH rjmp ok G3next: ldi temp, 0x0C ;statemachine: B3 cp temp, rs232state brne B3next; wenn kein Zustand passt, neu anfangen mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x02 brne B3weiter mov B1L, pwmL mov B1H, pwmH B3weiter: cpi YH, 0x02 brne ok_state3 mov B2L, pwmL mov B2H, pwmH rjmp ok ;--------------------------RGB4---------------------------- B3next: ldi temp, 0x0D ;statemachine: R4 cp temp, rs232state brne R4next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x03 brne R4weiter mov R1L, pwmL mov R1H, pwmH R4weiter: cpi YH, 0x03 brne ok_state4 mov R2L, pwmL mov R2H, pwmH rjmp ok R4next: ldi temp, 0x0E ;statemachine: G4 cp temp, rs232state brne G4next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x03 brne G4weiter mov G1L, pwmL mov G1H, pwmH G4weiter: cpi YH, 0x03 brne ok_state4 mov G2L, pwmL mov G2H, pwmH rjmp ok G4next: ldi temp, 0x0F ;statemachine: B4 cp temp, rs232state brne B4next; wenn kein Zustand passt, neu anfangen mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x03 brne B4weiter mov B1L, pwmL mov B1H, pwmH B4weiter: cpi YH, 0x03 brne ok_state4 mov B2L, pwmL mov B2H, pwmH rjmp ok ok_state4: ; steht nur hier, da branch nicht weit genug kommt rjmp ok ;--------------------------RGB5---------------------------- B4next: ldi temp, 0x10 ;statemachine: R5 cp temp, rs232state brne R5next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x04 brne R5weiter mov R1L, pwmL mov R1H, pwmH R5weiter: cpi YH, 0x04 brne ok_state4 mov R2L, pwmL mov R2H, pwmH rjmp ok R5next: ldi temp, 0x11 ;statemachine: G5 cp temp, rs232state brne G5next mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x04 brne G5weiter mov G1L, pwmL mov G1H, pwmH G5weiter: cpi YH, 0x04 brne ok_state4 mov G2L, pwmL mov G2H, pwmH rjmp ok G5next: ldi temp, 0x12 ;statemachine: B5 cp temp, rs232state brne B5next; wenn kein Zustand passt, neu anfangen mov temp2, buffer ; Gamma Korrektur anwenden rcall gammakorr ; Startadresse berprfen cpi YL, 0x04 brne B5weiter mov B1L, pwmL mov B1H, pwmH B5weiter: cpi YH, 0x04 brne ok_state4 mov B2L, pwmL mov B2H, pwmH rjmp ok B5next: rjmp fail fail_state: ; nur forward rjmp fail ok:; Byte erfolgreich bearbeitet inc rs232state ; Statemachine weiterz�len ldi temp, 0x15 ; Obergrenze berprfen cp rs232state, temp brne end ; Wenn letztes Byte noch nicht erreicht, weitermachen rjmp fail ; sonst Statemachine zurcksetzen und neu beginnen mit n�hster �ertragung end: ret .ESEG;------------------------------EEPROM-------------------------------------- Adresse: .DB 0 ; Startadresse auf dem RS232 Bus ; Format: --xxxyyy ; xxx Startadresse 2. RGB Kanal ; yyy Startadresse 1. RGB Kanal