- LiFePO4 Speicher Test         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: Assembler und Odometrie

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168

    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?

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.10.2004
    Ort
    Baoding
    Alter
    44
    Beiträge
    689
    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.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    05.07.2007
    Beiträge
    44
    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

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    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?

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.10.2004
    Ort
    Baoding
    Alter
    44
    Beiträge
    689
    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

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    05.07.2007
    Beiträge
    44
    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

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    05.07.2007
    Beiträge
    44

    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

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    Äh ...
    danke danke, A.Hoffmann, mein Freund ... ...
    Aber da weiß mein Lehrer doch sofort, dass ich das nicht gemacht habe ...

    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 ...

    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

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    05.07.2007
    Beiträge
    44
    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

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.09.2007
    Beiträge
    168
    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?

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen