Code:
;Version 1.0
;Odometrie nach dem Beispiel von Rechteck.c
.include "m8def.inc"
.equ fwd = PB5 ;vor
.equ rwd = PB4 ;zurück
.equ encodertrue = 7 ;Bit 7 von tooglereg für Odometrie an/aus
.equ kolisionflag = 6 ;Bit 6 von tooglereg für Kolisionerkennung
.equ toogleflagL = 2 ;Hat eine Änderung am Rad Links stattgefunden ?
.equ toogleflagR = 1 ;Hat eine Änderung am Rad Rechts stattgefunden?
.equ toogle = 0 ;Bit 0 von tooglereg für Rad R "0" und Rad L "1" umzuschalten
.equ geschwindigkeit = 0xA0
.equ encoderon = 0x80
.equ encoderoff = 0x7F
.equ rechterwinkel = 53 ; 90 grad rechts sind genau 53 schritte
.equ rechterwinkel2 = 54 ; 90 grad links sind genau 54 schritte
.equ halbrechterwinkel = 80 ;135 grad rechts
.equ weg = 100 ;soll 300 schritte fahren
.equ weglang = 150 ;Langer Weg diagonal
.equ wegkurz = 50 ;Kurzer Weg für das Dach
.def encoder_leftL = R1
.def encoder_leftH = R2
.def encoder_rightL = R3
.def encoder_rightH = R4
.def vergleicherL = R5
.def vergleicherH = R6
.def tmp = R16 ; Multipurose
.def tmpi = R17 ; Multipurose für Interrupts
.def tmpi2 = R19 ;Multipurose 2 für 16 Bit rechnen
.def tmp2 = R20 ;Multipurose für 16 Bit rechnen
.def geschlinks = R21 ;geschwindigkeit linkes Rad
.def geschrechts = R22 ;geschwindigkeit rechtes Rad
.def tooglereg = R18 ;Toogle Register
.org 0x00
rjmp reset ;ResetVector
.org ADCCaddr
rjmp ADCcomplete ; ADC Interrupt Vector Address
reset:
;Stack einrichten
ldi tmp,HIGH(RAMEND)
out SPH,tmp
ldi tmp,LOW(RAMEND)
out SPL,tmp
;Stack fertig
ldi tooglereg,0x00
ori tooglereg,encoderon
;PWM einstellen
ldi tmp,(1<<WGM10) | (1<<COM1A1) | (1<<COM1B1)
out TCCR1A,tmp
ldi tmp,(1<<CS11)
out TCCR1B,tmp
;DDR für Tastenabfrage
;A/D Conversion
ldi tmp,(1<< ADEN) | (1<<ADFR) | (1<<ADIE) | (1<<ADSC) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2)
out ADCSRA,tmp
ldi tmp,(1<<REFS0) | (1<<ADLAR) | (1<<MUX0)
out ADMUX,tmp
; 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
cbi DDRD,PD3
cbi DDRC,PC0 ;schalte PC0 als eingang
cbi DDRC,PC1 ;schalte PC0 als eingang
sbi PORTD,PD7 ;schalte Odometrie LEDs ein
cbi PORTB,PB0 ;Status LED aus
cbi PORTD,PD2 ;Dito
;ldi tmp,LOW(weg)
;mov vergleicherL,tmp
;ldi tmp,HIGH(weg)
;mov vergleicherH,tmp
;sbi PORTD,PD6
ldi geschrechts,geschwindigkeit
ldi geschlinks,geschwindigkeit
sei
main:
rcall motorengesch
rcall ladeweg
rcall fahre
rcall drehe
rcall ladeweg
rcall fahre
rcall drehe
rcall ladeweg
rcall fahre
rcall drehe
rcall ladeweg
rcall fahre
rcall drehehalb
rcall ladeweglang
rcall fahre
rcall drehelinks
rcall ladewegkurz
rcall fahre
rcall drehelinks
rcall ladewegkurz
rcall fahre
rcall drehelinks
rcall ladeweglang
rcall fahre
rcall motorenloeschen
stop:
rjmp stop
ladeweg:
cli
ldi tmp,LOW(weg)
mov vergleicherL,tmp
ldi tmp,HIGH(weg)
mov vergleicherH,tmp
sei
rcall odozaehlernull
sbi PORTB,fwd
sbi PORTD,fwd
ret
ladeweglang:
cli
ldi tmp,LOW(weglang)
mov vergleicherL,tmp
ldi tmp,HIGH(weglang)
mov vergleicherH,tmp
sei
rcall odozaehlernull
sbi PORTB,fwd
sbi PORTD,fwd
ret
ladewegkurz:
cli
ldi tmp,LOW(wegkurz)
mov vergleicherL,tmp
ldi tmp,HIGH(wegkurz)
mov vergleicherH,tmp
sei
rcall odozaehlernull
sbi PORTB,fwd
sbi PORTD,fwd
ret
drehe:
rcall motorenloeschen ;motoren STOP
ldi tmp,rechterwinkel ;Lade 90 grad Drehung
mov vergleicherL,tmp
ldi tmp,0x00
mov vergleicherH,tmp
rcall odozaehlernull ;Wegezähler löschen
sbi PORTD,fwd ;Jetzt Drehen wir uns was
rcall fahre ;Jetzt warten bis wir uns um 90 grad gedreht haben
rcall motorenloeschen ;motoren STOP
ret
drehelinks:
rcall motorenloeschen ;motoren STOP
ldi tmp,rechterwinkel2 ;Lade 30 schritte für die 90 grad Drehung
mov vergleicherL,tmp
ldi tmp,0x00
mov vergleicherH,tmp
rcall odozaehlernull ;Wegezähler löschen
sbi PORTB,fwd ;Jetzt Drehen wir uns was
rcall fahrelinks ;Jetzt warten bis wir uns um 90 grad gedreht haben
rcall motorenloeschen ;motoren STOP
ret
drehehalb:
rcall motorenloeschen ;motoren STOP
ldi tmp,halbrechterwinkel ;135 grad Drehung
mov vergleicherL,tmp
ldi tmp,0x00
mov vergleicherH,tmp
rcall odozaehlernull ;Wegezähler löschen
sbi PORTD,fwd ;Jetzt Drehen wir uns was
rcall fahre
rcall motorenloeschen ;motoren STOP
ret
fahre:
cli
mov tmp,encoder_rightL
mov tmp2,encoder_rightH
cp vergleicherL,tmp ;Vergleiche gefahrenen Weg
cpc vergleicherH,tmp2
sei
in tmp,SREG
sbrs tmp,0
rjmp fahre
ret
fahrelinks:
cli
mov tmp,encoder_leftL
mov tmp2,encoder_leftH
cp vergleicherL,tmp ;Vergleiche gefahrenen Weg
cpc vergleicherH,tmp2
sei
in tmp,SREG
sbrs tmp,0
rjmp fahrelinks
ret
.include "motoren.asm"
.include "LED.asm"
ADCcomplete:
in tmpi,SREG
push tmpi
ldi tmpi2,0x00
in tmpi,ADCL
in tmpi,ADCH
sbrs tooglereg,toogle ;Wenn Bit toogle = 1 Weiter bei Rechtem Rad
rjmp radlinks
;Rad Rechts
sbrs tooglereg,toogleflagR
rjmp flagRfalse
;flagRtrue
cpi tmpi,0x8C
brsh ausR
ldi tmpi,0x01
add encoder_rightL,tmpi
adc encoder_rightH,tmpi2
;debug
cbi PORTD,PD2
sbi PORTB,PB0
;ende debug
andi tooglereg,0xFD
rjmp ausR
flagRfalse:
cpi tmpi,0xA0
brlo ausR
ldi tmpi,0x01
add encoder_rightL,tmpi
adc encoder_rightH,tmpi2
;debug
cbi PORTD,PD2
sbi PORTB,PB0
;ende debug
ori tooglereg,(1<<toogleflagR)
ausR:
sbi ADMUX,MUX0
andi tooglereg,0xFE
rjmp rausadc
radlinks:
sbrs tooglereg,toogleflagL ;ist toogleflagL gesetzt? wenn ja springe zu flagtrue
rjmp flagLfalse ;wenn nicht springe zu flagLfalse
;flagLtrue
cpi tmpi,0x8C ;vergleiche mit 0xA0
brsh ausL ;wenn größer oder gleich springe zu ausL
ldi tmpi,0x01
add encoder_leftL,tmpi ;encoder_left++
adc encoder_leftH,tmpi2
;Debug
sbi PORTD,PD2
cbi PORTB,PB0
;Ende Debug
andi tooglereg,0xFB ;Lösche flagL
rjmp ausL
flagLfalse:
cpi tmpi,0xA0
brlo ausL
ldi tmpi,0x01
add encoder_leftL,tmpi
adc encoder_leftH,tmpi2
;Debug
sbi PORTD,PD2
cbi PORTB,PB0
;ende debug
ori tooglereg,(1<<toogleflagL)
ausL:
cbi ADMUX,MUX0
ori tooglereg,(1<<toogle)
rjmp rausadc
rausadc:
pop tmpi
out SREG,tmpi
reti
Lesezeichen