;wasserstandsregelung.asm .include "m16def.inc" ;Registerdefinitionen .def register = R16 ;Vielzweckregister .def multi_1 = R3 ;Multiplikator AD-Wandler .def multi_2 = R4 .def multi_3 = R5 .def erg_1 = R6 ;Ergebnis AD-Wandler .def erg_2 = R7 .def erg_3 = R8 .def istl = R9 .def istm = R10 .def istr = R11 .def Status = R30 .def ad_1 = R13 .def ad_2 = R14 ;Interruptroutine .def temp1 = R16 ;Temporäre für lcd-routine .def temp2 = R17 .def minl = R18 .def minm = R19 .def minr = R20 .def maxl = R21 .def maxm = R22 .def maxr = R23 .def solll = R24 .def sollm = R25 .def sollr = R26 .def wert = R27 ;Tasterauswertung .def lcd_wert = R28 .def temp3 = R29 .equ taster = 4 ;Wo ist der Taster angeschlossen ? rjmp reset rjmp Ext_Int0 ; Interrupt 1 rjmp Ext_Int1 ; Interrupt 2 reset: ;TEST ldi solll, '1' ldi sollm, '0' ldi sollr, '0' ldi minl, '0' ldi minm, '9' ldi minr, '0' ldi maxl, '1' ldi maxm, '1' ldi maxr, '0' ;TEST ldi register, HIGH (RAMEND) ;Stackpointer einrichten out SPH, register ldi register, LOW (RAMEND) out SPL, register ldi temp1, 0xFF ; Port C = Ausgang (LCD) out DDRC, temp1 ldi temp1, 0b00000000 ; Port D = Eingang (Drehimpulsgeber) out DDRD, temp1 ldi register, 0b11000000 ;Init Int0 & Int1 out GICR, register rcall lcd_init ; Display initialisieren rcall lcd_clear ; Display löschen rcall sende_lcd ; LCD Menü ;ldi temp1, 0b11001011 ; Cursor zur Position Solll ;rcall lcd_command ;Bit : 7 6 5 4 3 2 1 0 ;ADMUX: REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 ldi temp1, 0x40 mov ad_1, temp1 ;ldi ad_1, 0x40 ;0b01000000 out ADMUX, ad_1 ;Bit6=AVCC an AREF pin,Bit4..0=setzte ADC0 ldi temp1, 0 mov ad_1, temp1 ;ldi ad_1, 0 out SFIOR, ad_1 ;setze frei laufenden Modus; der ausgewählte Kanal wird ständig ;gemessen und der gemessene Wert in die ADCL und ADCH geschrieben ;aktiviwren des ADC ;ADEN = 1 (bit7) ;Enable ADC, aktiviert ADC ;ADSC = 0 (bit6) ;Start Conversion, Messvorgang gestartet ;ADATE = 0 (bit5) ;ADC Auto Trigger Enable, ;ADIF = 0 (bit4) ;ADC interrupt flag, ADIE und I-Bit gesetzt= ADC Interrupt ausgelöst ;ADIE = 0 (bit3) ;ADC interrupt enable, ktiviert ADC Interrupt ;ADPS0-2 = 101 ;Presclare = 1/32, bits bestimmen Teilungsfaktor zwischen ;der Taktfrequenzund dem Eingangstakt des ADC ;Bit 7 6 5 4 3 2 1 0 ;ADCSR ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0 ldi temp1, 0x85 mov ad_1, temp1 ;ldi ad_1, 0x85 ;0b10000101 out ADCSR, ad_1 ;ADEN,ADPS2 und ADPS0 gesetzt main: d_taster: ldi wert, 0 ; Wert auf 0 setzten sbis PIND, taster ; Ist Taster gedrückt ? rjmp wert_inc_0 ; ja, springe rjmp main2 ; sonst raus... wert_inc_0: sei ; Interrupt enable rjmp wert_inc wert_inc: rcall delay100ms ; Entprellen inc wert ; Erhöhe Wert um eins cpi wert, 3 ; Ist Wert > 9 ? brsh cursor_aus ; ja, springe (gleich opder größer) cpi wert, 1 ; Wert = 1 ? breq wert1 ; ja, springe cpi wert, 2 ; Wert = 2 ? breq wert2 ; ja, springe wert1: rjmp wert1_0 wert2: rjmp wert2_0 cursor_aus: ;ldi temp1, 0b00001110 ; sonst Cursor ausschalten ;rcall lcd_command ldi temp1, 0b11001011 ; Cursor wieder zur Position Solll rcall lcd_command rjmp main ; raus...löschen und von vorne wert1_0: ldi temp1, 0b11001011 ; Cursor zur Position Solll rcall lcd_command ldi temp1, 0b00001101 ; Cursor an, blinken rcall lcd_command mov lcd_wert, solll ; Aktuellen Wert holen ;mov temp1, lcd_wert ; Aktuellen Wert ausgeben ;rcall lcd_data ldi temp1, 0b11001011 ; Cursor zurück Position Solll rcall lcd_command wert1_1: sbis PIND, taster ; Ist Taster gedrückt ? Warten auf Interrupt rjmp wert_inc ; ja, springe mov solll, lcd_wert ; neuen Wert übergeben rjmp wert1_1 ; und nochmal wert2_0: ldi temp1, 0b11001100 ; Cursor zur Position Sollm rcall lcd_command ;mov lcd_wert, sollm ; Aktuellen Wert holen ;mov temp1, sollm ; Aktuellen Wert ausgeben ;rcall lcd_data ldi temp1, 0b11001100 ; Cursor zurück Position Sollm rcall lcd_command ;mov sollm, lcd_wert ; neuen Wert holen wert2_1: sbis PIND, taster ; Ist Taster gedrückt ? rjmp wert_inc ; ja, springe rjmp wert2_1 ; sonst nochmal main2: ;rcall d_taster ; Tasterroutine ;rcall start_i ; Startzustand auslesen rcall AD_auslesen ; A/D-Wandler Auslesen rcall multiplikation ; Multipliziere AD-Wert rcall ascii ; Wandle das Wort in ASCII Zeichen rcall regelgroessen ; Sende SOLL, IST, MIN, MAX zum LCD rcall regelung ; Vergleich von SOLL, IST, MIN & MAX rjmp main .include "ad_wandler.inc" .include "lcd-routines.asm" .include "lcd_menue.inc" .include "multi_ascii.inc" .include "regel_g.inc" ;.include "tasterauswertung.inc" .include "wertevergleich.inc" Ext_Int0: push Temp1 ; save Temp1 in Temp1,SREG ; save flag register push Temp1 in Temp1,MCUCR ; Int0 _/~ or ~\_ ? sbrc Temp1,0 ; skip next line if ~\_ jmp UpA ; was _/~ so jump to UpA ori Temp1,$01 ; MCUCR-bit0 = 1 out MCUCR,Temp1 ; Int0 next change will be _/~ sbic PinD,3 ; skip next line if channel B=0 jmp DecRot ; if B=1 and A=~\_ -> decrement jmp IncRot ; if B=0 and A=~\_ -> increment UpA: andi Temp1,$FE ; MCUCR-bit0 = 0 out MCUCR,Temp1 ; Int0 next change will be ~\_ sbic PinD,3 ; skip next line if channel B=0 jmp IncRot ; if B=1 and A=_/~ -> increment jmp DecRot ; if B=0 and A=_/~ -> decrement Ext_Int1: push Temp1 ; save Temp1 in Temp1,SREG ; save flag register push Temp1 in Temp1,MCUCR ; Int1 _/~ or ~\_ ? sbrc Temp1,2 ; skip next line when ~\_ jmp UpB ; was _/~ so jump to UpB ori Temp1,$04 ; MCUCR-bit2 = 1 out MCUCR,Temp1 ; Int1 next change will be _/~ sbic PinD,2 ; skip next line if channel A=0 jmp IncRot ; if A=1 and B=~\_ -> increment jmp DecRot ; if A=0 and B=~\_ -> decrement UpB: andi Temp1,$FB ; MCUCR-bit2 = 0 out MCUCR,Temp1 ; Int1 next change will be ~\_ sbic PinD,2 ; skip next line if channel A=0 jmp DecRot ; if A=1 and B=_/~ -> decrement jmp IncRot ; if A=0 and B=_/~ -> increment IncRot: inc lcd_wert ; no, increment jmp Exit ; DecRot: dec lcd_wert ; no, decrement Exit: pop Temp1 ; restore Flag register out SREG,Temp1 ; pop Temp1 ; restore Temp1 reti