;**************************************** ;* * ;* BARGRAPH mit 16Bit * ;* auf 8 LEDs * ;* mit SoftPWM zweistufig * ;* * ;* by Steven Wagner * ;**************************************** ;Info: ;Natürlich ist es auch möglich das Programm in eine ;Subroutine umzufunktionieren. ; .include "m16def.inc" .def temp1 = R16 .def Wert = R17 .def Stelle = R18 .def LReg = R19 ; Leuchtregister .def BReg = R20 ; Blinkregister .def Clock = R21 .equ LPORT = PORTD .equ LDDR = DDRD .equ AD_PIN = (3 + 0b01100000) ; Pin + Einstellung .org 0x0000 rjmp main ; Reset Handler .org OVF0addr rjmp timer0_overflow ; Timer Overflow Handler main: ldi temp1, LOW(RAMEND) ; Stackpointer initialisieren out SPL, temp1 ldi temp1, HIGH(RAMEND) out SPH, temp1 ldi temp1, AD_Pin ; hier wird die Referenzspannung, Rechts- oder out ADMUX, temp1 ; Linksbündigkeit und der Pin angegeben ldi temp1, 0b10000111 ; Der ADC wird Eingeschaltet und der out ADCSRA, temp1 ; Prescaler eingestellt ser temp1 ; I/O-Register initialisieren out LDDR, temp1 ldi temp1, 0b00000010 ; CS00 setzen: Teiler 1 out TCCR0, temp1 ldi temp1, 0b00000001 ; TOIE0: Interrupt bei Timer Overflow out TIMSK, temp1 sample_adc: sbi ADCSRA, ADSC ; den ADC starten. In ADSC ist das Bit 6 hinterlegt wait_adc: sbic ADCSRA, ADSC ; wenn der ADC fertig ist, wird dieses Bit ADSC gelöscht rjmp wait_adc ; falls nicht wird weiter geprüft in Wert, ADCH ; Obere 8Bit des ADC einlesen bargraph: sei ; Globales Interruptflag setzen clr temp1 wait: cpi temp1, 1 brne wait clr Stelle ; Variablen vorbereiten clr BReg clr LReg bar_check: ldi temp1, 16 ; Faktor laden cpi Stelle, 16 ; Wenn die Stellenanzahl erreicht ist brsh bar_end ; zu bar_end springen mul temp1, Stelle ; Stelle mit Faktor multiplizieren mov temp1, r0 ; und in temp1 speichern inc Stelle cp temp1, Wert ; Vergleich brsh bar_zero ; wenn Wert größer als temp1, zu zero springen subi temp1, -1 ; Hysterese von 1 cp temp1, Wert ; Vergleich brlo bar_one ; wenn Wert kleiner als temp1, zu one springen rjmp bar_end ; wenn innerhalb der Hysterese, abbrechen ; bar_one:clc ; Carry löschen cpi Stelle, 9 ; ab Stelle 9 wird der Helle Balken überlagert brsh barHigh sec ; BlinkRegister wird mit 1en gefüllt rol BReg ; clc ; rjmp bar_Check ; weitere Stellen Prüfen barHigh:sec ; LeuchtRegister wird mit 1en gefüllt rol LReg ; und beim Blinkregister werden 0en nachgeschoben clc rol Breg clc rjmp bar_Check ; weitere Stellen prüfen bar_zero: ; (zum leichteren Verständis) bar_end:rjmp sample_adc ; Zurück timer0_overflow: cli ; Interrupts deaktivieren cpi Clock, 2 ; Hier wird ein PWM-Erzeugt brlo TO_On clr temp1 cpi Clock, 15 brlo TO_End clr Clock rjmp TO_End TO_On: mov temp1, Breg TO_End: or temp1, LReg ; mit LeuchtRegister überlagert out LPort, temp1 ; und Ausgegeben ldi temp1, 1 ; CodeBit für Warten beenden inc Clock ; Clock incrementieren reti ; Wer mehrere Interrupts verwendet, muss mit dem Lokalen Interruptflags arbeiten.