Hallo,
ich habe festgestellt, das Serout den globalen Interrupt freigibt und dafür ein Beispiel (program seroutTST) angehängt (siehe code unten und Bild)
Ich finde das für den folgenden Fall störend. Wenn ich ganz sicher sein möchte, dass der drive-enable-pin meines RS485 Transceivers unmittelbar nach dem Senden der Daten wieder zurückgenommen wird, muss ich kurzeitig die Interrupts sperren und erst nach Aufruf von SetSerEnable wieder freigeben, oder? Der Serport arbeitet im Interrupt Modus.
// Codefragment
DisableInts;
SetSerEnable(USARTC0,true);
SerOutC0($AB); // buffer füllen, aber noch nicht senden
SetSerEnable(USARTC0,false);
EnableIntsX; // erst nach Freigabe des Interrupts beginn UART das Senden
Da aber Serout den globalen Interrupt eigenwillig freigibt, ist dies nicht 100% sicher gestellt.
Andere Interrupts könnten die Ausführung von SetSerEnable(USARTC0,false) hinauszögern.
Für den XMEGA hätte ich einen Workaround:
// Codefragment, ungetestet
DisableInts;
tmp := PMICCTRL;
PMICCTRL := PMICCTRL and not $07; // sperrt Interrupts, clear HILVLEN, MEDLVLEN und LOLVLEN
SerOutC0($AA);
SREG := SREG or $80;
PMICCTRL := PMICCTRL or ( tmp and $07); // HILVLEN, MEDLVLEN und LOLVLEN wieder hesrtellen
Gäbe es auch einen für ATMEGA?
Ich möchte wissen, ob das Aktivieren des globalen Interrupts durch Serout wirklich gewollt ist
und andere Leser darauf aufmerksam machen.
program seroutTST; // f_cpu = 32 MHz
{$W+}
Device = xmega128A1U, VCC = 3.3;
Define_Fuses
Override_Fuses;
NoteBook = A;
COMport = USB;
FuseBits5 = [BODLEVEL1, BODLEVEL2, BODACT0]; // BOD=2.8V if USB variant
ProgFuses = true;
ProgEEprom = true;
Import SysTick, SerPortC0;
Define
OSCtype = extXTAL=8000000, PLLmul=4, prescA=1, prescB=1, prescC=1, faildet;
SysTick = 10;
StackSize = 256, iData;
FrameSize = 256, iData;
SerPortC0 = 57600;
RxBufferC0 = 128, iData;
TxBufferC0 = 128, iData;
SerCtrlC0 = onSerTxComplete_C0;
//SerCtrlC0 = PORTC, 4, positive;
implementation
{$IDATA}
{-------------------------------------------------------------------------------
Main Program
-------------------------------------------------------------------------------}
var
sregDavor, sregDanach : byte;
begin
EnableInts($87);
DisableInts;
sregDavor := SREG;
SeroutC0($45);
sregDanach := SREG; // Serout hat globalen Interrupt eingeschaltet!
debug_Break; //
EnableIntsX; // kleiner Fehler in dere Doku auf Seite 171, da steht EnableInts(x)
end seroutTST.
ich habe festgestellt, das Serout den globalen Interrupt freigibt und dafür ein Beispiel (program seroutTST) angehängt (siehe code unten und Bild)
Ich finde das für den folgenden Fall störend. Wenn ich ganz sicher sein möchte, dass der drive-enable-pin meines RS485 Transceivers unmittelbar nach dem Senden der Daten wieder zurückgenommen wird, muss ich kurzeitig die Interrupts sperren und erst nach Aufruf von SetSerEnable wieder freigeben, oder? Der Serport arbeitet im Interrupt Modus.
Code
// Codefragment
DisableInts;
SetSerEnable(USARTC0,true);
SerOutC0($AB); // buffer füllen, aber noch nicht senden
SetSerEnable(USARTC0,false);
EnableIntsX; // erst nach Freigabe des Interrupts beginn UART das Senden
Da aber Serout den globalen Interrupt eigenwillig freigibt, ist dies nicht 100% sicher gestellt.
Andere Interrupts könnten die Ausführung von SetSerEnable(USARTC0,false) hinauszögern.
Für den XMEGA hätte ich einen Workaround:
Code
// Codefragment, ungetestet
DisableInts;
tmp := PMICCTRL;
PMICCTRL := PMICCTRL and not $07; // sperrt Interrupts, clear HILVLEN, MEDLVLEN und LOLVLEN
SerOutC0($AA);
SREG := SREG or $80;
PMICCTRL := PMICCTRL or ( tmp and $07); // HILVLEN, MEDLVLEN und LOLVLEN wieder hesrtellen
Gäbe es auch einen für ATMEGA?
Ich möchte wissen, ob das Aktivieren des globalen Interrupts durch Serout wirklich gewollt ist
und andere Leser darauf aufmerksam machen.
Code
program seroutTST; // f_cpu = 32 MHz
{$W+}
Device = xmega128A1U, VCC = 3.3;
Define_Fuses
Override_Fuses;
NoteBook = A;
COMport = USB;
FuseBits5 = [BODLEVEL1, BODLEVEL2, BODACT0]; // BOD=2.8V if USB variant
ProgFuses = true;
ProgEEprom = true;
Import SysTick, SerPortC0;
Define
OSCtype = extXTAL=8000000, PLLmul=4, prescA=1, prescB=1, prescC=1, faildet;
SysTick = 10;
StackSize = 256, iData;
FrameSize = 256, iData;
SerPortC0 = 57600;
RxBufferC0 = 128, iData;
TxBufferC0 = 128, iData;
SerCtrlC0 = onSerTxComplete_C0;
//SerCtrlC0 = PORTC, 4, positive;
implementation
{$IDATA}
{-------------------------------------------------------------------------------
Main Program
-------------------------------------------------------------------------------}
var
sregDavor, sregDanach : byte;
begin
EnableInts($87);
DisableInts;
sregDavor := SREG;
SeroutC0($45);
sregDanach := SREG; // Serout hat globalen Interrupt eingeschaltet!
debug_Break; //
EnableIntsX; // kleiner Fehler in dere Doku auf Seite 171, da steht EnableInts(x)
end seroutTST.
Attachments
Filename: | seroutTST.png |
Filesize: | 58.29 KB |
Title: | seroutTST |
Download counter: | 117 |