Fertig Code Teil 3
Hi
Nun ja, dies Initialisierung ist nicht in allen Teilen zwingend. Auch die Routinen, die nun aufgezeigt sind, müssen so nicht in eure Programme und es ist auch möglich, das der ein oder andere Fehlerteufel noch vorhanden ist. Lediglich die Kommunikation mit dem PC und die Timer 1 und 2 Routinen sind getestet und laufen...
Hi
Nun ja, dies Initialisierung ist nicht in allen Teilen zwingend. Auch die Routinen, die nun aufgezeigt sind, müssen so nicht in eure Programme und es ist auch möglich, das der ein oder andere Fehlerteufel noch vorhanden ist. Lediglich die Kommunikation mit dem PC und die Timer 1 und 2 Routinen sind getestet und laufen...
Code:
; *****************************************************************************
; * Programmblöcke vom Hauptprogramm *
; *****************************************************************************
;********************************************************************
;* Berechnen der Laufzeit. *
;* Für 100 Taktzyklen wird 1 zum Wert in Zykl1 addiert, Bei 100 *
;* in Zykl_1 zählt Zykl_1 +1 und Zykl_1 beginnt von 0 *
;* Eine Min- Max Berechnung kann hier erweitert werden *
;********************************************************************
Laufzeit:
LDS S_Merker, Zykl_1 ; Laufzeitzähler setzen
STS Zykl_Zeit_1, S_Merker
LDS S_Merker, Zykl_2
STS Zykl_Zeit_2, S_Merker ; Zykl_Zeit_1 u.2 in OpenEye auslesen
STS Zykl_1, S_Merker
STS Zykl_2, S_Merker
RET
;---------------------------- Eingänge lesen -----------------------------------------
Read_IO:
RET
;****************************************************
;* Kanalselektion *
;****************************************************
Read_IO_M:
LDI ZH,High(Neu_Input_A)
LDI ZL,Low(Neu_Input_A)
LDI Cnt_Reg, 0b11111011 ; 1. Kanal beschalten
RCall Read_IO_Kanal
LDI ZH,High(Neu_Input_B)
LDI ZL,Low(Neu_Input_B)
LDI Cnt_Reg, 0b11110111 ; 2. Kanal beschalten
RCall Read_IO_Kanal
LDI ZH,High(Neu_Input_C)
LDI ZL,Low(Neu_Input_C)
LDI Cnt_Reg, 0b11101111 ; 3. Kanal beschalten
RCall Read_IO_Kanal
LDI ZH,High(Neu_Input_D)
LDI ZL,Low(Neu_Input_D)
LDI Cnt_Reg, 0b11011111 ; 4. Kanal beschalten
RCall Read_IO_Kanal
RET
;***************************************************************
;* Kanal Eingänge einlesen und in Variable ablegen *
;***************************************************************
Read_IO_Kanal:
In S_Merker, PortC ; zuerst Port C lesen
ORI S_Merker, 0b00111100 ; alle Ausgabebits auf 1 setzen
AND S_Merker, Tab_Cnt ; nur Kanal-Bit auf 0 ziehen
OUT PortC, S_Merker ; Taster des selektierten Kanals aktiv
In S_Merker, PortC ; Port C in Register S_Merker schreiben
;Nun blenden wir unerwünschte Bits aus
ANDI S_Merker, 0b00000011 ; Nur Bit 0-1 sind für uns interessant.
In T_Merker, PortD ; Port D in Register T_Merker schreiben
;Nun blenden wir unerwünschte Bits aus
ANDI S_Merker, 0b11111100 ; Nur Bit 0-1 sind für uns interessant.
OR S_Merker, T_Merker ; führen die Eingänge zusammen
ST Z, S_Merker ; und legen neuen Wert in Variable ab
RET
; ******************************************************************
; * Kanalweise prüfen der Eingänge inclusive der Flankenauswertung *
; * ****************************************************************
Chk_IO_Change_M:
LDI ZH,High(Neu_Input_A) ; Variablenadressen Kanal A
LDI ZL,Low(Neu_Input_A)
LDI XH,High(IO_Change_Bit_A)
LDI XL,Low(IO_Change_Bit_A)
RCall Chk_IO_Chg_Kanal ; Auswertung
LDI ZH,High(Neu_Input_B) ; Variablenadressen Kanal A
LDI ZL,Low(Neu_Input_B)
LDI XH,High(IO_Change_Bit_B)
LDI XL,Low(IO_Change_Bit_B)
RCall Chk_IO_Chg_Kanal ; Auswertung
LDI ZH,High(Neu_Input_C) ; Variablenadressen Kanal C
LDI ZL,Low(Neu_Input_C)
LDI XH,High(IO_Change_Bit_C)
LDI XL,Low(IO_Change_Bit_C)
RCall Chk_IO_Chg_Kanal ; Auswertung
LDI ZH,High(Neu_Input_D) ; Variablenadressen Kanal D
LDI ZL,Low(Neu_Input_D)
LDI XH,High(IO_Change_Bit_D)
LDI XL,Low(IO_Change_Bit_D)
RCall Chk_IO_Chg_Kanal ; Auswertung
RET
; ********************************************************************
; * Es wird geprüft, ob eine Änderung eines Einganges aufgetreten ist und *
; * das Ergebnis in Die Variable IO_Change_Bit eingetragen. Im Programm *
; * wird dieses Bit nach der Bearbeitung gelöscht *
; * ******************************************************************
Chk_IO_Chg_Kanal:
LD S_Merker, Z+ ; Reg. S_Merker mit neuem Wert laden
LD T_Merker, Z ; das letzte gelesene Byte holen
EOR T_Merker, S_Merker ; S_Merker ist nicht verändert,
BREQ End_Chk_Chg_Kanal ; Reg. T_Merker ist 0 , keine Änderung
ST X, T_Merker ; Bits ablegen, die sich geändert haben
RCall Chk_To_Low ; Aufruf der Prüfung Wechsel von 1 nach 0
RCall Chk_to_High ; Aufruf der Prüfung Wechsel von 0 nach 1
ST Z, S_Merker ; Unterprogramme dürfen Register nicht verändern
End_Chk_Chg_Kanal:
RET
;---------------------------- seriellen Empfang prüfen ----------------------------
Chk_RS232_Empf: ; Lese serielles Interface
LDS S_Merker, Write_Pos
LDS T_Merker, Read_Pos
CP T_Merker, S_Merker
BREQ End_Chk_Empf
LDI ZH,High(Ring_Buf)
LDI ZL,Low(Ring_Buf) ; Adresszeiger auf Ringbuffer
INC T_Merker ; Lesezeiger erhöhen
CPI T_Merker, 20 ; Lesezeiger Grenze ?
BRLO Read_Val ; unter Grenze, dann Empfang abholen
CLR T_Merker ; Temp auf 0 setzen
Read_Val:
STS Read_Pos, T_Merker
ADD ZL, T_Merker ; Adresse kann größer als 1 Byte werden
ADC ZH, Zero ; daher Addition mit Übertrag
LD Work_Reg, Z ; Empfang abholen
STS Erste_Variable, Work_Reg
RCall Chk_RS232_Bef
End_Chk_Empf:
CLR Work_Reg
RET
;-------------------- Eingänge auf Änderung testen -----------------------------
; ***********************************************************************
; * -------------------- Eingänge auf Änderung testen ----------------- *
; * Es wird geprüft, ob eine Änderung eines Einganges aufgetreten ist *
; * und das Ergebnis in Die Variable IO_Change_Bit eingetragen *
; * Im Programm wird dieses Bit nach der Bearbeitung gelöscht. *
; ***********************************************************************
Chk_IO_Change:
LDS S_Merker, Neu_Input_A ; Reg. S_Merker mit neuem Wert laden
LDS T_Merker, old_Input_A ; das letzte gelesene Byte holen
EOR T_Merker, S_Merker ; S_Merker ist nicht verändert,
BREQ End_Chk_Change ; Reg. T_Merker ist 0 , keine Änderung
STS IO_Change_Bit_A, T_Merker ; Bits ablegen, die sich geändert haben
RCall Chk_To_Low ; Aufruf der Prüfung Wechsel von 1 nach 0
RCall Chk_to_High ; Aufruf der Prüfung Wechsel von 0 nach 1
STS Old_Input_A, S_Merker ; Unterprogramme dürfen S_Merker nicht verändern
End_Chk_Change:
RET
;-------------------- Ereignisbehandlung Eingänge -----------------------------
Chk_Signal_Flag:
RET
;********************************************************************
;* Auswerten der Zeitereignisse *
;* das ist keine ISR, daher auch kein Push und POP *
;* Soll ein Timer sofort erfasst werden, zum Bsp. Stoppuhr,dann *
;* ist die Routine direkt in der Timer-ISR aufzurufen *
;* Dies hier ist nur ein Beispiel, wie mit Controlbits gearbeitet *
;* werden kann. Die Verzögerung bewegt sich in wenigen ms *
;********************************************************************
Chk_Timer_Flag:
LDS Event_Reg, Timer_Flag
TST Event_Reg
BREQ End_TimeFlg
Mov Ablage, Event_Reg
LDI Temp, 0b00000001
AND Ablage, Temp
TST Ablage
BREQ Chk_TimeFlg_ms10
;Aufruf Routine für ms-Auftrag, dieser Aufruf besser direkt in Timer-ISR
LDI Temp, 0b11111110 ; Timerflag löschen
And Event_Reg, Temp
Chk_TimeFlg_ms10:
Mov Ablage, Event_Reg
LDI Temp, 0b00000010
AND Ablage, Temp
TST Ablage
BREQ Chk_TimeFlg_ms100
;Aufruf Routine für 10ms-Auftrag
LDI Temp, 0b11111101 ; Timerflag löschen
And Event_Reg,Temp
Chk_TimeFlg_ms100:
Mov Ablage, Event_Reg
LDI Temp, 0b00000100
AND Ablage, Temp
TST Ablage
BREQ Chk_TimeFlg_sek
; -------------- ;Aufruf Routine für 100ms-Auftrag
LDI Temp, 0b11111011 ; Timerflag löschen
And Event_Reg, Temp
Chk_TimeFlg_sek:
Mov Ablage, Event_Reg
LDI Temp, 0b00001000
AND Ablage, Temp
TST Ablage
BREQ Chk_TimeFlg_min
; -------------- ;Aufruf Routine für Sekunden-Auftrag
;RCall Toggle_PrtD5 ; Aufruf für Testzwecke freigeben, kommt nicht aus ISR
LDI Temp, 0b11110111 ; Timerflag löschen
AND Event_Reg, Temp
Chk_TimeFlg_min:
Mov Ablage, Event_Reg
LDI Temp, 0b00010000
AND Ablage, Temp
TST Ablage
BREQ Chk_TimeFlg_std
; -------------- ;Aufruf Routine für min-Auftrag
LDI Temp, 0b11101111 ; Timerflag löschen
AND Event_Reg, Temp
Chk_TimeFlg_std:
Mov Ablage, Event_Reg
LDI Temp, 0b00100000
AND Ablage, Temp
TST Ablage
BREQ Chk_TimeFlg_tag
; -------------- ;Aufruf Routine für Stds-Auftrag
LDI Temp, 0b11011111 ; Timerflag löschen
AND Event_Reg, Temp
Chk_TimeFlg_Tag:
Mov Ablage, Event_Reg
LDI Temp, 0b01000001
AND Ablage, Temp
TST Ablage
BREQ Chk_TimeFlg_wo
; -------------- ;Aufruf Routine für Tag-Auftrag
LDI Temp, 0b10111111 ; Timerflag löschen
AND Event_Reg, Temp
Chk_TimeFlg_wo:
Mov Ablage, Event_Reg
LDI Temp, 0b10000000
AND Ablage, Temp
TST Ablage
BREQ End_TimeFlg
; -------------- ;Aufruf Routine für Woches-Auftrag
LDI Temp, 0b01111111 ; Timerflag löschen
AND Event_Reg, Temp
End_TimeFlg:
STS Timer_Flag, Event_Reg ; und Timerflags zurückschreiben
RET
;********************************************************************
;* Auswerten Zeitereigniss Sekunde *
;* das ist keine ISR, daher auch kein Push und POP *
;********************************************************************
Toggle_PrtD5:
LDS S_Merker, Ausgabebyte
LDI Temp,0b00100000
EOR S_Merker, Temp
STS Ausgabebyte, S_Merker
RET
;--------------------------------- Ausgabe an RS 232 -----------------------------
Write_UART:
RET
; **********************************************************************************
; * ----------------------------- Ausgabe an IO-Ports -----------------------------*
; * Beachte, nur Bit 5 und 6 sollen verändert wertden. *
; * Alle anderen Bits bleiben unverändert *
; **********************************************************************************
Write_IO:
In S_Merker, PortD ; Wert in Register Port D lesen
LDS T_Merker, Ausgabebyte ; Bearbeitetes Ausgabebyte holen
ANDI S_Merker, 0b10011111 ; Nur Bits ändern, die Ausgegeben werden
OR T_Merker, S_Merker ; Mit eier Oder - Funktion Ausgabebits setzen
Out PortD, T_Merker ; und in das Ausgaberegister Port D schreiben
RET