;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 = R12 ;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 ad_1 = R30 .def ad_2 = R31 .def wert = R27 ;Tasterauswertung .def lcd_wert = R28 .def temp3 = R29 .equ taster = 4 ;Wo ist der Taster angeschlossen ? .equ Pin_Int0 = 2 ;An welchen Pins sind die Interrupts .equ Pin_Int1 = 3 rjmp reset rjmp EXT_INT0 ; Interrupt 1 rjmp EXT_INT1 ; Interrupt 2 reset: clr register clr multi_1 clr multi_2 clr multi_3 clr erg_1 clr erg_2 clr erg_3 clr temp1 clr temp2 clr minl clr minm clr minr clr maxl clr maxm clr maxr clr solll clr sollm clr sollr clr istl clr istm clr istr clr ad_1 clr ad_2 ;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 ad_init: ldi ad_1, 0x40 ;0b01000000 out ADMUX, ad_1 ;Bit6=AVCC an AREF pin,Bit4..0=setzte ADC0 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 ad_1, 0x85 ;0b10000101 out ADCSR, ad_1 ;ADEN,ADPS2 und ADPS0 gesetzt main: 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 rcall d_taster ; Auswertung Taster rjmp main ;WERTEVERGLEICH ;INTERRUPTS ;WERTEEINSTELLUNG .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" ;INT0 AUSWERTUNG ;_____________________________________________________________________________________________ EXT_INT0: ;Sicherung des Statusregisters damit nach dem Interrupt alles wieder so ist wie voher push register ; Sicherung des registers in register, SREG ; Statusregister holen push register ; dieses sichern in register, MCUCR ; MCUCR holen ;Auswertung des INT0 (siehe PAP) sbic PIND, Pin_INT0 ; INT0=1? rjmp INT0_1 ; ja, spring sbrc register, 0 ; Bit 0 = 0 ? INT0 = steigende Flanke ? rjmp INT0_3 ; ja, springe ori register, 0b00000011 ; bei nein auf steigende Flanke schalten out MCUCR, register sbrs status, 0 ; Zustand = 0 ? rjmp DECREMENT ; ja, springe zu DECREMENT rjmp I0_Zustand0_SREG ; sonst springe INT0_1: sbrc register, 0 ; Bit 0 = 0 ? INT0 = steigende flanke ? rjmp INT0_2 ; ja, springe sbrs status, 0 ; Zustand = 0 ? rjmp I0_Zustand1_DECR ; ja, springe rjmp I0_SREG_holen ; sonst SREG holen INT0_2: cbr register, 0b00000010 ; auf fallende Flanke schalten out MCUCR, register sbrs status, 0 ; Zustand =0 ? rjmp I0_Zustand1_SREG ; ja, springe rjmp DECREMENT ; sonst springe zu DECREMENT INT0_3: sbrs status, 0 ; Zustand = 0 ? rjmp I0_SREG_holen ; ja, springe rjmp I0_Zustand0_DECR ; sonst springe I0_Zustand1_SREG: ldi register, 0b00000001 mov status, register ; Zustand auf 1 gesetzt rjmp I0_SREG_holen ; springe zu SREG holen I0_Zustand1_DECR: ldi register, 0b00000001 mov status, register ; Zustand auf 1 gesetzt rjmp DECREMENT ; Springe zu DECREMENT I0_Zustand0_SREG: ldi register, 0b00000000 mov status, register ; Zustand auf 0 gesetzt rjmp I0_SREG_holen ; springe zu SREG holen I0_Zustand0_DECR: ldi register, 0b00000000 mov status, register ; Zustand auf 0 gesetzt rjmp DECREMENT ; springe zu DECREMENT I0_SREG_holen: pop register ; SREG zurückholen out SREG, register pop register ; register zurückholen reti ; FERTIG DECREMENT: ;LINKSDREHUNG ;cpi lcd_wert, '0' ; Ist Wert bereits auf 0 ? ;breq dec_1 ; ja, springe dec lcd_wert ; sonst ziehe 1 ab dec_1: pop register out SREG, register ; SREG wiedeherstellen pop register reti ;INTO AUSWERTUNG FERTIG ;__________________________________________________________________________________ ;INT1 AUSWERTUNG ;__________________________________________________________________________________ EXT_INT1: ;Sicherung des Statusregisters damit nach dem Interrupt alles wieder so ist wie voher push register ; Sicherung des registers in register, SREG ; Statusregister holen push register ; dieses sichern in register, MCUCR ; MCUCR holen ;Auswertung des INT1 (siehe PAP) sbic PIND, Pin_INT1 ; INT1=1? rjmp INT1_1 ; ja, spring sbrc register, 2 ; Bit 2 = 0 ? INT1 = steigende Flanke ? rjmp INT1_3 ; ja, springe ori register, 0b00001100 ; bei nein auf steigende Flanke schalten out MCUCR, register sbrs status, 0 ; Zustand = 0 ? rjmp INCREMENT ; ja, springe zu INCREMENT rjmp I1_Zustand0_SREG ; sonst springe INT1_1: sbrc register, 2 ; Bit 2 = 0 ? INT1 = steigende flanke ? rjmp INT1_2 ; ja, springe sbrs status, 0 ; Zustand = 0 ? rjmp I1_Zustand1_INCR ; ja, springe rjmp I1_SREG_holen ; sonst SREG holen INT1_2: cbr register, 0b00001000 ; auf fallende Flanke schalten out MCUCR, register sbrs status, 0 ; Zustand =0 ? rjmp I1_Zustand1_SREG ; ja, springe rjmp INCREMENT ; sonst springe zu INCREMENT INT1_3: sbrs status, 0 ; Zustand = 0 ? rjmp I1_SREG_holen ; ja, springe rjmp I1_Zustand0_INCR ; sonst springe I1_Zustand1_SREG: ldi register, '1' mov status, register ; Zustand auf 1 gesetzt rjmp I1_SREG_holen ; springe zu SREG holen I1_Zustand1_INCR: ldi register, 1 mov status, register ; Zustand auf 1 gesetzt rjmp INCREMENT ; Springe zu INCREMENT I1_Zustand0_SREG: ldi register, 0 mov status, register ; Zustand auf 0 gesetzt rjmp I1_SREG_holen ; springe zu SREG holen I1_Zustand0_INCR: ldi register, 0 mov status, register ; Zustand auf 0 gesetzt rjmp INCREMENT ; springe zu INCREMENT I1_SREG_holen: pop register ; SREG zurückholen out SREG, register pop register ; register zurückholen reti ; FERTIG INCREMENT: ;RECHTSDREHUNG ;cpi lcd_wert, 9 ; Ist Wert bereits auf 9 ? ;breq inc_1 ; ja, springe inc lcd_wert ; sonst addiere 1 dazu inc_1: pop register out SREG, register ; SREG wiedeherstellen pop register reti ;INT1 AUSWERTUNG FERTIG ;__________________________________________________________________________ ;START Ausgangszustand bestimmen (In Welcher Rastposition befindet sich der Drehgeber?) ;-------------------------------------------------------------------------------------- start_i: sbic PIND, Pin_INT0 ; Ist Int0 = 1 ? rjmp interrupt0 ; Bei ja, springe ldi register, 0b00000011 ; sonst ist 0 und reagiere auf steigende Flanke ldi temp1, 0b00000000 mov status, temp1 ; Zustand auf 0 gesetzt ;TEST ldi temp1, 0b10000000 rcall lcd_command ldi temp1, '0' rcall lcd_data ;TEST sbic PIND, Pin_INT1 ; Ist Int1 = 1 ? rjmp interrupt1 ; bei ja, springe ori register, 0b00001100 ; sonst ist 0 und reagiere auf steigende Flanke ;TEST ldi temp1, 0b11000000 rcall lcd_command ldi temp1, '0' rcall lcd_data ;TEST rjmp write_MCUCR interrupt0: ;TEST ldi temp1, 0b10000000 rcall lcd_command ldi temp1, '1' rcall lcd_data ;TEST ldi register, 0b00000010 ; INT0 ist 1 also reagiere auf fallende Flanke ldi temp1, 0b00000001 mov status, temp1 ; Zustand auf 1 gesetzt sbic PIND, Pin_INT1 ; INT1 auch auf 1 ? rjmp interrupt1_1 ; bei ja, springe ;TEST ldi temp1, 0b11000000 rcall lcd_command ldi temp1, '0' rcall lcd_data ;TEST ori register, 0b00001100 ; sonst reagiere auf steigende Flanke rjmp write_MCUCR interrupt1: ;TEST ldi temp1, 0b11000000 rcall lcd_command ldi temp1, '1' rcall lcd_data ;TEST ori register, 0b00001000 ; sonst reagiere auf fallende Flanke rjmp write_MCUCR interrupt1_1: ;TEST ldi temp1, 0b11000000 rcall lcd_command ldi temp1, '1' rcall lcd_data ;TEST ori register, 0b00001000 ; reagiere auf fallende Flanke rjmp write_MCUCR write_MCUCR: out MCUCR, register ; Schreibe ins Control Register ret ;------------------------------------------------------------------------------------- ;ENDE Ausgangszustand bestimmen