- fchao-Sinus-Wechselrichter AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Adressierung - Verständnisproblem

  1. #1
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    02.11.2005
    Beiträge
    1.614

    Adressierung - Verständnisproblem

    Anzeige

    Powerstation Test
    Servus

    Da wir in der Vorlesung jetzt mit Assembler begonnen haben und ich in den Ferien nicht weiter dazu gekommen bin mich mit dem Thema zu befassen muss ich doch wieder eine Grundlagen Frage stellen.

    Interrupts wurden nicht behandelt, kamen aber im Beispielprogramm vor. Also zum AVR Tutorial und nachgesehen:

    Zitat Zitat von AVR Tutorial
    Aufbau der Interruptvektortabelle

    Jetzt müssen wir dem Assembler nur noch klarmachen, dass er unser rjmp interrupt0 an die richtige Stelle im Programmspeicher schreibt, nämlich an den Interruptvektor für INT0. Dazu gibt es die Assemblerdirektive. Durch .org 0x001 sagt man dem Assembler, dass er die darauffolgenden Befehle ab Adresse 0x001 im Programmspeicher platzieren soll. Diese Stelle wird von INT0 angesprungenen.

    Damit man nicht alle Interruptvektoren immer nachschlagen muss, sind in der Definitionsdatei m8def.inc einfach zu merkende Namen für die Adressen definiert. Statt 0x001 kann man z.B. einfach INT0addr schreiben. Das hat außerdem den Vorteil, dass man bei Portierung des Programms auf einen anderen AVR-Mikrocontroller nur die passende Definitionsdatei einbinden muss, und sich über evtl. geänderte Adressen für die Interruptvektoren keine Gedanken zu machen braucht.

    Nun gibt es nur noch ein Problem: Beim Reset (bzw. wenn die Spannung eingeschaltet wird) wird das Programm immer ab der Adresse 0x000 gestartet. Deswegen muss an diese Stelle ein Sprungbefehl zum Hauptprogramm erfolgen, z.B. rjmp RESET um an die mit RESET: markierte Stelle zu springen.

    Wenn man mehrere Interrupts verwenden möchte, kann man auch, anstatt jeden Interruptvektor einzeln mit .org an die richtige Stelle zu rücken, die gesamte Sprungtabelle ausschreiben:


    .include "m8def.inc"

    .org 0x000 ; kommt ganz an den Anfang des Speichers
    rjmp RESET ; Interruptvektoren überspringen
    ; und zum Hauptprogramm
    rjmp EXT_INT0 ; IRQ0 Handler
    rjmp EXT_INT1 ; IRQ1 Handler
    rjmp TIM2_COMP
    rjmp TIM2_OVF
    rjmp TIM1_CAPT ; Timer1 Capture Handler
    rjmp TIM1_COMPA ; Timer1 CompareA Handler
    rjmp TIM1_COMPB ; Timer1 CompareB Handler
    rjmp TIM1_OVF ; Timer1 Overflow Handler
    rjmp TIM0_OVF ; Timer0 Overflow Handler
    rjmp SPI_STC ; SPI Transfer Complete Handler
    rjmp USART_RXC ; USART RX Complete Handler
    rjmp USART_DRE ; UDR Empty Handler
    rjmp USART_TXC ; USART TX Complete Handler
    rjmp ADC ; ADC Conversion Complete Interrupthandler
    rjmp EE_RDY ; EEPROM Ready Handler
    rjmp ANA_COMP ; Analog Comparator Handler
    rjmp TWSI ; Two-wire Serial Interface Handler
    rjmp SPM_RDY ; Store Program Memory Ready Handler

    RESET: ; hier beginnt das Hauptprogramm

    Hier ist es unbedingt nötig, bei unbenutzten Interruptvektoren statt des Sprungbefehls den Befehl reti reinzuschreiben. Wenn man einen Vektor einfach weglässt stehen die nachfolgenden Sprungbefehle sonst alle an der falschen Adresse im Speicher.
    Hilft nur auch nicht weiter. Mein Problem: Die Adressierung. Uns wurde gesagt "BLOß KEINE FESTEN ADRESSEN FÜR DAS HAUPTPROGRAM!!!" und wenn ich das richtig sehe vergebe ich doch eine feste Adresse für das Hauptprogramm? Und für die Interrupts ebenso... Beispiel aus unserem Code:

    Code:
    .cseg
    
    .org 0x0000
    rjmp Progstart               ; Interrupt Vektor für Reset
    
    .org 0x0002
    rjmp Extint1                   ; Interrupt Vektor für externen Interrupt 1
    
    .org 0x0018
    rjmp TC1int                   ; Interrupt Vektor für Timer/Counter 1-Interrupt
    
    .org 0x0045                   ; Ende der Interrupt Vektor Tabelle
    
    Progstart:
    [...]
    
    Extint1:                          ; ISR für externen Interrupt 1
    
    reti
    
    TC1int:                           ; ISR für Timer/Counter 1 Interrupt
    
    reti
    
    .exit
    Beide Interrupts werden sonst nicht verwendet. Aber: Man benutzt doch einen Adressraum im Speicher für das Hauptprogramm, oder nicht? Von $0000 bis $0002 wenn ich das richtig sehe... Soll man aber doch nicht machen. Und warum werden Adressen für Interrupts ausgegeben die in ihrer Subroutine nichts tun auser an die Stelle zurück zu Springen an der sie benutzt werden ..

    Ich bin verwirrt, helft mir
    [/code]

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von Neutro
    Registriert seit
    28.10.2007
    Ort
    Ostfriesland
    Alter
    44
    Beiträge
    642
    Meine ASM Kenntnisse sind zwar schon etwas eingerostet, aber wird ASM nicht so programmiert das die Adressen zu jedem Befehl vorangestellt sind
    und dann hochgezählt werden, je nachdem ob ein oder zwei Byte Befehl?
    dann wird doch der Sprung auf eine bestimmte Adresse ausgeführt oder auf ein Label.
    Vielleicht ist das bei anderem Compilern aber schon wieder ganz anders als das System das wir damals hatten ( Mikroprozessor Intel 8085)

    MfG

    Neutro
    Jemand mit einer neuen Idee ist ein Spinner, bis er Erfolg hat.
    (Mark Twain)

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    02.11.2005
    Beiträge
    1.614
    Ja du springst immer zu dem Label, relativer spring rjmp

    Also
    Code:
    loop:
    rjmp loop
    Wäre eine Endlosschleife ... Aber das mit den Adressen versteh ich nich. Sage ich, dass mein Programm bei $0000 Anfängt und bei $0018 ein anderer Vektor beginnt heist ja das ich eine Begrenzte Kapazität an Speicher habe O.o Bzw mein Programm eben irgendwann i nden anders benutzten Bereich rein geht ^^

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von Neutro
    Registriert seit
    28.10.2007
    Ort
    Ostfriesland
    Alter
    44
    Beiträge
    642
    Wenn die Speicheradressen fest vergeben sind kann es doch eigentlich nicht
    passieren das eine Adresse 2x verwendet wird. Da muss dann doch der Compiler meckern oder?
    Ein Programm besteht doch immer aus einer Schleife, wenn diese durchgearbeitet ist wird doch wieder an die Startadresse zurückgesprungen.
    Die Unterprogramme werden dann doch unter das Hauptprogramm geschrieben. Dann kann sich da doch eigentlich nichts in die Quere kommen.
    Vielleicht sehe ich das aber auch alles völlig falsch. Wäre gut wenn sich da noch ein erfahrener ASM Progger äußern könnte.

    MfG

    Neutro
    Jemand mit einer neuen Idee ist ein Spinner, bis er Erfolg hat.
    (Mark Twain)

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    02.11.2005
    Beiträge
    1.614
    Jep wäre gut - ich bin nämlcih genauso Verwirrt...

    0x0000
    .
    . PROGRAMM
    .
    0x0018
    .
    . INTERRUPT VEKTOR 1
    .
    0x02

    Für mich sieht das nach Platz problem aus^^

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Das mit "keine festen Adressen" ist so gemeint, dass du dich immer nur auf symbolische Label beziehen sollst, und nicht "jmp 0x0043"

    Natürlich hat ein Label letzlich eine feste adresse, sonst findet ihn ja keiner. Aber diese Adresse vergibt der Assembler, die geht dich nix an.

    Vorteil, klaro: wenn du was einfügst oder löscht, ändern sich ja alle adressen danach. aber der Label (name) bleibt gleich.

    die sache mit der Vector-Tabelle habe ich versucht, dort zu erklären:

    https://www.roboternetz.de/wissen/in...inenprogrammes

    Wenn du meinst, dass es auf einem µC Platzprobleme haben könntest, dann hast du recht
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    02.11.2005
    Beiträge
    1.614
    Also ist das obige so legal. DAs mit den Labels ist klar. Aber wenn ich sage von $0000 bis $0018 ist mein Programm, dann ist ja irgendwann schluss mit Platz ^^


    danke für deinen Link. Seh ich das richtig das man einfach nur eine Adresse für die ISRs vergibt, das Programm aber an einer völlig anderen Stelle steht und für beides genügend Platz vom ASS reserviert wird?

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.112

    Re: Adressierung - Verständnisproblem

    Ich habe Dein eigentliches Problem noch nicht ganz verstanden, aber ich will es versuchen...
    Zitat Zitat von BlackDevil
    Uns wurde gesagt "BLOß KEINE FESTEN ADRESSEN FÜR DAS HAUPTPROGRAM!!!" und wenn ich das richtig sehe vergebe ich doch eine feste Adresse für das Hauptprogramm? Und für die Interrupts ebenso...
    ...könnte heißen, Du sollst nicht schreiben:
    rjmp 0x56;
    denn das wäre Blödsinn, weil sich die Adresse natürlich mit dem Code ändert, der dazwischen steht. Das kann nur der Compiler und der macht das sehr gut, wenn Du Labels (also variable Adressen) verwendest.

    Zitat Zitat von BlackDevil
    Aber: Man benutzt doch einen Adressraum im Speicher für das Hauptprogramm, oder nicht? Von $0000 bis $0002 wenn ich das richtig sehe...
    Wenn ich mich recht errinnerne: Nein! Das sind die Adressen für die IRQs. DIe werden "hardwaremäßig" angesprungen, wenn der entsprechende IRQ ausgelöst wird. Mit .org reservierst Du zunächst Platz bis zum nächsten .org. Diesen Platz nutzt Du für den RJPM Befehl + Sprungsdresse, mehr nicht!. Würdest Du hier zeilenweise Code einfügen, dann würdest Du von einer IRQ Adresse zur nächsten schreiben und so ein riesen Chaos anrichten (sofern Deine Reservierung dem Standard entspricht). Deshalb wird bei größeren µCs 2Words und bei kleinerern nur 1Word reserviert, denn bei größeren ist der Adressraum größer.
    Gruß

  9. #9
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    02.11.2005
    Beiträge
    1.614
    Code:
    .cseg
    
    //.org 0x0000
    //rjmp Progstart               ; Interrupt Vektor für Reset
    
    .org 0x0002
    rjmp Extint1                   ; Interrupt Vektor für externen Interrupt 1
    
    .org 0x0018
    rjmp TC1int                   ; Interrupt Vektor für Timer/Counter 1-Interrupt
    
    .org 0x0045                   ; Ende der Interrupt Vektor Tabelle
    
    //Progstart:
    [...]
    
    Extint1:                          ; ISR für externen Interrupt 1
    
    reti
    
    TC1int:                           ; ISR für Timer/Counter 1 Interrupt
    
    reti
    
    .exit
    Also stehen die mit // gekennzeichneten Stellen zwar im direkten zusammenhang, aber die Adressierung 0x000 und Progstart haben nichts mit einer Adressierung des Programmcodes, der ja dann beim nächsten Org zu ende wäre, zu tun richtig?

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.112
    Du hast eine Gabe, Dich uneindeutig auszudrücken, aber ich würde sagen ja. Denn diese Adressen sind reserviert und hardwarecodiert. Immer, wenn der Reset IRQ ausgelöst wird, springt der Programpointer auf 0x0000 und das kann man nicht ändern. Er führt dann den Code aus, der dort steht, auch wenn da keiner steht. Dann geht alles in die Hose.
    ...denke ich...
    Gruß

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