mikrocontroller.net

Forum: Compiler & IDEs Interruptproblem ISR(USART_RXC_vect)


Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe folgendes Problem:
Ich möchte empfangene Zeichen wieder zurücksenden. Das ganze soll über
einen Interrupt - wenn Zeichen empfangen - erfolgen.

Sobald der µC ein Zeichen empfängt sendet er wahllos Zeichen in einer
Endlosschleife zurück.

Ich muss erwähnen, dass ich gerade von Assembler auf GCC umsteige.
Also kein GCC-Profi

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

ISR(USART_RXC_vect)
{
  unsigned char Zeichen;
  Zeichen = UDR;
  while (!(UCSRA & (1<<UDRE)));     // warten bis Senden moeglich
  UDR = Zeichen;                          // sende Zeichen
}


int main(void)
{
  UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);    // UART TX,RX und INTRx
einschalten
  UBRRH  = 0;                                // Highbyte ist 0
  UBRRL  = 51;                              // Lowbyte ist 51 ( dezimal
)
  while (!(UCSRA & (1<<UDRE)));     // warten bis Senden moeglich
  UDR = '38';                          // sende Zeichen
  sei();
  while(1)
  {
      /*Endlosschleife*/
  }
}

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probiere es mal so:
int main(void)
{
  UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);    // UART TX,RX und INTRx
einschalten
  UBRRH  = 0;                                // Highbyte ist 0
  UBRRL  = 51;                              // Lowbyte ist 51 (
dezimal
  sei();
  while (!(UCSRA & (1<<UDRE)));     // warten bis Senden moeglich
      UDR = '38';                          // sende Zeichen
  while(1) /*Endlosschleife*/
  {
  }
}

So müsste er einmal am anfang die '38'schicken und dann immer das
zeichen schicken was er empfangen hat.

Das mit dem wahllos senden müsste man allerdings anders gestalten.

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso was ich noch fragen wollte!

Hat denn dein Compiler nicht gemeckert ?

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal,

aber was soll daran besser sein, wenn ich vor Senden der '38' die
Globalen Interrupts zulasse?

Mit meinem Programm(s.o.) sendet er wahllos Zeichen sobald er etwas
empfängt. Zudem ist das erste Zeichen was er antwortet, nicht das
gleiche welcher er über RxD erhalten hat.

Mit deiner Änderung sendet er kein Zeichen zurück.

Zudem habe ich einen Kontrollport(PortB) aktiviert. Wenn er in
Interuptroutine springen soll schaltet er die LED um.
-> Macht er nicht, d.h er springt nicht in die Interruptroutine!

Aber warum?

Nochmal mein Programm:

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

ISR(USART_RXC_vect)
{
  PORTB=0xF0;
  register unsigned char akku;
  akku = UDR;
  while (!(UCSRA & (1<<UDRE)));     // warten bis Senden moeglich
  UDR = akku;                          // sende Zeichen
}


int main(void)
{
  UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);    // UART TX,RX und INTRx
einschalten
  UBRRH  = 0;                                // Highbyte ist 0
  UBRRL  = 51;                              // Lowbyte ist 51 ( dezimal
)
  DDRB=0xFF;
  PORTB=0x0F;
  while (!(UCSRA & (1<<UDRE)));     // warten bis Senden moeglich
  UDR = '38';                          // sende Zeichen
  sei();
  while(1)
  {
      /*Endlosschleife*/
  }
}

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Build succeeded with 0 Warnings..."

Ich denke mal das ist in Ordnung.

Warum meinst du er solle meckern?

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>UDR = '38';
Wie soll das gehen?

'' (Hochkommata) beschreiben einen Character (einzelnes Zeichen).
38 sind aber zwei Zeichen.

Wenn, dann müsste es
 UDR = "38";
heissen.

Das wird aber auch nicht funktionieren, da man immer nur ein Zeichen
(acht bit / ein Byte) zur Zeit ins UDR schreiben kann.
Vielleicht meinst du ja UDR = 38; Damit wird dann die Dezimalzahl 38
ins UDR geschrieben. Das dürfte laut ASCII ein "&" sein.

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe Dein Programm mit einem Mega16 getestet und es funktioniert
einwandfrei.

Eine Warnung gibt der Compiler bei UDR = '38'; , da nur ein Zeichen
angegeben werden darf. Dafür müssen aber mit der Compileroption -Wall
alle Warnungen ausgegeben werden.
Besser UDR = 38; entspricht dem Zeichen '&'.

Stimmen denn die Baudraten überein?

Gruß Sven

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Außerdem fügst Du die interrupt.h und signal.h ein, was auf eine ältere
Compilerversion schließen lässt.
Die Interruptfunktion implementierst Du aber mit ISR, was in der
aktuelle Compilerversion benutzt werden muss.

Die Implementierung der ISR muss natürlich der Version des
angewendetetn Compilers entsprechen.

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann 0x38 oder '38' schreiben und erhalte in meinem
Terminalprogramm das gleiche Ergebnis.
Steht das Terminal auf HEX-Anzeige erhalte ich jedesmal 38 und analog
erhalte ich bei ASCII-Anzeige die 8.

Aber das ist ja nicht mein Problem!!!
Mein Problem ist, er springt nicht in die Interruptroutine
ISR(USART_RXC_vect).

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne blöde Frage:
Welchen Compiler benutzt du und in welcher Form.

Das von dir gepostete geht definitiv nicht ohne
Warnings durch den Compiler.

(Ach ja: welche variablen in Register abgelegt werden sollen,
überlässt du besser dem Compiler. Streich am besten das
Schlüsselwort 'register' aus deinem C-Sprachschatz. Im besten
Fall ignoriert es der Compiler sowieso, im schlimmsten Fall
bewirkt es das Gegenteil von dem was du erreichen möchtest.)

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze:
AVR Studio 4.12.490 SP3
GUI Version 4,12,0,490

Baudrate auf 9600-8-N-1 gestellt
Signal.h hatte ich nur implementiert, wegen test von SIGNAL(UART...).
Habe ich schon wieder entfernt.

>Die Implementierung der ISR muss natürlich der Version des
angewendetetn Compilers entsprechen.

Wie soll ich das verstehen. GCC ist Neuland für mich. Ich habe die
ganze Zeit in Assembler entwickelt. Als Info nutze ich das Tutorial
dieser Homepage.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was.
Für welchen µC soll das eigentlich sein?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UDR = '38'  // '38' sind zwei Zeichen, nämmlich '3' und '8'

#include <avr/iom8515.h>  // brauchts Du nicht zu includen.

Üblicherweise wird die CPU im makefile definiert, dann werden mit dem
<avr/io.h> automatisch die richtigen CPU-Definitionen reingehohlt!

Gruss von mir

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir den WinAVR-20060421 installiert.

Als µC nutze ich den ATMega16 mit einem 8MHz internen Takt

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche Version vom WinAvr hast du installiert?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ATMega16

Und warum includest du dann
#include <avr/iom8515.h>

Du hast keinen mega8515.

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry ich meinte Atmega8515,

ich versuche gerade dass ganze auf einem Atmega16 zu testen, denn
vielleicht ist der 8515 defekt.


WinAVR-20060421 ist das nicht die aktuellste Version?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> WinAVR-20060421 ist das nicht die aktuellste Version?
Doch ist sie.


Wenn ich allerdings bei mir mega8515 einstelle, dann
sagt mir der Compiler:

> ../UART.c:6: warning: `USART_RXC_vect' appears to be a misspelled
> signal handler

Liest du eigentlich die Warnungen vom Compiler?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und schmeiss den Include

#include <avr/iom8515.h>

raus. Der Prozessortyp wird im AVR-Studio unter
'Project' - 'Configuration Options' eingestellt.
Wenn du ihn nachträglich änderst auch den Punkt 'Debug' -
'Select Platform and Device' nicht vergessen.

Du inkludierst immer nur avr/io.h

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe jetzt diese Meldung auch.

Das Fenster zeigt bei mir nur 5 Zeilen an und wenn die Meldung "Build
succeeded with 0 Warnings..." angezeigt wird, gehe ich davon aus, dass
keine Fehler vorhanden sind.
Seltsam ist nur, wenn ich es ein zweites mal kompiliere erscheint diese
Warnung nicht mehr.

Habe die Schreibweise IST(USART_RXD_VECT) in ...vect) und es
funktioniert.

Danke an Alle die mir geholfen haben

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich aber interrupt.h entferne erhalte ich Fehler, wegen sei().

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

Bewertung
0 lesenswert
nicht lesenswert
Du sollst auch <avr/signal.h> entfernen, nicht <avr/interrupt.h>.

Autor: Daniel M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon klar. Habe ich so auch gemacht.

Anderes Problem:
Kann ich in der Interruptroutine ein Funktion starten?
In der Zeit sollen auch keine anderen Interrupts aktiviert werden.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sicher kannst du.
Eine Interrupt Funktion ist auch nur eine Funktion
wie jede andere, nur dass sie halt 'von der Hardware
aufgerufen wird' und nicht von deinem Program selbst.

Ob du das machen sollst, ist eine andere Frage:
Alte Grundregel: Interrupt Funktionen sollten so schnell
wie möglich durchlaufen. D.h. wenn deine Funktion viel
Arbeit zu erledigne hat, dann ist es keine gute Idee sie
aufzurufen.

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

Bewertung
0 lesenswert
nicht lesenswert
Kommt hinzu, dass der Compiler dann die worst-case-Annahme macht
und alle Register, die von dieser Funktion laut ABI zerstört
werden könnten vorher retten muss.  Ausnahme: die Funktion ist
static deklariert und ist so kurz (oder "static inline"), dass
sie vom Compiler gleich inline erweitert wird.

Autor: Marian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Daniel: Jo sorry, sehe jetzt auch das es keinen anderen Sinn macht was
ich schrieb. Ich hatte die eine Klammer falsch interpretiert und sie
eigentlich nur rausgenommen wobei die ja nur im Kommentar stand (*an
den kopf hau*)

Aber wieso sendet er bei dir verschiedene Zeichen? Du schreibst doch
dein empfangenes Zeichen in die Variable Zeichen und schreibst sie
danach wieder ins UDR. D.h. er sendet das was du ihm vorher schickst
oder nich?

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.