Code:
.include "m8def.inc"
;Motorenrichtung
.equ fwd = PB5 ;vor
.equ rwd = PB4 ;zurück
;Ende Motorenrichtung
;Definiere Anfangwert vom Zähler
.equ anfang = 256 - 255
;Definiere 5 Sekunden
.equ fuenfsek = 153
;Ende Definition von 5 Sekunden
;Definiere 1 Sekunde
.equ einesek = 32
;Definiere halbe sekunde
.equ halbesek = 16
.def Lold=R1 ;Alter Wert Odometrie links
.def Rold=R2 ;Alter Wert Odometrie rechts
.def Lnow = R3 ;Neuer Wert Odometrie links
.def Rnow = R4 ;Neuer Wert Odometrie rechts
.def tmp = R16 ;Multipurose
.def tmpi = R17 ;Multipurose für Interrupts
.def zaehler = R18 ; Zählerregister
.def statusmot = R19 ;Motorenstatus
.def zaehlerodo = R20 ;Zähler Odometrie
;bit 0 -> Motor Rechts 0 vor 1 zurück
;bit 1 -> Motor links 0 vor 1 zurück
.def geschrechts = R24 ;Geschwindigkeit für Motor Rechts
.def geschlinks = R25;Geschwindigkeit für Motor Links
;Vektoren
.org 0x000
rjmp reset ;reset
.org INT1addr
rjmp kolision
.org OVF0addr ;Timer0
rjmp timer
;Ende Vektoren
reset:
;Stack einrichten
ldi tmp,HIGH(RAMEND)
out SPH,tmp
ldi tmp,LOW(RAMEND)
out SPL,tmp
;PWM einstellen
ldi tmp,(1<<WGM10) | (1<<COM1A1) | (1<<COM1B1)
out TCCR1A,tmp
ldi tmp,(1<<CS11)
out TCCR1B,tmp
;A/D Conversion
ldi tmp,(1<< ADEN) | (1<<ADPS2) | (1<<ADPS1)
out ADCSRA,tmp
ldi tmp,(1<<ADLAR) | (1<<REFS0)
out ADMUX,tmp
;Timer 0 einstellen
ldi tmp,(1<<CS02) | (1<<CS00) ;prescaler 1024
out TCCR0,tmp
ldi tmp,(1<<TOIE0) ;Interrupt bei überlauf
out TIMSK,tmp
;DDR für Tastenabfrage
cbi DDRD,PD3
;Ende DDR für Tastenabfrage
;Einstellen Low Level Interrupt für Tastenabfrage
ldi tmp,(1<<ISC11)
out MCUCR,tmp
ldi tmp,(1<<INT1)
out GICR,tmp
;Ende EXT1 Interrupt
; DDR für Motor Rechts und Statusled green
ldi tmp,(1<<PB0) |(1<<PB1) | (1<<PB2) | (1<<PB5) | (1<<PB4)
out DDRB,tmp
;DDR für Motor Links,Statusled red, LED für Linienverfolgung und LEDs
;Odometrie und Backleds
ldi tmp,(1<<PD2) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7)
out DDRD,tmp
ldi zaehler,0x00 ; lösche inhalt von zähler
rcall motorenloeschen
sei
main:
;Schalte Liniendiode ein...
rcall lineon
;Lade Wert für vorwärtsfahren
sbi PORTB,fwd ;in den rechten
sbi PORTD,fwd ;und in den linken Motor
ldi geschrechts,0x90 ;Geschwindigkeit 0x90
ldi geschlinks,0x90
rcall motorengesch ;LOS!
;Starte Timer für 5 Sekunden
loop:
cpi statusmot,0x80 ;liegt Kolision vor ?
brne odometrie ;wenn nicht dann mit odometrie weitermachen
ldi statusmot,0x00
rcall motorenloeschen ;Stop
;Beide Motoren zurück
sbi PORTB,rwd
sbi PORTD,rwd
ldi zaehler,einesek
ldi tmp,anfang
out TCNT0,tmp ;Timer0 auf eine Sekunde
warte:
tst zaehler
brne warte
rcall motorenloeschen
sbi PORTB,rwd
sbi PORTD,fwd
ldi zaehler,halbesek
ldi tmp,anfang
out TCNT0,tmp
warte_:
tst zaehler
brne warte_
rcall motorenloeschen
sbi PORTB,fwd
sbi PORTD,fwd
rjmp loop
odometrie:
cbi DDRC,PC0 ;schalte PC0 als eingang
cbi DDRC,PC1 ;schalte PC0 als eingang
sbi PORTD,PD7 ;schalte Odometrie LEDs ein
mov Lold,Lnow ;sichere alten Zustand
;lese linkes Rad in tmp
sbi ADMUX,MUX0
cli
sbi ADCSRA,ADSC
AD_BUSYL:
sbis ADCSR,ADIF
rjmp AD_BUSYL
in tmp,ADCL
in tmp,ADCH
sei
cpi tmp,0xA0 ;vergleiche Ergebnis mit 0xA0
brlo schwarzL ;wennkleiner springe nach schwarz
rjmp weissL
schwarzL:
ldi tmp,0x001
mov Lnow,tmp ;schreibe eine 1 in Lnow
rjmp vergleicheL
weissL:
ldi tmp,0x000
mov Lnow,tmp
vergleicheL:
cp Lnow,Lold ;Vergleche zustand alt und neu
breq auslesenR ;wenn gleich weiter mit rechtem Rad
inc zaehlerodo ;zaehlerodo ++
auslesenR:
mov Rold,Rnow ;sichere alten Zustand
;lese rechts in tmp
cbi ADMUX,MUX0
cli
sbi ADCSRA,ADSC
AD_BUSYR:
sbis ADCSR,ADIF
rjmp AD_BUSYR
in tmp,ADCL
in tmp,ADCH
sei
cpi tmp,0xA0 ;vergleiche Ergebnis mit 0xA0
brlo schwarzR ;wenn kleiner springe nach schwarz
rjmp weissR
schwarzR:
ldi tmp,0x001
mov Rnow,tmp ;schreibe eine 1 in Lnow
rjmp vergleicheR
weissR:
ldi tmp,0x000
mov Rnow,tmp
vergleicheR:
cp Rnow,Rold ;Vergleche zustand alt und neu
breq setzemotoren ;wenn gleich weiter mit Motorensetzen
dec zaehlerodo ;zaehlerodo --
setzemotoren:
cpi zaehlerodo,0x00
brlo linksschnell ;vergleiche mit null wenn kleiner dann spring
dec geschlinks ;rechts--
rcall motorengesch
rjmp loop
linksschnell:
inc geschlinks ;links++
rcall motorengesch
rjmp loop
.include "motoren.asm"
.include "LED.asm"
;Interrupthandling bei timer 0 überlauf
timer:
in tmpi,SREG
push tmpi
dec zaehler ;zähler --
ldi tmpi,anfang ;Starte Timer neu
out TCNT0,tmpi
pop tmpi
out SREG,tmpi
reti ;raus aus dem interrupt
;Interrupthandling bei einer Kolision
kolision:
in tmpi,SREG
push tmpi
ldi statusmot,0x80
pop tmpi
out SREG,tmpi
reti
Wenn etwas doch unklar ist, dann einfach fragen
Lesezeichen