mikrocontroller.net

Forum: Compiler & IDEs Interrupt-UART


Autor: Ludwig Meyerhoff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich will über die UART meines kleinen AVR 90S2313er an den PC senden.
Das klappt auch, wenn ich "polled" sende.
Ich wollte aber gerne interruptgesteuert senden.
Das wollte ich über die UDRE-Interrupt machen.

Wenn ich nun einen sei() mache, mache, führt der Controller einen Reset
aus.

Verschiebe ich den sei() nach vor der Endlosschleife, wird der Text
übertragen - unendlich oft (RESET halt!).



#define _AVR_AT90S2313_ 1
#define BUFLEN 40
#include <avr/io.h>
#include <avr/interrupt.h>

char obuf[BUFLEN + 1];
char ibuf[BUFLEN + 1];
unsigned int BufCount = 0;

ISR(UART_UDRE_vect)
{
        if( obuf[BufCount] != 0 )
                if( USR & 0x20 )
                        UDR     = obuf[BufCount++];
}

int main (void)
{
char c = 0;
        UBRR    = 23;   // 9600bps bei 3.6864 MHz (Datenblatt)
        UCR     = 0x20 + 0x08;   // UDRIE + TXEN
        DDRB    = 0xff;

        PORTB   = UCR;   // Ist 0x2a: UDRIE + TXEN + RXB8
        sei();   // hier wird ein Reset ausgeführt!

        obuf[0] = 'D';
        obuf[1] = 'a';
        obuf[2] = 's';
        obuf[3] = ' ';
        obuf[4] = 'k';
        obuf[5] = 'l';
        obuf[6] = 'a';
        obuf[7] = 'p';
        obuf[8] = 'p';
        obuf[9] = 't';
        obuf[10]        = '!';
        obuf[11]        = '\n';
        obuf[12]        = '\r';
        obuf[13]        = '\0';
        while( obuf[c] != 0)
                if( USR & 0x20 )
                        UDR     = obuf[c++];

        BufCount        = 0;

        while(1);
return(0);
}

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

Bewertung
0 lesenswert
nicht lesenswert
UDRE-Interrupt ist eine gute Idee, aber den musst du halt wieder
abschalten, wenn du nichts mehr zu senden hast: ansonsten ist
das UART data register immer `empty', der Interrupt triggert also
immer wieder.

> #define _AVR_AT90S2313_ 1

Aua!  Finger weg!

Makros, die mit zwei Unterstrichen beginnen, definierst du bitte
nie selbst, es sei denn, die zugehörige Dokumentation würde
dich an irgendeiner Stelle ausdrücklich dazu auffordern, das zu
tun.

Wenn dein MCU type nicht definiert ist (-mmcu=at90s2313), brauchst
du dich auch nicht wundern, wenn Compiler und Linker Mist machen.

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

Bewertung
0 lesenswert
nicht lesenswert
Einen AT90S2313 habe ich gerade nicht da, nur einen ATtiny2313.
Habe dein Progrämmchen ein wenig umgeschrieben (andere Register-
namen, anderer Name des Interruptvektors, Register symbolisch
statt numerisch benannt, UDRIE am Ende des Strings zurückgesetzt),
das funktioniert alles.  Allerdings darfst du die Interrupts
natürlich erst gestatten (entweder sei oder UDRIE), nachdem im
Puffer etwas drin steht.  Sonst feuert der Interrupt mitten in
deine Füllroutine rein.

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

Bewertung
0 lesenswert
nicht lesenswert
Wenn mich nicht alles täuscht, sollte das Hexfile sogar AT90S2313-
kompatibel sein:

:1000000012C02AC029C028C027C026C025C024C0CD
:1000100024C022C021C020C01FC01EC01DC01CC0E3
:100020001BC01AC019C011241FBECFEDCDBF10E0F8
:10003000A0E6B0E0EEE2F1E003C0C89531960D9283
:10004000A036B107D1F710E0A0E6B0E001C01D92E4
:10005000A63BB107E1F734C0D3CF1F920F920FB682
:100060000F9211242F933F938F939F93EF93FF93BE
:100070008091600090916100F92FE82FE357FF4FC6
:10008000E081EE2331F0ECB901969093610080930A
:100090006000209160003091610080916200909139
:1000A00063002817390709F45598FF91EF919F9144
:1000B0008F913F912F910F900FBE0F901F90189529
:1000C000CFEDD0E0DEBFCDBF87E189B988E28AB944
:1000D00084E480938D0091E690938E0083E7809373
:1000E0008F0080E2809390008BE6809391008CE6F5
:1000F000809392009093930080E780939400809384
:10010000950084E78093960081E2809397008AE0CF
:10011000809398008DE08093990010929A008DE072
:0E01200090E090936300809362007894FFCF8C
:00000001FF

Autor: Ludwig Meyerhoff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Danke Jörg!
Ich hatte das Makefile von einem anderen Projekt übernommen, dem
"uisp" den richtigen AVR mitgeteilt, aber nicht dem Compiler ...

Man sollte nicht den Maschienencode für einen 8515er auf einem 2313er
aufspielen ...

und ich wundere mich, wieso im entsprechenden .s file er immer
Interrupt-Vektor 10 statt 8 benutzt - sofern ich das File richtig
interpretiert habe!



Saluti!

Ludwig

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.