; RGBLED_DimmerHSV_001.asm ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;|* Titel : *| ;|* Prozessor : *| ;|* Autor, Datum : (c) Erwin Spitaler * Created: 13.05.2012 04:02:49 *| ;|* *| ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .include "m8def.inc" ;.include "tn2313def.inc" ;------------------------------------------------------------------------------ ; CPU frequency ;------------------------------------------------------------------------------ #define F_CPU 16000000 ;------------------------------------------------------------------------------ ; Data segment ;------------------------------------------------------------------------------ .dseg ; HSB H =Farbton(grad) ; S =Sätigung , B =Helligkeit Zwischenwert01: .db 1 ; = B*(1-S) Zwischenwert02: .db 1 ; = B*(1-S*f) Zwischenwert03: .db 1 ; = B*(1-S*(1-f)) Zwischenwert_f: .db 1 ; = (hsb_H/6 -42) warum 42 weil es ca 1/6 von 255 ist RGB_R: .db 1 RGB_G: .db 1 RGB_B: .db 1 hsb_h: .db 1 hsb_s: .db 1 hsb_b: .db 1 .def par1 = r16 .def par2 = r17 .def par3 = r18 ;------------------------------------------------------------------------------ ; Code segment schreibe in Flash ;------------------------------------------------------------------------------ .cseg ;------------------------------------------------------------------------------ ; Interruptvektoren ;------------------------------------------------------------------------------ .include "vectors.asm" ;Interruptvektoren ; .org INT_VECTORS_SIZE ;------------------------------------------------------------------------------ ; Program code ;------------------------------------------------------------------------------ Main: ldi r16,LOW(RAMEND) ; init Stack Ende out SPL, r16 ldi r16,HIGH(RAMEND) out SPH, r16 clr r16 out ddrd , r16 ser r16 out ddrb , r16 out portd, r16 ;---ADC----init------------------------------------------------------------------ ldi r16, 0b01000101 ; , interne Referenzspannung 5V out ADMUX, r16 ldi r16, 0b11011111 ; , vorteiler 128 , out ADCSRA, r16 ;---ADC--------------------------------------------------------------------------- ;---PWM------------------------init PB1-2----------------------------------------- ldi r16 , 7 out PortB , r16 ldi r16 , 0b10100001 out TCCR1A , r16 ldi r16 , 0b00000010 out TCCR1B , r16 ;---PWM-----------------------init PB3-------------------------------------------- ldi r16 , 0b01100010 out TCCR2 , r16 ;---PWM--------------------------------------------------------------------------- sei clr r16 ;------------------------------------------------------------------------------ ; Main program loop ;------------------------------------------------------------------------------ MainLoop: rjmp MainLoop ;------------------------------------------------------------------------------ ; ;------------------------------------------------------------------------------ ; ADC einlesen: onADC: push r16 push r17 in r16, ADCL ; in r17, ADCH ; asr r17 ; von 10bit auf 8bit /4 ror r16 asr r17 ror r16 in r17 , admux ori r17 , 0b11111000 cpi r17 , 0b11111101 ;über prüfen welcher kanal BRSH onADC01 cpi r17 , 0b11111100 BRSH onADC02 ;anna für Hellikeits fading mit kanal 3 (PC3) sts hsb_b, r16 ; in sram laden ldi r17 , 0b01000101 out ADMUX, r17 ; kanal ändern rcall hsb_to_rgb sbi ADCSRA, ADSC ; den ADC starten pop r17 pop r16 reti onADC01: ;anna für RGB fading mit kanal 5 (PC5) sts hsb_h, r16 ; in sram laden ldi r17 , 0b01000100 out ADMUX, r17 ; kanal ändern sbi ADCSRA, ADSC ; den ADC starten pop r17 pop r16 reti onADC02: ;anna für Sättigung mit kanal 4 (PC4) sts hsb_s, r16 ; in sram laden ldi r17 , 0b01000011 out ADMUX, r17 ; kanal ändern sbi ADCSRA, ADSC ; den ADC starten pop r17 pop r16 reti ;------------------------------------------------------------------------------ ; ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ ; ;------------------------------------------------------------------------------ HSB_TO_RGB: ;sonderfall sättigung S=0? lds r16,hsb_s tst r16 ;Sättigung=0? brne hsb2rgb1 ;nein: dann normal weiter lds r16,hsb_b ;ja: RGB alle auf B-Wert setzen sts rgb_r,r16 sts rgb_g,r16 sts rgb_b,r16 rjmp end_hsb_to_rgb hsb2rgb1: ;1. zwischenwert: v1=(hsb_B*(255-hsb_S)) div 255 (oder256?) lds zl , hsb_s com zl ;(255-hsb_S) lds zh , hsb_b ;(hsb_B*(255-hsb_S)) rcall hsb_mult ;jetzt durch 255(?256?) div also nur high byte nehmen sts zwischenwert01 , zh ;-;-;-;-;-;-;-;-;;-;-;-;-;-;-;-;-;;-;-;-;-;-;-;-;-;;-;-;-;-;-;-;-;-; ;f=(hsb_H/6 -42) warum 42 weil es ca 1/6 von 255 ist clr zh lds zl, hsb_H lsl zl ;mal 32 dann ist f/32 rol zh;2 lsl zl rol zh;4 lsl zl rol zh;8 lsl zl rol zh;16 lsl zl rol zh;32 ;duch 42 div ldi r16 , -1 div42: inc r16 subi zl, low(42) sbci zh, high(42) brcc div42 sts zwischenwert_f , r16 ;f/32 ;-;-;-;-;-;-;-;-;;-;-;-;-;-;-;-;-;;-;-;-;-;-;-;-;-;;-;-;-;-;-;-;-;-; ;2. zwischenwert: v2=(hsb_B*(255-hsb_s*f); lds zl , zwischenwert_f lds zh , hsb_s ;zh=S rcall hsb_mult ;zh:zl=(S*f) ;div 255 in dem man zh nimmt com zh ;(255-hsb_s*f) ;$FF - zh mov r16 , zh ;div 32 um von f/32 clr zh asr r16 ror zh asr r16 ror zh asr r16 ror zh asr r16 ror zh asr r16 ror zh lds zl , hsb_b ;(hsb_B*(255-hsb_s*f) rcall hsb_mult ;jetzt durch 255 div also nur high byte nehmen sts zwischenwert02 , zh ;3. zwischenwert: v3=255-((S*(255-f)) div 255)); v3=(B*v3) div 255 B*(1-S*(1-f)) lds zl , zwischenwert_f com zl ;(255-f) mov r16 , zl ;(255-f)/32 clr zl asr r16 ror zl asr r16 ror zl asr r16 ror zl asr r16 ror zl asr r16 ror zl lds zh , hsb_s rcall hsb_mult ;(S*(255-f) danach div also high byte nehmen com zh ;255-((S*(255-f)) div 255)) lds zl , hsb_b ;(B*v3) rcall hsb_mult ;jetzt durch 255 div also nur high byte nehmen sts zwischenwert03 , zh /* ldi zl,100 sub zl,par2 ;zl=(100-f) (f steht ja noch in par2) lds zh,hsb_s ;zh=S rcall hsb_mult ;zh:zl=(S*(100-f)) rcall hsb_div100 ;zl=(S*(100-f)) div 100 ldi zh,100 sub zh,zl ;zh=100-((S*(100-f)) div 100) lds zl,hsb_b ;zl=B rcall hsb_mult ;zh:zl=B*(100-((S*(100-f)) div 100)) rcall hsb_div100 ;zl=(B*(100-((S*(100-f)) div 100))) div 100 push zl ;auf stack sichern */ lds r16 , hsb_h cpi r16 , 42 BRLO eins cpi r16 , 84 BRLO zwei cpi r16 , 126 BRLO drei cpi r16 , 168 BRLO vier cpi r16 , 210 BRLO fuenf cpi r16 , 255 BRLO sechs01 sechs01: rjmp sechs eins: lds r16 , hsb_b sts RGB_R , r16 lds r16 , Zwischenwert03 sts RGB_G , r16 lds r16 , Zwischenwert01 sts RGB_B , r16 rjmp end_hsb_to_rgb zwei: lds r16 , Zwischenwert02 sts RGB_R , r16 lds r16 , hsb_b sts RGB_G , r16 lds r16 , Zwischenwert01 sts RGB_B , r16 rjmp end_hsb_to_rgb drei: lds r16 , Zwischenwert01 sts RGB_R , r16 lds r16 , hsb_b sts RGB_G , r16 lds r16 , Zwischenwert03 sts RGB_B , r16 rjmp end_hsb_to_rgb vier: lds r16 , Zwischenwert01 sts RGB_R , r16 lds r16 , Zwischenwert02 sts RGB_G , r16 lds r16 , hsb_b sts RGB_B , r16 rjmp end_hsb_to_rgb fuenf: lds r16 , Zwischenwert03 sts RGB_R , r16 lds r16 , Zwischenwert01 sts RGB_G , r16 lds r16 , hsb_b sts RGB_B , r16 rjmp end_hsb_to_rgb sechs: lds r16 , hsb_b sts RGB_R , r16 lds r16 , Zwischenwert01 sts RGB_G , r16 lds r16 , Zwischenwert02 sts RGB_B , r16 end_hsb_to_rgb: clr r17 lds r16 , RGB_R out OCR1AH , r17 out OCR1AL , r16 lds r16 , RGB_G out OCR1BH , r17 out OCR1BL , r16 lds r16 , RGB_B out OCR2 , r16 ret ;=============================== ;zh:zl = zh*zl, alternative Routine für ATmega ;umbenennen in HSB_mult, obige HSB_mult entfernen HSB_Mult: push R0 ;kann entfallen, wenn r0 ungenutzt ist push R1 ;kann entfallen, wenn r1 ungenutzt ist mul zh,zl movw zh:zl,R1:R0 pop R1 ;kann entfallen, wenn r1 ungenutzt ist pop R0 ;kann entfallen, wenn r0 ungenutzt ist ret ;------------------------------------------------------------------------------ ; ;------------------------------------------------------------------------------ ; Include source files ;------------------------------------------------------------------------------ ;.include ".asm" ;####################################################################################################### ;################# End of main.asm file '''############################# ;####################################################################################################### ;####################################################################################################### /* vectors.asm file .org 0x000 rjmp Main .org INT0addr ; External Interrupt0 Vector Address reti .org INT1addr ; External Interrupt1 Vector Address reti .org OC2addr ; Output Compare2 Interrupt Vector Address reti .org OVF2addr ; Overflow2 Interrupt Vector Address reti .org ICP1addr ; Input Capture1 Interrupt Vector Address reti .org OC1Aaddr ; Output Compare1A Interrupt Vector Address reti .org OC1Baddr ; Output Compare1B Interrupt Vector Address reti .org OVF1addr ; Overflow1 Interrupt Vector Address reti .org OVF0addr ; Overflow0 Interrupt Vector Address reti .org SPIaddr ; SPI Interrupt Vector Address reti .org URXCaddr ; USART Receive Complete Interrupt Vector Address reti .org UDREaddr ; USART Data Register Empty Interrupt Vector Address reti .org UTXCaddr ; USART Transmit Complete Interrupt Vector Address reti .org ADCCaddr ; ADC Interrupt Vector Address rjmp onADC ;reti .org ERDYaddr ; EEPROM Interrupt Vector Address reti .org ACIaddr ; Analog Comparator Interrupt Vector Address reti .org TWIaddr ; Irq. vector address for Two-Wire Interface reti .org SPMRaddr ; SPM complete Interrupt Vector Address reti End of vectors.asm file */