So far, so good. Took a brief look @ mE UART functions and as they work with WORDs instead of BYTEs.
Nothing to be afraid of, I though. Configured Peripheral Pins, configured UARTs (both), created Interrupts for UART1 and made my main loop to send through UART2 whatever I got on U1 interrupt. Here's my code:
Code: Select all
program Test_UART;
{ Declarations section }
procedure Setup;
begin
ANSELA:=$00; //all pins Digital
ANSELB:=$00; //all pins Digital
ANSELC:=$00; //all pins Digital
TRISA:=%01000010000;
TRISB:=%0000010111000111;
TRISC:=%0101110000;
IC1CON:=0;
IC2CON:=0;
IC3CON:=0;
IC4CON:=0;
IC5CON:=0;
INTCON.INT0EP:=0; //interrupt on falling edge
INTCON.INT1EP:=0; //interrupt on falling edge
INTCON.INT2EP:=0; //interrupt on falling edge
INTCON.INT3EP:=0; //interrupt on falling edge
INTCON.INT4EP:=0; //interrupt on falling edge
Delay_10ms;
Unlock_IOLOCK;
//
PPS_Mapping_NoLock(_RPA4, _INPUT, _U1RX);
PPS_Mapping_NoLock(_RPB4, _OUTPUT, _U1TX);
PPS_Mapping_NoLock(_RPB8, _INPUT, _U2RX);
PPS_Mapping_NoLock(_RPB9, _OUTPUT, _U2TX);
//
PPS_Mapping_NoLock(_RPA8, _OUTPUT, _SDO1); //SPI1 mapping - Data In (SI)
PPS_Mapping_NoLock(_RPA9, _INPUT, _SDI1); //SPI1 mapping - Data Out (SO)
PPS_Mapping_NoLock(_RPB13, _INPUT, _SDI2); //SPI1 mapping - Data In (SI)
PPS_Mapping_NoLock(_RPB5, _OUTPUT, _SDO2); //SPI1 mapping - Data Out (SO)
Lock_IOLOCK;
Delay_10ms;
UART1_Init(115200);
UART2_Init(115200);
buf_counter:=0;
U1RXIE_bit:=0;
U1TXIE_bit:=0;
U1RXIF_bit:=0;
U1TXIF_bit:=0;
U1IP0_bit := 1; // Set UART1 interrupt
U1IP1_bit := 0; // Set interrupt priorities
U1IP2_bit := 1; // Set UART1 interrupt to level 5
U2RXIE_bit:=0;
U2TXIE_bit:=0;
U2RXIF_bit:=0;
U2TXIF_bit:=0;
U2IP0_bit := 1; // Set UART2 interrupt
U2IP1_bit := 1; // Set interrupt priorities
U2IP2_bit := 1; // Set UART2 interrupt to level 7
Delay_10ms;
URXISEL0_bit:=0; //generate interrupt on EVERY char instead of 3/4 or full buffer
URXISEL1_bit:=0; //generate interrupt on EVERY char instead of 3/4 or full buffer
U1RXIE_bit:=1;
// U2RXIE_bit:=1;
EnableInterrupts;
end;
procedure interrupt_UART1_Receive; iv IVT_UART_1; ilevel 5; ics ICS_AUTO;
var b2_, b3_: boolean;
w: word;
begin
U1RXIF_bit:=0;
if (U1STA.OERR <> 0) or (U1STA.FERR <> 0) or (U1STA.PERR <> 0) then
begin
OERR_bit:=0;
end
else
// if RIDLE_bit <> 0 then
begin
w:=UART1_Read;
buf_rcv[buf_counter]:=Lo(w); //UART1_Read;
Inc(buf_counter);
if buf_counter = 26 then
begin
b2_:=buf_rcv[0] = packet_StartByte;
b3_:=buf_rcv[buf_counter - 1] = packet_EndByte;
if (b2_) and //packet_StartByte available?
(b3_) then //packet_EndByte avavilable?
begin
T1IE_bit:=0;
UART1_Ready:=tcpsOK;
end
else
begin
T1IE_bit:=0;
UART1_Ready:=tcpsInvalidRequest;
end;
end;
end;
end;
procedure Zero_UART1_Variables;
begin
memset(@buf_snd[0], 0, buf_length);
memset(@buf_rcv[0], 0, buf_length);
UART1_Ready:=-1;
buf_counter:=0;
end;
var I: Integer;
w: word;
begin
Setup;
Zero_UART1_Variables;
while True do
begin
if UART1_Ready <> -1 then
begin
for I:=0 to buf_counter - 1 do
begin
w:=buf_rcv[I] and $0F;
U2TXREG:=w;
//UART2_Write(buf_rcv[I]);
end;
UART1_Ready:=-1;
Zero_UART1_Variables;
end;
end;
end.
- UART1 is connected to PC hardware serial port, from which I send packet bytes
- UART2 is connected to another PC hardware serial port, from which I read the bytes, sent on UART1
What I want to point is that data, received from PIC's UART2 is WORD instead of bytes, i.e. every byte from packet has a MSB of 0x00 (in most cases, but sometimes MSB is different/random value). No breaks/errors are generated during reception, so I wouldn't blame UART baudrate for that. I tried to receive and send mE functions but they generate the same result. Read through PDFs and forums, nowhere is mentioned anything regarding my problem. Please, take a look and check if I'm missing anything , either in configuration or in sending/receiving procedures, although I used almost the same mechanism for PIC16 and PIC18 and had no problems there...