izaseba
04.06.2005, 16:13
Hallo,
Ich habe mir gedacht, den Asuro mit Assembler zu Programmieren, na ja ich schwimme
immer gegen den Strom...
Es klappt bei den ersten Versuchen, aber bei Odometrie stoße ich doch auf Probleme, und ich hoffe, daß mir hier ein Assemblerguru vielleicht weiterhelfen kann...
zu meinem Programm,
Der Assuro fährt einfach geradeaus, bis der irgendwo gegen fährt, dann fährt er eine Sekunde zurück, dreht sich eine halbe sekunde und fährt weiter...
Naja es klappt alles soweit bis auf das geradeausfahren,
Meine Routine will einfach nicht funktionieren wenn ihr mal drüber gucken könnt,
ich hoffe, daß ich alles ausreichend komentiert habe
.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
Gruß Sebastian
Ich habe mir gedacht, den Asuro mit Assembler zu Programmieren, na ja ich schwimme
immer gegen den Strom...
Es klappt bei den ersten Versuchen, aber bei Odometrie stoße ich doch auf Probleme, und ich hoffe, daß mir hier ein Assemblerguru vielleicht weiterhelfen kann...
zu meinem Programm,
Der Assuro fährt einfach geradeaus, bis der irgendwo gegen fährt, dann fährt er eine Sekunde zurück, dreht sich eine halbe sekunde und fährt weiter...
Naja es klappt alles soweit bis auf das geradeausfahren,
Meine Routine will einfach nicht funktionieren wenn ihr mal drüber gucken könnt,
ich hoffe, daß ich alles ausreichend komentiert habe
.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
Gruß Sebastian