-
Assembler und Odometrie
Hallo Leute,
ich wollte die Odometrie benutzen, zum Initialisieren benutze ich:
Code:
.include "m8def.inc"
SBI PORTD, PORTD7
SBI DDRD, DDD7
CBI PORTC, PORTC0
CBI PORTC, PORTC1
CBI DDRC, DDC0
CBI DDRC, DDC1
Ist das richtig?
Nun ist mein Problem wie aktiviere ich den Eingang ...
Normalerweise mit dem Befehl IN aber wie wende ich ihn dann an?
EDIT:
Habe nun folgendes geschrieben:
Code:
.include "m8def.inc"
SBI PORTD, PORTD7
SBI DDRD, DDD7
SBI DDRD, DDD6
CBI PORTC, PORTC0
CBI PORTC, PORTC1
CBI DDRC, DDC0
CBI DDRC, DDC1
main: sbi PORTD, PORTD6
sbic PORTC0, 1
cbi PORTD, PORTD6
RJMP main
Aber die Front-LED leuchtet durchgehend ...
Was habe ich falsch gemacht?
Bzw. falsch gedacht?
-
Nachdem Du deine LED ausgeschalten hast mit cbi PORTD, PORTD6 springst Du wieder zum Anfang der Schleife wo Du die LED sofort wieder einschaltest mit sbi PORTD, PORTD6. Wenn Du in nem Zimmer den Lichtschalter schnell ein- und ausschaltest wirds da auch nicht dunkel.
8-[
-
Hallo zusammen.
Auserdem hat der PORTD6 da nicht zu suchen, denn er hat nichts
mit der Odometrie zu tun.
Sondern mit dem Linienverfolger.
MfG
A.Hoffmann
-
Hallo ...
danke für eure Antworten ...
Ich habe folgendes vor:
Drehe ich an einem Rad soll vorne die Front-LED an bzw. ausgehen.
Fertig!
@Rofo88:
Wie würdest du denn das Programm schreiben auf Basis von meiner Version?
-
Code:
main: sbic PINC, 1
rjmp ein
cbi PORTD, 6
rjmp end
ein: sbi PORTD, 6
end: RJMP main
Wenn Du mit dem AVR Studio arbeitest versuchs mal mit dem Debugger.
MfG
-
Hallo H3IIGhost.
Dazu mußt du die Radumdrehung erkennen.
Das was du bisher gemacht hast, ist nur die Vorbereitung für
die Odometrie Messung.
Du muß also noch den Analog - Digitalkonverter auswerten, um eine
Bewegung des Rades zu erkennen.
Schau dir doch mal die Beispielfunktion in der Orginal C - Lib an.
void OdometrieData(unsigned int *data)
Wenn du dir ein C - Projekt mit dieser Lib anlegst, kannst du dir auch
den Assembler -Code im Disassembler anschauen.
Ich würde dir auch empfehlen, diesen Code zu Benutzen.
Mit den normalen Assembler Anweisungen gibt es jede menge Probleme
mit dem ADC.
MfG
A.Hoffmann
-
Odometrie mit Assembler
Hallo
Versuche es einmal damit.
Wenn du an dem rechten Rad drehst, müsste sich der gewünschte Efekt
einstellen.
Code:
.include "m8def.inc"
.def rBin1H = r0
.def rBin1L = r1
.def temp = r16 ; Arbeitsregister
.def temp2 = r17 ; Arbeitsregister
.def schwarzL = r18 ; Schwellwert für schwarz
.def schwarzH = r19
.def weisL = r20 ; Schwellwert für weiß
.def weisH = r21
.equ CLOCK = 8000000
.cseg
.org 0x000
rjmp Prog_Initial ; Interruptvektoren überspringen
reti ; INT0addr - Externer Interrupt 0
reti ; INT1addr - Externer Interrupt 1
reti ; OC2addr - Output Compare2
reti ; OVF2addr - Overflow2
reti ; ICP1addr - Input Capture1
reti ; OC1Aaddr - Output Compare1A
reti ; OC1Baddr - Output Compare1B
reti ; OVF1addr - Overflow1
reti ; OVF0addr - Overflow0
reti ; SPIaddr - SPI
reti ; URXCaddr - USART Receive Complete
reti ; UDREaddr - USART Data Register Empty
reti ; UTXCaddr - USART Transmit Complete
reti ; ADCCaddr - Analog Digital wandler
reti ; ERDYaddr - EEPROM
reti ; ACIaddr - Analog Comparator
reti ; TWIaddr - Two - Wire Interface
reti ; SPMaddr - SPM complete
Prog_Initial:
;******************************************************************************
; Stack Pointer setzen *
;******************************************************************************
ldi temp, LOW(RAMEND) ; Stack Pointer low
out SPL, temp ; setzen
ldi temp, HIGH(RAMEND) ; Stack Pointer high
out SPH, temp ; setzen
;******************************************************************************
;* Init LEDs *
;******************************************************************************
sbi DDRB, DDB0 ; Duo LED grün
sbi DDRD, DDD2 ; Duo LED rot
cbi PORTB, PORTB0 ; aus
cbi PORTD, PORTD2 ; schalten
sbi DDRD, DDD6 ; Front LED
cbi PORTD, PORTD6 ; aus
sbi DDRD, DDD7 ; Back LEDs
cbi PORTD, PORTD7
sbi DDRC, DDC0
sbi DDRC, DDC1
cbi PORTC, PORTC1
cbi PORTC, PORTC1 ; ausschalten
sei ; Interrupts erlauben
;**************** Ende Init **********************************************
Prog_Run:
rcall odometrie_led_on
rcall odo_ticks_rechts
rjmp Prog_Run
;******************************************************************************
; Odometrie Sensor Ticks Rechts *
;******************************************************************************
odo_ticks_rechts:
ldi schwarzL, 0x8A
ldi schwarzH, 0x02
ldi weisL, 0xC2
ldi weisH, 0x01
weis: ; schwarz -> weiß übergang
rcall odometrie_r
cp rBin1L, weisL ; compare aktuellen Wert
cpc rBin1H, weisH ; mit weiß
brlo wtiksplus3 ; branch wenn < schwellwert weiß
rjmp weis ; nein weiter warten
wtiksplus3:
rcall front_led_on
schwarz: ; weiß -> schwarz Übergang
rcall odometrie_r
cp rBin1L, schwarzL ; compare aktuellen Wert
cpc rBin1H, schwarzH ; mit schwarz
brsh wtiksplus4 ; branch wenn => schwellwert schwarz
rjmp schwarz ; nein weiter warten
wtiksplus4:
rcall front_led_off
rjmp weis
;******************************************************************************
; Odometrie LED On *
;******************************************************************************
odometrie_led_on:
cbi DDRC, DDC0 ; Richtungs Steuerung
cbi DDRC, DDC1 ; C= + C1 = INPUT
sbi PORTD, PORTD7 ; Odometrie LED On
ret
;******************************************************************************
; Odometrie Sensor Rechts *
;******************************************************************************
odometrie_r:
;ADMUX = (1 << REFS0) | WHEEL_RIGHT AVCC reference with external capacitor
LDI R30,0x27 ;Load immediate
LDI R31,0x00 ;Load immediate
LDI R24,0x40 ;Load immediate
STD Z+0,R24 ;Store indirect with displacement
;ADCSRA |= (1 << ADSC); // Start conversion
LDI R26,0x26 ;Load immediate
LDI R27,0x00 ;Load immediate
LDI R30,0x26 ;Load immediate
LDI R31,0x00 ;Load immediate
LDD R24,Z+0 ;Load indirect with displacement
ORI R24,0x40 ;Logical OR with immediate
ST X,R24 ;Store indirect
;while (!(ADCSRA & (1 << ADIF))) wait for conversion complete
lab2:
LDI R30,0x26 ;Load immediate
LDI R31,0x00 ;Load immediate
LDD R24,Z+0 ;Load indirect with displacement
CLR R25 ;Clear Register
ANDI R24,0x10 ;Logical AND with immediate
ANDI R25,0x00 ;Logical AND with immediate
SBIW R24,0x00 ;Subtract immediate from word
BREQ lab2 ;Branch if equal
;ADCSRA |= (1 << ADIF) clear ADCIF
LDI R26,0x26 ;Load immediate
LDI R27,0x00 ;Load immediate
LDI R30,0x26 ;Load immediate
LDI R31,0x00 ;Load immediate
LDD R24,Z+0 ;Load indirect with displacement
ORI R24,0x10 ;Logical OR with immediate
ST X,R24 ;Store indirect
;**************** Daten sichern und weiter Verarbeiten *********************
;data[1] = ADCL + (ADCH << 8);
in rBin1L, ADCL ; Ergebnis
in rBin1H, ADCH ; sichern
ret ;Subroutine return
;******************************************************************************
;* Front LED Ein *
;******************************************************************************
front_led_on:
sbi PORTD, PORTD6
ret
;******************************************************************************
;* Front LED Aus *
;******************************************************************************
front_led_off:
cbi PORTD, PORTD6
ret
MfG
A.Hoffmann
-
Äh ...
danke danke, A.Hoffmann, mein Freund ... ;) ...
Aber da weiß mein Lehrer doch sofort, dass ich das nicht gemacht habe ... :D
Was machen eigentlich folgende Befehle:
reti, .equ, .cseg, .org, etc.
Was ist der Stack Pointer?
Und ich steige im Moment nicht wirklich durch das Programm durch ... :D
Gibt es das vielleicht auch als Version, wie ich die habe?!
So in die Richtung?
EDIT:
Habe nicht das Programm von Roffo88 gesehen ...
@Roffo88: Danke! Sowas Einfaches habe ich mir erstmal vorgestellt ... ;)
@A.Hoffmann: Nochmals danke für deine Mühe, werde nur mir deinen Code anschauen ... und selber versuchen das auf das zweite Rad zu übertragen ...
EDIT2:
Danke Roffo88 habe ich nun eine erweiterte Version geschrieben.
Die steuert die Status-LED an:
Code:
.include "m8def.inc"
SBI PORTD, PORTD7
SBI DDRD, DDD7
SBI DDRD, DDD2
SBI DDRB, DDB0
CBI PORTC, PORTC0
CBI PORTC, PORTC1
CBI DDRC, DDC0
CBI DDRC, DDC1
main: sbic PINC, 1
rcall ein1
cbi PORTD, 2
sbic PINC, 0
rcall ein2
cbi PORTB, 0
rjmp main
ein1: sbi PORTD, 2
ret
ein2: sbi PORTB, 0
ret
-
Guten Abend zusammen.
Eine Beschreibung der Assembler Anweisungen und dirktiven, findest
du auf www.atmel.com. Gib dort in das Suchfenster doc1022 ein.
Ansonsten soll dir das Programm nur als Beispiel dienen.
Es gibt bstimmt bessere Lösungen, aber um eins wirst du nicht herumkommen du mußt mit dem Analog - Digtalwandler arbeiten.
Sonst kannst du keine Radbewegung erkennen.
MfG
A.Hoffmann
-
Hallo,
leider ist ja die Anleitung auf Englisch und die Beispiele sind dürftig!
Danke nochmals für das Programm.
Ich wollte ja noch keine Bewegung selber messen, sondern einfach nur überprüfen, ob schwarz oder weiß unter dem Sensor ist und das halt dann ausgeben.
Oder weiß jemand wo man eine deutsche Beschreibung der Befehle bekommt?