Code:
;**********************************Header**************************************
;* Projektname: Roboter-Linienverfolgung *
;* Name des Erstellers: *
;* Zuletzt aktualisiert: 7.4.2010 *
;* Beschreibung: Ein ROboter, der einer ca1,5-2cm breiten Linie nachfaährt *
;******************************************************************************
;*****************************Initialisierungen********************************
.include "m8def.inc" ;Definitionsdatei des Mega8
;Stackpointer-init***********
ldi r16, High(Ramend)
out SPH, r16
ldi r16, Low(Ramend)
out SPL, r16
;ADC-init***********
sbi ADCSRA, ADEN ;ADC erlauben
cbi ADCSRA, ADPS0
sbi ADCSRA, ADPS1
sbi ADCSRA, ADPS2 ;PRESCALER 64
;*************************Variablendeklarationen*******************************
.def Messergebnisleft = r16
.def Messergebnisright = r17
.def Messergebnismiddle = r18
.def Schwellwertleft = r19
.def Schwellwertmiddle = r20
.def Schwellwertright = r21
.def Linksaus = r22
.def Mitteaus = r23
.def Rechtsaus = r24
.def Linienerkennung = r29
;*****************************Ein-Ausgänge*************************************
sbi DDRB, 1 ;PORTB.1 als Ausgabeport
sbi DDRB, 2 ;PORTB.2 als Ausgabeport
cbi DDRD, 2 ;PORTD.2 als Eingabeport
sbi PORTD, 2 ;Pullups aktivieren
;*****************************Hauptprogramm************************************
Hauptprogramm:
clr Linienerkennung ;Virbereitung auf neue Messung
;TEIL1...................START.......................Messe aktuelle Werte der Linie aus
rcall StartADConChanel0_8bit
in Messergebnisleft, ADCH
rcall StartADConChanel1_8bit
in Messergebnismiddle, ADCH
rcall StartADConChanel2_8bit
in Messergebnisright, ADCH
;TEIL2...................START.......................Erstelle aktuelle Werte für Linienerkennung
cp Messergebnisleft, Schwellwertleft ;Vergleiche LDR links aktuell mit vorher ausgerechnetem
;Schwellwert
brlo FahreFort0
ldi Linienerkennung, 0b00000100 ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
FahreFort0:
cp Messergebnismiddle, Schwellwertmiddle ;Vergleiche LDR mitte aktuell mit vorher ausgerechnetem
;Schwellwert
brlo FahreFort1
ldi Linienerkennung, 0b00000010 ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
FahreFort1: ;wenn kleiner dann lass es auf Null
cp Messergebnisright, Schwellwertright ;Vergleiche LDR rechts aktuell mit vorher ausgerechnetem
;Schwellwert
brlo FahreFort2
ldi Linienerkennung, 0b00000001 ;Wenn nicht kleiner, sprich wenn größer dann setze Bit auf 1
FahreFort2: ;wenn kleiner dann lass es auf Null
;TEIL3...................START.......................Auswertung-->Motorsteuerung
sbrc Linienerkennung, 2
ldi r28, 0b00000010 ;Motor = Rechts
out PORTB, r28
sbrc Linienerkennung, 1
ldi r28, 0b00000110 ;Motor = Beide
out PORTB, r28
sbrc Linienerkennung, 0
ldi r28, 0b00000100 ;Motor = Links
out PORTB, r28
;TEIL4...................START.......................Falls neie Messung vorgesehen dann mache sie zuerst
sbis PIND, 2 ;Überprüfe PIND.0
rcall Messeschwellwert ;Wenn PIND.0 = 0 (Taster betätigt)--> Messung
rjmp Hauptprogramm ;ansosnten wieder von vorne
;*********************************************************************************
;***********************Unterprogramme/Funktionen******************************
Messeschwellwert:
rcall StartADConChanel0_8bit ;Messe linken LDR bei weißem Untergrund
in r25, ADCH
rcall StartADConChanel1_8bit ;Messe mittleren LDR bei weißem Untergrund
in r26, ADCH
rcall StartADConChanel2_8bit ;Messe rechten LDR bei weißem Untergrund
in r27, ADCH
cbi PORTB, 1
cbi PORTB, 2
rcall Wait1
sbi PORTB, 1
rcall Wait3
cbi PORTB, 1
;Linker Schwellwert--------------
push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
clr r28 ;lösche registerinhalt in r28 zur neuen Anwendung
rcall StartADConChanel0_8bit
in Messergebnisleft, ADCH ;Messe LDRleft bei schwarzem Untergrund
add r25, Messergebnisleft ;Addiere Weißen Wert mit Schwarzen Wert
BRCC RechneWeiter0;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür
;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
;ergibt den richtigen Schwellwert
ldi r28, 128 ;wenn Carry 1 dann lade 128 in carry-register
RechneWeiter0: ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
mov r16, r25 ;Den Dividenten ins Register der Division kopieren
;Diese Register ist als Messergebnisleft definiert
;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
ldi r17, 2 ;Den Divisor ins Register der Division laden
;Dieses Register ist Messergebnismiddle, dass tört aber keinen
;da hier nicht verwendet
rcall Division
;Ergebnis steht jetzt in Register Ergebnis (r30)
add r28, Ergebnis ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
;bei verschiedenen Linienfarben unterschiedlich, kann es sein
;dass es kleinere Spannungen auch geben kann, daher muss
;ein möglicher Überlauf berücksichtigt werden
;Endergebnis steht jetzt in r28
mov Schwellwertleft, r28 ;Kopiere den Schwellwert in definiertes Register
;für diesen Wert
rcall Wait1
pop r28
;--------------------------------
sbi PORTB, 1
sbi PORTB, 2
rcall Wait3
cbi PORTB, 1
cbi PORTB, 2
;Mittlerer Schwellwert-----------
push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
clr r28 ;lösche registerinhalt in r28 zur neuen Anwendung
rcall StartADConChanel1_8bit
in Messergebnismiddle, ADCH ;Messe LDRleft bei schwarzem Untergrund
add r26, Messergebnismiddle ;Addiere Weißen Wert mit Schwarzen Wert
BRCC RechneWeiter1;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür
;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
;ergibt den richtigen Schwellwert
ldi r28, 128 ;wenn Carry 1 dann lade 128 in carry-register
RechneWeiter1: ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
mov r16, r26 ;Den Dividenten ins Register der Division kopieren
;Diese Register ist als Messergebnisleft definiert
;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
ldi r17, 2 ;Den Divisor ins Register der Division laden
;Dieses Register ist Messergebnismiddle, dass tört aber keinen
;da hier nicht verwendet
rcall Division
;Ergebnis steht jetzt in Register Ergebnis (r30)
add r28, Ergebnis ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
;bei verschiedenen Linienfarben unterschiedlich, kann es sein
;dass es kleinere Spannungen auch geben kann, daher muss
;ein möglicher Überlauf berücksichtigt werden
;Endergebnis steht jetzt in r28
mov Schwellwertmiddle, r28 ;Kopiere den Schwellwert in definiertes Register
;für diesen Wert
rcall Wait1
pop r28
;--------------------------------
sbi PORTB, 2
rcall Wait3
cbi PORTB, 2
;Rechter Schwellwert-------------
push r28 ;In diesem Register wird das Carry einer Addition geprüft, deswegen ist sicherung nötig
clr r28 ;lösche registerinhalt in r28 zur neuen Anwendung
rcall StartADConChanel2_8bit
in Messergebnisright, ADCH ;Messe LDRleft bei schwarzem Untergrund
add r27, Messergebnisright ;Addiere Weißen Wert mit Schwarzen Wert
BRCC RechneWeiter2;Teste Carry Flag wegen Addition, wenn 1 dann war ein Überlauf und lade
;128 in ein Register weil nachher der Mittelwert gebildet wird und dafür
;eine 9 Bit Zahl notwendig ist, dh: r27/2 + (Register mit Carry = 255/2)
;ergibt den richtigen Schwellwert
ldi r28, 128 ;wenn Carry 1 dann lade 128 in carry-register
RechneWeiter2: ;wenn Carry 0 dann lasse carry-Register auf 0 (wenn Schwellwerte niedrig)
mov r16, r27 ;Den Dividenten ins Register der Division kopieren
;Diese Register ist als Messergebnisleft definiert
;jedoch hats keine auswirkung, denn dies wird hier nicht verwendet
ldi r17, 2 ;Den Divisor ins Register der Division laden
;Dieses Register ist Messergebnismiddle, dass tört aber keinen
;da hier nicht verwendet
rcall Division
;Ergebnis steht jetzt in Register Ergebnis (r30)
add r28, Ergebnis ;Korrektur falls Carry 1 war, dies dinet dazu, falls der Schwellwert
;bei verschiedenen Linienfarben unterschiedlich, kann es sein
;dass es kleinere Spannungen auch geben kann, daher muss
;ein möglicher Überlauf berücksichtigt werden
;Endergebnis steht jetzt in r28
mov Schwellwertright, r28 ;Kopiere den Schwellwert in definiertes Register
;für diesen Wert
rcall Wait1
pop r28
;--------------------------------
ret
;*************************************
;*************************************
;################################################################################
.include "Division8Bit+Rest.asm" ;8 Bit division //call division
.include "wait1.asm"
.include "wait3.asm"
.include "ReadEEPROM.asm" ; //call Read_EEPROM
.include "WriteEEPROM.asm" ; //call Write_EEPROM
.include "StartADConCHANEL0_8bit.asm"
.include "StartADConCHANEL1_8bit.asm"
.include "StartADConCHANEL2_8bit.asm"
;################################################################################
In Aufrufe.txt sind die Unterprogramme die ich geschrieben habe
Lesezeichen