Forum: Compiler & IDEs Interrupt-UART


von Ludwig Meyerhoff (Gast)


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);
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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

von Ludwig Meyerhoff (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.