- LiTime Speicher und Akkus         
Ergebnis 1 bis 10 von 10

Thema: Verständnisproblem #define

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.04.2008
    Alter
    39
    Beiträge
    557

    Verständnisproblem #define

    Anzeige

    Powerstation Test
    Moin,

    ich spiele grade mit einem Mega8 und einem L298N rum um zwei Motoren anzusteuern.

    Ich versuche dabei das Prinzip (in Hard- wie Software) vom einem vorhandenen Board / Programm nachzuvollziehen.

    Verdrahtet ist der L298N wie folgt mit dem Mega8 (nur Logik):

    L298N -> Mega8

    IN1 -> PB5
    IN2 -> PB4
    ENA -> PB2 (OC1B)

    IN3 -> PD4
    IN4 -> PD5
    ENB -> PB1 (OC1A)

    Die Drehrichtung wird ja über H(igh) und L(ow) an den Input(IN)-Pins vorgegeben. Über die PWM-Pins an ENA und ENB wird die Geschwindigkeit geregelt. Die Geschwindigkeit funktioniert auch und wurde auch von mir verstanden. Aber bei der Richtungswahl komme ich grade nicht weiter:

    Die Funktion dafür sieht wie folgt aus (wurde scheinbar vom Asuro adoptiert)

    Code:
       
    void MotorDir(unsigned char left_dir, unsigned char right_dir)
    {
    PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | left_dir;
    PORTB = (PORTB &~ ((1 << PB4) | (1 << PB5))) | right_dir;
    }
    Beim Funktionsaufruf werden “Schlüsselwörter” übergeben (FWD,RWD,BREAK,FREE) welche wie folgt definiert werden:

    Code:
    #define     FWD        (1 << PB5) /* (1 << PD5) */
    #define     RWD        (1 << PB4) /* (1 << PD4) */
    #define     BREAK      0x00
    #define     FREE       (1 << PB4) | (1 << PB5) /* (1 << PD4) | (1 << PD5)*/
    So viel zur Theorie und den Grundlagen. Mein Problem ist jetzt folgendes:

    Um die Drehrichtung zu bestimmen wird einer der beiden IN-Pins pro Motor auf H der andere auf L gezogen (BREAK und FREE mal außen vor). Da aber die Pins PD4 und PD5 in der Definition auskommentiert sind, werden diese doch bei einem Funktionsaufruf gar nicht geändert, bzw. ein

    Code:
    MotorDir(FWD,FWD);
    würde doch ein

    Code:
    PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | (1<<PB5);
    erzeugen.


    Wie ist es jetzt also Möglich, dass mit dem Aufruf der Funktion die Pegel von PD4 und PD5 beeinflusst werden?
    Haben die /* */ hinter einem #define vielleicht eine andere Wirkung als das auskommentieren des dazwischen befindlichen Codes?
    Alles ist möglich. Unmögliches dauert nur etwas länger!

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Auskommentiert ist der zweite Teil, weil PD5 gleich PB5 gilt (ist beides Mal die Zahl 5). Damit kann das gleiche Makro sowohl für die Richtung links als auch rechts verwendet werden.

    Was der Code macht ist relativ einfach: Er löscht erst beide Richtungsbits auf einer Seite und setzt dann die von dir übergebenen, im Falle von FWD also Pin 5 am jeweiligen Port.

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.04.2008
    Alter
    39
    Beiträge
    557
    Also wird unterschieden, ob PORTD oder PORTB beschrieben werden soll und dazu passend aus dem #define das PD5 bzw PB5 ausgewählt?
    Alles ist möglich. Unmögliches dauert nur etwas länger!

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Also wird unterschieden, ob PORTD oder PORTB beschrieben werden soll und dazu passend aus dem #define das PD5 bzw PB5 ausgewählt?
    Nein, im Define ist es immer PB5. Aber PD5 und PB5 sind einfach beide das Gleiche, nämlich einfach 5.
    Code:
    PORTD = 1<<PD5;
    PORTD = 1<<PB5;
    PORTD = 1<<5;
    Alle drei Zeilen sind völlig identisch.


    PS: Ist aber schlechter Programmierstil, weil verwirrend (wie man sieht).
    Ich hätte es eher so geschrieben:
    Code:
    #define  FWD  (1 << 5)    /* PD5,PB5 */
    Geändert von sternst (23.01.2012 um 15:25 Uhr)
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Zitat Zitat von Arkon Beitrag anzeigen
    Also wird unterschieden, ob PORTD oder PORTB beschrieben werden soll und dazu passend aus dem #define das PD5 bzw PB5 ausgewählt?
    Nein, sieh dir Mal den Code hier genauer an:

    Code:
    #define     FWD        (1 << PB5) /* (1 << PD5) */
    #define     RWD        (1 << PB4) /* (1 << PD4) */
    #define     BREAK      0x00
    #define     FREE       (1 << PB4) | (1 << PB5) /* (1 << PD4) | (1 << PD5)*/
    
    void MotorDir(unsigned char left_dir, unsigned char right_dir) {
    
    PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | left_dir;
    PORTB = (PORTB &~ ((1 << PB4) | (1 << PB5))) | right_dir;
    } MotorDir(FWD,FWD);
    PB5 wird irgendwo in den Untiefen der avr-libc als 5 definiert, ebenso PD5. Warum? Weil es eben das Bit 5 im entsprechenden Register ist. Der Trick besteht einfach darin, dass die Pinbelegung für Links/Rechts symmetrisch gemacht wurde, damit sind alle Konstanten übertragbar. Aus FWD wird also (1 << 5)

    MotorDir setzt jetzt auf beiden Seiten beide Richtungspins auf 0 und "verodert" da dann dein FWD rein. Die Funktion überschreibt also IMMER den Status beider Seiten, MotorDir(FWD, FWD) tut nichts anderes als in den Register PORTD und PORTB jeweils Bit 5 zu setzen. Der Konstanten ist es vollkommen egal, wo sie eingesetzt wird, niemand wählt da irgendwas aus ...

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.04.2008
    Alter
    39
    Beiträge
    557
    Ah jetzt ja.....

    Danke an euch. Hab den Code wie sternst gepostet hat geändert. So macht das auch wieder Sinn
    Alles ist möglich. Unmögliches dauert nur etwas länger!

  7. #7
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Wenn dein Programm io.h includet, dann sucht der Kompiler nach der zum Kontroller passenden io-Datei:

    C:\WinAVR\avr\include\avr\iom8.h

    Und in dieser Datei findest du die Defines für PB5 und PD5.
    (Da findet man auch die schwer zu merkenden ISR-Namen)

    Gruß

    mic

    "wurde scheinbar vom Asuro adoptiert" Quelle des Programms?
    Geändert von radbruch (23.01.2012 um 15:35 Uhr)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.04.2008
    Alter
    39
    Beiträge
    557
    Zitat Zitat von radbruch Beitrag anzeigen
    wurde scheinbar vom Asuro adoptiert" Quelle des Programms?
    Jemand an unserer Hochschule hat das Board und das Programm dazu geschrieben. War vor 2 oder 3 Jahren bei einem Wettkampf an der FH im Einsatz. Wurde dann durch ein neues, komplexeres Board ersetzt (dass ich auch für meinen Low-Cost-Bot verwende). Ich konnte halt ein paar "Restbestände" abgreifen.
    Alles ist möglich. Unmögliches dauert nur etwas länger!

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.04.2008
    Alter
    39
    Beiträge
    557
    Nachtrag:

    Kann mir noch jemand erklären, warum bei MotorDir(FREE,FREE); die Motoren frei drehen?

    Um dies zu erreichen muss der Enable-Pin des jeweiligen Motors auf LOW gezogen werden. Das wären ja die beiden PWM-Pins OC1A und OC1B bzw. PB2 und PB3.

    Nach meinem, scheinbar fehlerhaften, Verständnis wird ja so der PORTD bzw. PORTB komplett auf LOW gezogen. Davon unbeeindruckt dürfte doch aber die PWM-Einstellung sein wordurch die Enable-Pins nicht (dauerhaft) auf LOW gezogen werden.
    Alles ist möglich. Unmögliches dauert nur etwas länger!

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Negativ, FREE setzt jeweils die Pins 4 und 5 auf HIGH. Die beiden High-Side Transistoren werden also ausgeschaltet, die beiden Low-Side Transistoren werden durch das PWM beeinflusst. Der Stromfluss setzt sich aber unabhängig von den Low-Side Transistoren durch die Freilaufdioden fort, der Motor wird relativ wenig abgebremst. Bei BREAK wird dagegen der Stromfluss abgebremst, da VCC bei den High-Side Transistoren durchgeschaltet wird, der Stromfluss durch die beiden unteren Freilaufdioden aber eigentlich in die entgegengesetzt Richtung läuft.

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

Ähnliche Themen

  1. Baudraten - #define xxx und einige Auswirkungen
    Von oberallgeier im Forum Software, Algorithmen und KI
    Antworten: 14
    Letzter Beitrag: 15.11.2011, 10:04
  2. #define und adressen setzten in asm30 - dspic
    Von Pitt1986 im Forum PIC Controller
    Antworten: 2
    Letzter Beitrag: 10.06.2008, 21:13
  3. Mit #define zugewiesene Konstanten nicht zuweisbar?
    Von EDatabaseError im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 21.05.2008, 18:09
  4. Verständnisproblem declare Sub
    Von meldano im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 15.06.2007, 06:56
  5. #define send, #define reveice
    Von pebisoft im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 09.03.2005, 08:37

Berechtigungen

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

LiTime Speicher und Akkus