-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 19

Thema: Wo sind die Ports des ATmega8L im Code definiert?

  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    61
    Beiträge
    674

    Wo sind die Ports des ATmega8L im Code definiert?

    Anzeige

    Wenn man sich von oben nach unten im Code durchwühlt, trifft man im low level Bereich auf Code wie diesen:

    Code:
    inline void MotorSpeed (unsigned char left_speed, unsigned char right_speed)
    {
      OCR1A = left_speed;
      OCR1B = right_speed;
    }
    
    inline 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;
    }
    Jetzt die Frage:
    Woher kennt der Compiler die Definition der Variablen OCR1A, OCR1B, PORTB, PORTD, PB4, PB5, PD4, PD5 ? Ich habe in den Files der Lib 2.70 gesucht aber nirgends etwas gefunden.

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    19.06.2006
    Ort
    Schriesheim
    Alter
    30
    Beiträge
    478
    AVR Studio --> External-Dependencies --> "iom???.h" --> "iomxx0_1.h"

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Diese Definitionen werden mit dem Compiler geliefert und liegen daher in dessen Verzeichnis.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    18.12.2006
    Ort
    Eberbach
    Beiträge
    199

    Re: Wo sind die Ports des ATmega8L im Code definiert?

    Hi,
    Zitat Zitat von ehenkes
    ...
    Jetzt die Frage:
    Woher kennt der Compiler die Definition der Variablen OCR1A, OCR1B, PORTB, PORTD, PB4, PB5, PD4, PD5 ? Ich habe in den Files der Lib 2.70 gesucht aber nirgends etwas gefunden.
    bei mir ist <WinAVR_ROOT> = c:\WinAVR.

    In asuro.h:
    Code:
    ...
    #define ASURO_H
    
    #include <avr/io.h>
    ...
    In <WinAVR_ROOT>\avr\include\avr\io.h:
    Code:
    ...
    #elif defined (__AVR_ATmega8__)
    #  include <avr/iom8.h>
    ...
    Und in <WinAVR_ROOT>\avr\include\avr\iom8.h findest Du ALLES ...

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    18.12.2006
    Ort
    Eberbach
    Beiträge
    199

    Re: Wo sind die Ports des ATmega8L im Code definiert?

    ... und das Define __AVR_ATmega8__ kommt (irgendwie magic) aus dem mcu = atmega8 im Makefile.

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    61
    Beiträge
    674
    Klasse Spurensuche! Jetzt fehlen mir nur noch diese ...

    _SFR_IO16
    _SFR_IO8

    z. B. aus
    #define OCR1A _SFR_IO16(0x2A)
    #define OCR1B _SFR_IO16(0x2
    #define PORTB _SFR_IO8(0x1
    #define PORTD _SFR_IO8(0x12)

    ... dann wäre die Kette komplett.

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    61
    Beiträge
    674
    Ich habe es via google gefunden: in sfr_defs.h

    Code:
    #define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
    #define _SFR_IO16(io_addr) ((io_addr) + __SFR_OFFSET)
    
    #ifndef __SFR_OFFSET
    /* Define as 0 before including this file for compatibility with old asm
       sources that don't subtract __SFR_OFFSET from symbolic I/O addresses.  */
    #define __SFR_OFFSET 0x20
    #endif
    Kann dies bitte jemand erläutern? Wann muss ich __SFR_OFFSET als 0 setzen anstelle 0x20?

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Das hängt mit der internen Architektur des AVRs zusammen. Es gibt zwei Methoden, die Hardware-Konfigurations-Register (SFRs) anzusprechen, und deswegen hat jedes SFR auch zwei Adressen. Schau dir mal in Datenbaltt die Registerübersicht an. Für PORTB steht dort z:b. 0x18 (0x3. Beide Adressen bezeichnen dasselbe Register, aber unter Verwendung der beiden Zugriffsmethoden:
    die erste ist direkter Zugiff auf die Register mit speziellen Befehlen (IN/OUT). Dabei wird kein Offset benötigt. DIe Adresse von PORTB ist hier also 0x18. Mit "OUT 0x18, r16" wird daher der Inhalt von Register 16 auf PORTB ausgegeben.

    Als zweite Möglichkeit werden die Register quasi ins RAM gespiegelt, haben also jedes eine eigene Speicheradresse. Da in den ersten 32 Bytes des RAMs aber schon die Multifunktionsregister leigen, fangen die SFRs erst bei 0x0020 an. Der eigentliche RAM beginnt übrigens erst bei 0x0060, weil davor halt die SFRs liegen.
    "STS 0x38, r16" würde wiederum Register 16 auf PORTB ausgeben.

    EDIT: stimmt wohl doch nicht!
    Der C-Compiler bevorzugt grundsätzlich die zweite Methode und braucht daher den Offset.

    Ich hoffe das war korrekt so, hab lange kein ASM mehr geschrieben (da muss man sowas mitunter beachten. Wenn du also neugierig bist, wie der AVR wirklich funktioniert, solltest du dich etwas mit ASM beschäftigen).

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    14.04.2007
    Ort
    Einhausen
    Alter
    61
    Beiträge
    674
    Danke, das ist sehr verständlich erklärt. Jetzt bleibt nur noch die offene Frage: Warum verwendet der C-Compiler die Methode via RAM? ... oder anders gefragt: kann ich den C-Compiler zwingen, direkt auf die Register (ohne Spiegelung ins RAM) zuzugreifen?

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    06.02.2005
    Ort
    Hamburg
    Alter
    31
    Beiträge
    4.255
    Da hab ich wohl falsch vermutet. Hab mir grad mal nen .hex disassembliert. Es wird doch IN/OUT verwendet.

    Es gibt aber bei den größeren AVRs mit vielen Funktionen auch SFRs, die sich nur als RAM ansprechen lassen. Dafür wird der Offset auf jeden Fall benötigt.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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