www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik avr-tutorial timer, interruptvektor ist nicht definiert


Autor: ALB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
ich beschäftige mich gerade mit dem avr-gcc tutorial auf dieser seite 
und habe eine problem bei den timern. ich will den overflow interrupt 
vom timer1 abfragen. habe schon rausgefunden das der interuptvektor bei 
meinem atmega32 etwas anders heißt als im tutorial. nämlich: TIMER1_OVF. 
also sollte ich ihn doch folgendermaßen benutzen:

#include <avr/interrupt.h>

.text                              ; was nun folgt, gehört in den 
FLASH-Speicher

.global main                       ; main ist auch in anderen Modulen 
bekannt
 temp = r24
.org 0x0000
        rjmp    main                  ; Reset Handler
.org TIMER1_OVF_vect
        rjmp    timer1_overflow       ; Timer Overflow Handler

main:                              ; zu 'main' wird nach Reset 
hingesprungen
        LDI R24, 0xFF
        OUT _SFR_IO_ADDR(DDRA), R24  ;port a als ausgabe setzten
        OUT _SFR_IO_ADDR(PORTA), R24 ;ale pins auf 1

        ldi     r16, 0b00000010      ; CS00 setzen: Teiler 8
        OUT _SFR_IO_ADDR(TCCR1B) , R16

        ldi     r16, 0b00000100      ; TOIE0: Interrupt bei Timer 
Overflow
        OUT _SFR_IO_ADDR(TIMSK), r16

        ldi r17,0x00
        sei

  rjmp Hauptschleife


Hauptschleife:





        rjmp Hauptschleife
timer1_overflow:                      ; Timer 0 Overflow Handler
        OUT _SFR_IO_ADDR(PORTB), r17
        com     r17
        reti

ich bekomme dann folgende fehlermeldung vom compiler:
p4real@noname:~/avr$ avr-gcc -mmcu=atmega32 test.S
test.S: Assembler messages:
test.S:10: Warning: symbol "__vector_9" undefined; zero assumed
test.S:10: Error: attempt to move .org backwards

da steht etwas von vector9(das ist der vektor für den timer1 overflow 
interrupt) jetzt habe ich aber keine ahnung warum der nicht definiert 
ist.

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Prust.
1.)Also als erstes solltest du dir überlegen, ob du in C oder ASM 
programmieren willst.

2.)Wenn du das weißt, versuchs noch einmal selber.
Wenn es dann wieder nicht klappt, melde dich nochmal.

Gruß.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fabian Ostner wrote:
> Prust.
> 1.)Also als erstes solltest du dir überlegen, ob du in C oder ASM
> programmieren willst.
Er hat sich bereits für Assembler entschieden. Was gibt es da 
auszusetzen? Wenn man keine Ahnung hat, sollte man mit solchen 
Äußerungen sehr vorsichtig sein.

@ALB:
Ich meine, mich erinnern zu können, dass es mit den Vektoradressen 
sowieso in gnu-asm ein kleines Problem gab (gnu-asm arbeitet mit 
Byte-Adressen, nicht mit Wort-Adressen wie der ATMEL-AVR-ASM).

Wirf mal einen Blick in den Thread:
Beitrag "Atmel ASM portieren"
Möglicherweise sind da schon ein paar Deiner Probleme behandelt.

EDIT:
Ach ja, die avr/io.h fehlt natürlich, weshalb der den Vektornamen auch 
nicht kennt. Wundert mich nur, dass es nicht mehr Fehlermeldungen 
gibt...

Autor: Chris :) (fr34k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>habe schon rausgefunden das der interuptvektor bei
>meinem atmega32 etwas anders heißt als im tutorial. nämlich: TIMER1_OVF.

Ich hoff ich schreib jetzt keinen blödsinn, aber soweit ich mich 
erinnern kann heißt der vektor: TMR1_OVF

wie gesagt, ich hab jetzt grad weder datenblatt noch sonstwas bei der 
hand, is nur ne erinnerung ....

Autor: ALB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke,
der beitrag hat geholfen. (suchfunktion hatte ich zwar auch benutzt, 
aber den hab ich nicht gefunden)

TIMER1_OVF_vect versteht der assembler nicht. also habe ich die 
speicheradresse direkt angegeben, was in meinem fall 0x008 ist.

@ Johannes M. : die avr/io.h hab ich nur versehentlich nicht mit ins 
forum kopiert, sorry

jetzt kann der code ohne Fehler und wahrnungen compiliert werden, aber 
blinken tut trotzdem nichst. `_´ Nur dauerleuchten.
hab den code rauf und runter gelesen und alles nochma geprüft. keine 
ahnung woran es liegt. kann vielleicht nochmal einer von euch füchsen 
nen blick drauf werfen?

#include <avr/io.h>
#include <avr/interrupt.h>

.text                              ; was nun folgt, gehört in den 
FLASH-Speicher

.global main                       ; main ist auch in anderen Modulen 
bekannt


.org 0x0000
        rjmp    main                  ; Reset Handler
.org 0x008
        rjmp    timer1_overflow       ; Timer Overflow Handler

main:                              ; zu 'main' wird nach Reset 
hingesprungen
        LDI R24, 0xFF
        OUT _SFR_IO_ADDR(DDRA), R24  ;port a als ausgabe setzten
  OUT _SFR_IO_ADDR(PORTA), R24 ;alle pins auf 1

        ldi     r16, 0b00000010      ; CS00 setzen: Teiler 8
        OUT _SFR_IO_ADDR(TCCR1B) , R16

        ldi     r16, 0b00000100      ; TOIE0: Interrupt bei Timer 
Overflow
        OUT _SFR_IO_ADDR(TIMSK), r16
   ldi r17,0x00
        sei

  rjmp Hauptschleife


Hauptschleife:

        rjmp Hauptschleife
timer1_overflow:                      ; Timer 1 Overflow Handler
        OUT _SFR_IO_ADDR(PORTA), r17
        com     r17
        reti

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ ALB (Gast)

>TIMER1_OVF_vect versteht der assembler nicht. also habe ich die
>speicheradresse direkt angegeben, was in meinem fall 0x008 ist.

Tu uns und vor allem DIR einen grossen Gefallen und vergiss den GCC 
Assembler. Dessen Syntax ist inkompatibel zum AVR-Studio. Und so gut wie 
keiner verwendet ihn. Du wirst also auf verlorenem Posten kämpfen.

MFG
Falk

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ALB wrote:

> ...aber
> blinken tut trotzdem nichts. `_´ Nur dauerleuchten.

Was sagt denn deine Theorie zur Blinkgeschwindigkeit?

Ohne den Code zu prüfen: Wenn es zu schnell fürs Auge ist, gibt es 
Dauerleuchten sowie wenn es zu langsam ist und gleichzeitig mit Licht an 
gestartet wird, dann auch...

Autor: ALB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@falk: ja so lansam kotzt mich dieses ding auch an. kennt jemand einen 
avr-studio kompatiblen assembler für linux?

Autor: ALB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@steffan: also an der geschwindigkeit sollte es nicht liegen. 16 bit 
zähler zählt bis 65536, vorteiler 8 => zählt etwa 500000 takte, bei 1MHz 
schaltet er 2 mal pro sekunde.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:

> Tu uns und vor allem DIR einen grossen Gefallen und vergiss den GCC
> Assembler. Dessen Syntax ist inkompatibel zum AVR-Studio. Und so gut wie
> keiner verwendet ihn.

Das ist, mit Verlaub, Quatsch.

Das Teil vom AVR Studio ist ein einfachster Absolutassembler, der zu
nicht viel taugt.  Eric Weddington hätte ihn lieber heute als morgen
komplett abgeschossen, da der Aufwand für die Parallelentwicklung
unsinnig ist.  Das scheitert eigentlich nur noch daran, dass mal
jemand einen Script zimmern muss, der die Syntax des alten und völlig
standalone gezimmerten Atmel-Assemblers in GNU-Syntax automatisch
überführt.  Wenn man einen solchen Script hat, kann man das Atmel-Teil
durch einen CLI-kompatiblen Wrapper ersetzen, der im Hintergrund den
gas aufruft.

Um den GNU-Assembler führt insgesamt ohnehin kein Weg herum, da der
Atmel-Assembler nicht in der Lage ist, verschiebliche Objekte zu
erzeugen, ganz zu schweigen von ELF-Dateien.  Das beides braucht man
aber, wenn man ihn als Backend für einen Compiler nehmen will.  Damit
ist die Weiterentwicklung des gas für den AVR praktisch garantiert und
zwingend notwendig (obwohl der GCC selbst durchaus auch andere
Assembler aufrufen könnte).

Ein Hinweis für den OP: .org ist außerhalb eines Absolutassemblers
kein sinnvoller Befehl.  Die Zuordnung der Speicheradressen erledigt
dort der Linker.  Zwar kann man auch Assemblerdateien komplett über
den Compiler als Frontend bearbeiten lassen, aber beim Linken sollte
man entweder den Linker mit avr-ld explizit selbst aufrufen, oder
du benutzt -nostartfiles, damit du deinen eigenen Startupcode
definieren kannst.  Im Moment wirft dein avr-gcc-Kommando sowohl den
Assembler (mit C-Präprozessor) als auch gleich danach den Linker an,
d. h. beide Schritte werden im Hintergrund durch ein einziges
Kommando ausgeführt.

Dein Beispiel ist leider schlecht formatiert, da du keine Code-
Markierungen benutzt hast.  Folgende Variante sollte funktionieren:
#include <avr/io.h>

.global main
main:                              ; zu 'main' wird nach Reset hingesprungen
        LDI R24, 0xFF
        OUT _SFR_IO_ADDR(DDRA), R24  ;port a als ausgabe setzten
        OUT _SFR_IO_ADDR(PORTA), R24 ;ale pins auf 1

        ldi     r16, 0b00000010      ; CS00 setzen: Teiler 8
        OUT _SFR_IO_ADDR(TCCR1B) , R16

        ldi     r16, 0b00000100      ; TOIE0: Interrupt bei Timer Overflow
        OUT _SFR_IO_ADDR(TIMSK), r16

        ldi r17,0x00
        sei

Hauptschleife:
        rjmp Hauptschleife

.global TIMER1_OVF_vect
TIMER1_OVF_vect:                      ; Timer 0 Overflow Handler
        OUT _SFR_IO_ADDR(PORTB), r17
        com     r17
        reti

Kommando:
avr-gcc -mmcu=atmega32 -o timer.elf timer.S

Damit wird der Startup-Code des C-Laufzeitsystems benutzt,
einschließlich deren Interruptvektortabelle.  Daher muss das
Hauptprogramm auch zwingend ein globales Symbol namens main
sein und die Interruptvektornamen müssen globale Symbole mit den
entsprechenden Makronamen aus <avr/io.h> sein.

Wenn du das nicht willst, sondern alles selbst unter Kontrolle haben
willst, dann wäre das hier die Variante:
#include <avr/io.h>

        jmp     Hauptprogramm
        jmp     INT0_vector
        jmp     INT1_vector
        jmp     TIMER2_COMP_vector
        jmp     TIMER2_OVF_vector
        jmp     TIMER1_CAPT_vector
        jmp     TIMER1_COMPA_vector
        jmp     TIMER1_COMPB_vector
        jmp     TIMER1_OVF_vector
        jmp     TIMER0_OVF_vector
        jmp     SPI_STC_vector
        jmp     USART_RXC_vector
        jmp     USART_UDRE_vector
        jmp     USART_TXC_vector
        jmp     ADC_vector
        jmp     EE_RDY_vector
        jmp     ANA_COMP_vector
        jmp     TWI_vector
        jmp     INT2_vector
        jmp     TIMER0_COMP_vector
        jmp     SPM_RDY_vector

Hauptprogramm:
        LDI R24, 0xFF
        OUT _SFR_IO_ADDR(DDRA), R24  ;port a als ausgabe setzten
        OUT _SFR_IO_ADDR(PORTA), R24 ;ale pins auf 1

        ldi     r16, 0b00000010      ; CS00 setzen: Teiler 8
        OUT _SFR_IO_ADDR(TCCR1B) , R16

        ldi     r16, 0b00000100      ; TOIE0: Interrupt bei Timer Overflow
        OUT _SFR_IO_ADDR(TIMSK), r16

        ldi r17,0x00
        sei

Hauptschleife:
        rjmp Hauptschleife

TIMER1_OVF_vector:                      ; Timer 0 Overflow Handler
        OUT _SFR_IO_ADDR(PORTB), r17
        com     r17
        reti

; leere Vektoren

INT0_vector:
INT1_vector:
TIMER2_COMP_vector:
TIMER2_OVF_vector:
TIMER1_CAPT_vector:
TIMER1_COMPA_vector:
TIMER1_COMPB_vector:
TIMER0_OVF_vector:
SPI_STC_vector:
USART_RXC_vector:
USART_UDRE_vector:
USART_TXC_vector:
ADC_vector:
EE_RDY_vector:
ANA_COMP_vector:
TWI_vector:
INT2_vector:
TIMER0_COMP_vector:
SPM_RDY_vector:
        rjmp    .-2

Kommando:
avr-gcc -mmcu=atmega32 -nostartfiles -o timer.elf timer.S

Hier bist du in der Namensvergabe völlig frei, dafür musst du die
Interruptvektortabelle selbst aufbauen.  Sinnvoller Weise baut man
sie komplett ein, wenngleich im Prinzip eine lückenhafte Definition
mit .org auch denkbar ist.  Die Namen müssen keinerlei Konvention
mehr unterliegen und auch nicht global sein.  Die fertige ELF-Datei
enthält exakt diesen Code und sonst nichts.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite

>Das Teil vom AVR Studio ist ein einfachster Absolutassembler, der zu
>nicht viel taugt.

So wie damals WinWord. Ist aber dennoch Defacto Standard im Bereich ASM.

MFG
Falk

Autor: ALB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke,
das war doch mal eine solide antwort. jetzt blinkts auch.

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ui,
da sag ich mal sry.
Habe noch nie GNU-Assembler gesehen, sah für mich aus wie ne Mischung 
aus C und ASM. Zumal du auch noch was von AVR-GCC-Tutorial geschrieben 
hast.

Schäm

Autor: ALB (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch ein kleiner nachtrag: der code den ich hier reingeschrieben habe 
und der von (dl8dtl) berichtigt wurde hat einen kleinen Fehler. in der 
3.letzten zeile muss porta anstatt portb hin. (achtung stolperstein für 
den nächsten anfänger der dieses problem hat)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner wrote:

> So wie damals WinWord. Ist aber dennoch Defacto Standard im Bereich ASM.

Winword? :-)

Naja, Mittelmäßigkeit setzt sich halt prima durch.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.