First one is when I use Uart1_Write_Char(val) to write a character it doesn't work, but if I use U1TXREG := val it works
Second of it, I get strange things from time to time, it's sending double characters, or sometimes it skips a few characters..
First I'll Include the unit, after that I'll include the Interrupts (note this is only done for Uart1, in my code I use a different unit to process Uart2)
The main program is only for a test, in the actual code I send large chunks to the Uart unit (aprox 200 chars each second on 38K4 Baud)
Can Somebody tell me why I get data errors from time to time?
Code: Select all
unit UartB;
uses DSPIC_aditional_string_library;
const
CL = #13+#10;
const rxbufsizeA : word = 100;
rxbufsizeB : word = 10;
txbufsizeA : word = 600;
txbufsizeB : word = 10;
var
RXheadA,RXheadB,
RXtailA,RXtailB : word;
RxbufA : string[rxbufsizeA];
RxbufB :string[rxbufsizeB];
RXbufemptyA,RXbufemptyB,
RXbfullA,RXbfullB : boolean
txbufA : string[txbufsizeA];
txbufB : string[txbufsizeB];
txheadA,txheadB,
txtailA,txtailB : word;
crflagA,crflagB : word;
TXbuffullA,TXbuffullB,
TXbufemptyA,TXbufemptyB : boolean;
CharCountA,CharCountB : word;
Uart1Sending,Uart2Sending : Boolean;
implementation
function InbufA:word;
begin
if txheadA = txtailA then result := 0;
if txheadA < txtailA then result := txheadA-txtailA;
if txheadA > txtailA then result := txtailA-txheadA;
end;
function InbufB:word;
begin
if txheadB = txtailB then result := 0;
if txheadB < txtailB then result := txheadB-txtailB;
if txheadB > txtailB then result := txtailB-txheadB;
end;
procedure Uart1_TX_Byte();
begin
// transmit everything in buffer
if (txheadA <> txtailA) then
begin
U1TXREG:=txbufA[txheadA];
//Uart1_Write_Char(txbufA[txheadA]); // THIS WON'T WORK!
inc(txheadA);
if txheadA > txbufsizeA then txheadA := 0;
if txheadA=txtailA then
begin
TXbufemptyA := true;
end;
end;
Uart1Sending := False;
end;
procedure Uart2_TX_Byte();
begin
if (InbufB = 0) then
begin
Uart2Sending := False;
exit;
end
else
begin
Uart2Sending := True;
end;
// transmit everything in buffer
U2TXREG:=txbufB[txheadB];
inc(txheadB);
TXbuffullB := false;
if txheadB > txbufsizeB then txheadB := 0;
if txheadB=txtailB then
begin
TXbufemptyB := true;
end;
end;
procedure Uart1_RX_Byte();
begin
RXbufA[RXtailA] := U1RXREG;
if RXbufA[RXtailA] = 0 then exit; // Filter 0 chars
inc(CharCountA);
if RXbufA[RXtailA] = 10 then
begin
inc(crflagA);
CharCountA := 0;
end;
inc(RXtailA);
if rxtailA > rxbufsizeA then rxtailA := 0;
RXbufemptyA := false;
if RXtailA = RXheadA then RXbfullA := true;
end;
procedure Uart2_RX_Byte();
begin
RXbufB[RXtailB] := U2RXREG;
if RXbufB[RXtailB] = 0 then exit; // Filter 0 chars
inc(CharCountB);
if RXbufB[RXtailB] = 10 then
begin
inc(crflagB);
CharCountB := 0;
end;
inc(RXtailB);
if rxtailB > rxbufsizeB then rxtailB := 0;
RXbufemptyB := false;
if RXtailB = RXheadB then RXbfullB := true;
end;
function Uart1_Read_Char_ :byte; // read a byte from the input-FIFO
var k : byte;
begin
k := 0;
if RXbufemptyA = false then
begin
k := RXbufA[RXheadA];
RXbufA[RXheadA] := 0; // destructive read
inc(RXheadA);
if RXheadA > RXbufsizeA then RXheadA := 0;
if RXheadA = RXtailA then RXbufemptyA := true else RXbfullA := false;
end;
result := k;
end;
function Uart2_Read_Char_ :byte; // read a byte from the input-FIFO
var k : byte;
begin
k := 0;
if RXbufemptyB = false then
begin
k := RXbufB[RXheadB];
RXbufB[RXheadB] := 0; // destructive read
inc(RXheadB);
if RXheadB > RXbufsizeB then RXheadB := 0;
if RXheadB = RXtailB then RXbufemptyB := true else RXbfullB := false;
end;
result := k;
end;
procedure Uart1_Write_CharI_(k : Char); // write a byte to the TX-FIFO
begin
TXbufA[TXtailA] := k;
inc(TXtailA);
if txtailA > txbufsizeA then txtailA := 0;
if TXtailA=TXheadA then txbuffullA := true; // notify buffer full
txbufemptyA := false;
end;
procedure Uart1_Write_Char_(k : Char);
begin
Uart1_Write_CharI_(k);
if Uart1Sending = False then Uart1_TX_Byte(); // Start sending after the CRLF
end;
procedure Uart2_Write_CharI_(k : Char); // write a byte to the TX-FIFO
begin
TXbufB[txtailB] := k;
inc(txtailB);
if txtailB > txbufsizeB then txtailB := 0;
if TXtailB=TXheadB then txbuffullB := true; // notify buffer full
txbufemptyB := false;
end;
procedure Uart2_Write_Char_(k : Char);
begin
Uart2_Write_CharI_(k);
if Uart2Sending = False then Uart2_TX_Byte(); // Start sending after the CRLF
end;
procedure Uart1_Writeln_(var s : string[txbufsizeA]);
var i : word;
begin
i := 0;
while s[i] <> 0 do
begin
if (Com1TXInt = True) then
Uart1_Write_CharI_(s[i])
else
Uart1_Write_Char(s[i]);
inc(i);
end;
if (Uart2Sending = False) and (Com1TXInt = True) then
begin
ClearBit(IFS0,12); //Clear TXInt Uart 1
Uart1_TX_Byte(); // Start sending after the CRLF
end;
end;
procedure Uart1_Writeln(var s : string[txbufsizeA]);
begin
str_cat(s,CL);
Uart1_Writeln_(s);
end;
procedure Uart2_Writeln_(var s : string[txbufsizeB]);
var i : word;
begin
i := 0;
while s[i] <> 0 do
begin
if (Com2TXInt = True) then
Uart2_Write_CharI_(s[i])
else
Uart2_Write_Char(s[i]);
inc(i);
end;
//if (Uart1Sending = False) and (Com2TXInt = True) then
if Testbit(U2STA,8) = 1 then
begin
ClearBit(IFS1,15); //Clear TXInt Uart 2
Uart2_TX_Byte(); // Start sending after the CRLF
end;
end;
procedure Uart2_Writeln(var s : string[txbufsizeB]);
begin
str_cat(s,CL);
Uart2_Writeln_(s);
end;
procedure Uart1_Readln(var s: string[txbufsizeA];var ok:boolean);
var i : word;
dat : byte;
begin
i:=0;
dat:=0;
if crflagA > 0 then
begin
while ((dat <> 10) and (RXbufemptyA = False)) do
begin
dat:=Uart1_Read_Char_();
if dat > 0 then
begin
s[i]:=dat;
inc(i);
end;
end;
dec(crflagA);
if RXbufemptyA = true then crflagA:=0;
s[i]:=#0;
ok:=True;
end
else
begin
s[0]:=#0;
ok:=False;
end;
end;
procedure Uart2_Readln(var s: string[txbufsizeB];var ok:boolean);
var i : word;
dat: byte;
begin
i:=0;
dat:=0;
if crflagB > 0 then
begin
while ((dat <> 10) and (RXbufemptyB = False)) do
begin
dat:=Uart2_Read_Char_();
if dat > 0 then
begin
s[i]:=dat;
inc(i);
end;
end;
dec(crflagB);
if RXbufemptyB = true then crflagB:=0;
s[i]:=#0;
ok:=True;
end
else
begin
s[0]:=#0;
ok:=False;
end;
end;
procedure Uart_Init_();
begin
memset(@RXbufA,0,rxbufsizeA);
memset(@TXbufA,0,txbufsizeA);
memset(@RXbufB,0,rxbufsizeB);
memset(@TXbufB,0,txbufsizeB);
RXheadA := 0;
RXtailA := 0;
TXtailA := 0;
TXheadA := 0;
CharCountA := 0;
CharCountB := 0;
RXbfullA := false;
RXbufemptyA := true;
TXbuffullA := false;
TXbufemptyA := true;
crflagA := 0;
RXheadB := 0;
RXtailB := 0;
TXtailB := 0;
TXheadB := 0;
RXbfullB := false;
RXbufemptyB := true;
TXbuffullB := false;
TXbufemptyB := true;
crflagB := 0;
Uart1Sending := False;
Uart2Sending := False;
// Int register voor 24FJ
IFS0.11 := 0; //Clear RXInt Uart 1
IEC0.11 := 1; // Enable RXInt Uart 1
IFS1.14 := 0; //Clear RXInt Uart 2
IEC1.14 := 1; // Enable RXInt Uart 2
IFS0.12 := 0; //Clear TXInt Uart 1
if (Com1TXInt = True) then
IEC0.12 := 1; // Enable TXInt Uart 1
IFS1.15 := 0; //Clear TXInt Uart 2
if (Com2TXInt = True) then
IEC1.15 := 1; // Enable TXInt Uart 2
ClearBit(U1STA,1); //Clear overflow
ClearBit(U2STA,1); //Clear overflow
end;
end.
Code: Select all
procedure Uart1RXInt; org $2A;
begin
ClearBit(IFS0,11); //Clear RXInt Uart 1
Uart1_RX_Byte();
end;
procedure Uart1TXInt; org $2C;
begin
ClearBit(IFS0,12); //Clear TXInt Uart 1
Uart1_TX_Byte();
end;
begin
// Int register voor 24FJ
IFS0.11 := 0; //Clear RXInt Uart 1
IEC0.11 := 1; // Enable RXInt Uart 1
IFS0.12 := 0; //Clear TXInt Uart 1
IEC0.12 := 1; // Enable TXInt Uart 1
IFS1.14 := 0; //Clear RXInt Uart 2
IEC1.14 := 1; // Enable RXInt Uart 2
IFS1.15 := 0; //Clear TXInt Uart 2
IEC1.15 := 1; // Enable TXInt Uart 2
while True do
begin
Uart1_Writeln('Test and a lot more');
delay_ms(10);
end;
end;
end.