Pfad: Home => AVR-Übersicht => Anwendungen => LED-Licht => Software
LED-Licht

Software für das Ledlicht mit ATtiny13



;
; ***********************************
; *  Ledlicht mit einem ATtiny13    *
; * (C)2012 by avr-asm-tutorial.net *
; ***********************************
;
.nolist
.include "tn13def.inc"
.list
;
; *******************
;   H A R D W A R E
; *******************
;
;          ____________
;         /            |
; RES o--|             |--o VCC
;        |     AT      |
;  S3 o--|             |--o S2/SCK
;        |    tiny     |
;  S4 o--|             |--o OUT/MISO
;        |     13      |
; GND o--|             |--o S1/MOSI
;        |_____________|
;
; Eingangs-Portbits Schalter
.equ bS1In = 0
.equ bS2In = 2
.equ bS3In = 3
.equ bS4In = 4
;
; Ausgangs-Portbit LED-Ansteuerung
.equ bOut = 1
;
; ***************************************************
;  W I E   D I E   S O F T W A R E   A R B E I T E T
; ***************************************************
;
; Prozessor:
;   Arbeitet mit 1.2 MHz Default Takt
;   Default R/C-Oszillator geteilt durch 8
;   Default Fuse-Einstellungen
; Timer 0:
;   Arbeitet als Fast PWM mit TOP=15
;   Systemtakt durch 256 geteilt
;   f(PWM) = 293 Hz
;   OC0B steuert PWM-Verhaeltnis (0 .. 15)
;     OCR0B wird gesetzt aus dem unteren Nibble der Tabellenbytes
;     Setzt OC0B-Ausgang bei Zyklusbeginn
;     Loescht Ausgang bei Compare Match
;   OC0A setzt TOP und loest Interrupts aus
; Timing der Zyklen:
;   Oberes Nibble der Tabellenbytes setzt Anzahl PWM-Zyklen (Dauer)
;     (16 bis 256)
;   Resultiert in Zeiten zwischen 0,055 und 0,88 Sekunden Dauer
; Eingangsschalter:
;   S1: wenn gesetzt halbiert die Helligkeit (PWM / 2)
;   S2: wenn gesetzt ver-16-facht die Geschwindigkeit (Zyklusdauer / 16)
;   S3, S4: waehlt Programm aus
;     00: LEDs an und aus 10 mal
;     01: Modulierter Anstieg und Abfall der Helligkeit
;     02: Linearer Anstieg und Abfall der Helligkeit
;     03: Nacheinander Programme 02, 01 und 00
;
; *******************
;   R E G I S T E R 
; *******************
;
; Frei: R0..R14
.def rSreg = R15 ; zum Sichern und Wiederherstellen des SREG bei Interrupts
.def rmp = R16 ; Vielzweckregister ausserhalb Interrupts
.def rimp = R17 ; Vielzweckregister innerhalb Interrupts
.def rCnt = R18 ; Zaehlregister fuer PWM-Zyklen
.def rC3 = R19 ; Zaehler fuer Programmauswahl in Modus 03
; Frei: R20 .. R29
; Benutzt: ZH:ZL als Zeiger auf Flashtabelle
;
; *********************************************
;  R E S E T   U N D   I N T - V E K T O R E N
; *********************************************
;
	rjmp main ; Reset Vektor
	reti ; INT0
	reti ; PCINT0
	rjmp Tc0Int ; TIM0_OVF
	reti ; EE_RDY
	reti ; ANA_COMP
	reti ; TIM0_COMPA
	reti ; TIM0_COMPB
	reti ; WDT
	reti ; ADC
;
; Interruptvektor TIM0_OVF
;
Tc0Int:
	in rSreg,SREG ; sichere SREG
	dec rCnt ; naechster PWM-Zyklus
	brne Tc0IntRet ; wenn nicht Null mache weiter
	lpm rCnt,Z+ ; lese naechstes Tabellenbyte und erhoehe Zeiger
	mov rimp,rCnt ; kopiere Byte nach rimp
	andi rimp,0x0F ; maskiere oberes Nibble
	sbis PINB,bS1In ; halbe Intensitaet?
	lsr rimp ; halber PWM-Zyklus
	out OCR0B,rimp ; schreibe in PWM Compare
	andi rCnt,0xF0 ; maskiere unteres Nibble
	sbis PINB,bS2In ; 16-fach schneller?
	swap rCnt ; 16 mal schneller
Tc0Int1:
	lpm rimp,Z ; lese naechsten Tabellenwert
	tst rimp ; Null?
	brne Tc0IntRet ; nicht Null, mach weiter so
	out SREG,rSreg ; stelle SREG wieder her
	set ; setze T-Flagge
	reti ; Ruuckkehr vom Interrupt
Tc0IntRet:
	out SREG,rSreg ; stelle SREG wieder her
	reti ; Rueckkehr vom Interrupt
;
; ***************************************
;  H A U P T P R O G R A M M   S T A R T
; ***************************************
;
Main:
	; Initiiere Stapel
	ldi rmp,LOW(RAMEND) ; RAMEND in SPL
	out SPL,rmp
	; Initiiere Ports
	ldi rmp,1<<bOut ; Ausgangsport als Ausgang
	out DDRB,rmp
	ldi rmp,0x1F-(1<<bOut) ; Pull-Up-Widerstaende und LEDs an
	out PORTB,rmp
	; initiiere Z-Zeiger
	ldi ZH,HIGH(2*Tab1) ; Zeiger Z auf Tab1
	ldi ZL,LOW(2*Tab1)
	ldi rCnt,1 ; Zaehler auf Eins
	; initiiere Timer 0, Fast PWM, COMPB als positiver PWM 
	ldi rmp,0x0F ; Compare A setzt TOP
	out OCR0A,rmp
	ldi rmp,0x00 ; Compare B auf LEDs Aus
	out OCR0B,rmp
	ldi rmp,(1<<COM0B1)|(1<<WGM01)|(1<<WGM00) ; Fast PWM
	out TCCR0A,rmp
	ldi rmp,(1<<WGM02)|(1<<CS02) ; Vorteiler=256, Starten
	out TCCR0B,rmp
	ldi rmp,1<<TOIE0 ; Interrupt bei TOP
	out TIMSK0,rmp
	; initiere Schlafen und Interrupts
	ldi rmp,1<<SE ; Schlafmodus Idle
	out MCUCR,rmp
	sei ; Interrupts anschalten
;
; ***************************
;  H A U P T S C H L E I F E
; ***************************
;
Loop:
	sleep ; gehe schlafen
	nop
	brtc Loop ; nichts zu tun, geh wieder schlafen
	clt ; Loesche Flagge
	in rmp,PINB ; lese Schalter
	andi rmp,0x18 ; maskiere alle Schalter ausser S3+S4
	brne Loop2
	; Programm ist 03
	inc rC3
	inc rC3
	cpi rC3,7 ; ueber der Grenze?
	brcs Loop1 ; nein
	clr rC3 ; starte von vorne
Loop1:
	ldi ZH,HIGH(2*TabPtr) ; Zeige auf Zeigertabelle
	ldi ZL,LOW(2*TabPtr)
	add ZL,rC3 ; addiere Offset
	ldi rmp,0 ; MSB korrekt? 
	adc ZH,rmp
	lpm rmp,Z+ ; Lese Tabellenadresse
	lpm ZH,Z
	mov ZL,rmp
	rjmp Loop ; weiter im Takt
Loop2: ; Lese Schalter
	lsr rmp ; dividiere durch 2
	lsr rmp ; dividiere durch 4
	ldi ZH,HIGH(2*TabPtr) ; Zeige auf Zeigertabelle
	ldi ZL,LOW(2*TabPtr)
	add ZL,rmp ; addiere Offset
	ldi rmp,0 ; MSB korrekt?
	adc ZH,rmp
	lpm rmp,Z+ ; lese Tabellenadresse
	lpm ZH,Z
	mov ZL,rmp
	rjmp Loop ; weiter im Takt
;
; Zeigertabelle
;
TabPtr: 
	.dw 2*Tab1 ; Programm 03, starte mit Programm 01
	.dw 2*Tab3 ; dto., Programm 02
	.dw 2*Tab2 ; dto., Programm 01
	.dw 2*Tab1 ; Zeiger auf Programm 00
;
; Tabellen fuer Ablaufprogramme
; Unteres Byte: erster Zyklus
;   Unteres Nibble: Helligkeit 0..F
;   Oberes Nibble: 16*Anzahl PWM-Zyklen
; Oberes Byte: zweiter Zyklus
;   Nibbles dito.
; Ende des Programmablaufs: 00
;
Tab1:
	.dw 0xFFF0 ; aus und an (Blinken)
	.dw 0xFFF0
	.dw 0xFFF0
	.dw 0xFFF0
	.dw 0xFFF0
	.dw 0xFFF0
	.dw 0xFFF0
	.dw 0xFFF0
	.dw 0xFFF0
	.dw 0x0000 ; Ende
Tab2: ; Modulierter Anstieg und Abfall
	.dw 0xA0C1
	.dw 0xA1C2
	.dw 0xA2C3
	.dw 0xA3C4
	.dw 0xA4C5
	.dw 0xA5C6
	.dw 0xA6C7
	.dw 0xA7C8
	.dw 0xA8C9
	.dw 0xA9CA
	.dw 0xAACB
	.dw 0xABCC
	.dw 0xACCD
	.dw 0xADCE
	.dw 0xAECF
	.dw 0xAFCE
	.dw 0xAECD
	.dw 0xADCC
	.dw 0xACCB
	.dw 0xABCA
	.dw 0xAAC9
	.dw 0xA9C8
	.dw 0xA8C7
	.dw 0xA7C6
	.dw 0xA6C5
	.dw 0xA5C4
	.dw 0xA4C3
	.dw 0xA3C2
	.dw 0xA2C1
	.dw 0xA1C0
	.dw 0xA0C1
	.dw 0xA1C2
	.dw 0xA2C3
	.dw 0xA3C4
	.dw 0xA4C5
	.dw 0xA5C6
	.dw 0xA6C7
	.dw 0xA7C8
	.dw 0xA8C9
	.dw 0xA9CA
	.dw 0xAACB
	.dw 0xABCC
	.dw 0xACCD
	.dw 0xADCE
	.dw 0xAECF
	.dw 0xAFCE
	.dw 0xAECD
	.dw 0xADCC
	.dw 0xACCB
	.dw 0xABCA
	.dw 0xAAC9
	.dw 0xA9C8
	.dw 0xA8C7
	.dw 0xA7C6
	.dw 0xA6C5
	.dw 0xA5C4
	.dw 0xA4C3
	.dw 0xA3C2
	.dw 0xA2C1
	.dw 0xA1C0
	.dw 0x0000
Tab3:
	.dw 0xC1C0 ; Linearer Anstieg und Abfall
	.dw 0xC3C2
	.dw 0xC5C4
	.dw 0xC7C6
	.dw 0xC9C8
	.dw 0xCBCA
	.dw 0xCDCC
	.dw 0xCFCE
	.dw 0xCDCE
	.dw 0xCBCC
	.dw 0xC9CA
	.dw 0xC7C8
	.dw 0xC5C6
	.dw 0xC3C4
	.dw 0xC1C2
	.dw 0xC1C0
	.dw 0xC3C2
	.dw 0xC5C4
	.dw 0xC7C6
	.dw 0xC9C8
	.dw 0xCBCA
	.dw 0xCDCC
	.dw 0xCFCE
	.dw 0xCDCE
	.dw 0xCBCC
	.dw 0xC9CA
	.dw 0xC7C8
	.dw 0xC5C6
	.dw 0xC3C4
	.dw 0xC1C2
	.dw 0x00C0
TabEnd:
;
; Ende des Quellcodes
;
.db "(C)2012 by Gerhard Schmidt",0x00,0x00
.db "C(2)10 2ybG reahdrS hcimtd",0x00,0x00



An den Seitenanfang

©2012 by http://www.avr-asm-tutorial.net