Uart1 and Uart2 problems

General discussion on mikroBasic PRO for PIC.
Post Reply
Author
Message
dangerous
Posts: 748
Joined: 08 Mar 2005 16:06
Location: Nottinghamshire, UK

Uart1 and Uart2 problems

#1 Post by dangerous » 18 May 2023 09:05

Hi,
Sorry for the long post but this is driving me crazy!I am using a P18F45K22 running at 64MHz int osc. Windows 10 Fully updated, EasyPIC v7, MB v7.6.0. I have aslo tried a P18F44K22 and a couple of other 45K22s so I think I can rule out faulty ICs.

I would like to use both uarts, Uart1 to read data from a PC and Uart2 to write data out to a decoder unit byte by byte, which is what I need to do, as it is received. Same baud rate in and out.
I have done this before using a circular buffer to save a known number of sucessive bytes of received data before processing it and re tranmitting, but simply polling for Rx a byte on Uart 1 and send it to Uart 2 always writes to Uart 1.

I have tried various ways to get round this but it always seems to write to Uart 1.

The startup message did not write correctly at first and gave two copies of "Ready" to Uart 1 until I added the " UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)" and "UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle)" lines at 57 & 61. The message is then sent correctly. I added the same to the byte tx routines for UART1 & 2 but that made no difference.(lines 30 & 35).
I tried writing directly to UART2 TXREG, but still output was to Uart1.

EasyPic v7, Uart1 is on COM3 via a USB to RS232(TTL level) converter to/from the PC and Uart2 is on the in built USB Uart on Com 11. I am using the MB Uart tool on COM3 to read and write to UART1, and Realterm capture program to monitor Uart 2.

The startup message is fine now but sending a simple byte by byte as typing or a string to UART1 always writes back to Uart1 but never to Uart2. It appears that text writes to UART2 are fine, but bytes or chars are not. Of course text is read from an array of bytes, not as a single byte, but I cannot see what the difference is, as the same basic write byte routine is just called repeatedly until the array has all been sent.

Code is based on the Uart1 read/write example supplied with MB V7 with writes to Uart2 added.

Code: Select all

' *
' * Project name:
'     UART (Simple usage of UART module library functions)
' * Copyright:
'     (c) Mikroelektronika, 2011.
' * Revision History:
'     20110929:
'       - initial release (FJ);
' * Description:
'     This code demonstrates how to use uart library routines. Upon receiving
'     data via RS232, MCU immediately sends it back to the sender.
' * Test configuration:
'     MCU:             PIC18F45K22
'                      http://ww1.microchip.com/downloads/en/DeviceDoc/40001412G.pdf
'     Dev.Board:       EasyPIC7 - ac:UART
'                      http://www.mikroe.com/easypic/
'     **Oscillator:      ** Int HS PLL on = 64MHz.
       ' ** Was :HS-PLL 32.0000 MHz, 8.0000 MHz Crystal
'     Ext. Modules:    None.
'     SW:              mikroBasic PRO for PIC
'                      http://www.mikroe.com/mikrobasic/pic/
' * NOTES:
'     - Turn on RX and TX UART switches (SW1.1 and SW2.1). (board specific)
'     - Put RX and TX UART jumpers (J3 and J4) in RS-232 or USB position,
'       depending on your choice (board specific).
' *

program UART
dim uart_rd,u2_rd as byte
Sub procedure U1_wr(dim inch as byte)
       'UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)   makes no difference
       UART1_Write(inch)
end sub

Sub procedure U2_wr(dim inch as byte)
    'UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle)   makes no difference
    UART2_Write(inch)
   ' do
'      nop               'check TX2 status
'    loop until TXSTA2.TRMT
'    TXREG2 = inch       'write to register starts transmission
'     do
'      nop               'check TX2 status
'    loop until TXSTA2.TRMT     'wait for Tx to end
end sub

main:
  OSCCON = 0x70
  PLLEN_bit = true
  ANSELC = 0                           ' Configure PORTC pins as digital
  ANSELD = 0
  
  UART1_Init(9600)                     ' Initialize UART module at 9600 bps
  Delay_ms(100)                        ' Wait for UART module to stabilize
  UART2_Init(9600)
  Delay_ms(100)                        ' Wait for UART module to stabilize

  UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
  UART1_Write_Text("Ready 1")
  UART1_Write(13)                      ' Line Feed
  UART1_Write(10)                      ' Carriage Return
  UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle) 'without this, always writes to UART1
  UART2_Write_Text("Ready 2")
  UART2_Write(13)                      ' Line Feed
  UART2_Write(10)                     ' Carriage Return

  while (TRUE)                         ' Endless loop
    if (UART1_Data_Ready() <> 0) then  ' If data is received,
       uart_rd = UART1_Read()          'read the received data
      ' Uart1_write(uart_rd)
       'Uart2_write(uart_rd)
       'Uart2_write(uart_rd)            'any way  round writes to Uart1 only
       'Uart1_write(uart_rd)
       'U1_wr(uart_rd)                 ' sub routines to allow set up of uarts
       U2_wr(uart_rd)                  'always writes to UART1 only  ???????????
    end if
  wend
end.
What I have noticed in the .list file is that L_UART2_Write16 checks the TXSTA2 bit 1 whilst L__UART1_Write14 checks TXSTA bit 1, not specifically TXSTA1, 1 Is this relevant?

Code: Select all

_UART2_Write:
;__Lib_UART_c67d67.mpas,200 :: 		
;__Lib_UART_c67d67.mpas,201 :: 		
L__UART2_Write61:
0x001C	0xB272      	BTFSC       TXSTA2, 1 
0x001E	0xD002      	BRA         L__UART2_Write62
0x0020	0x0000      	NOP
0x0022	0xD7FC      	BRA         L__UART2_Write61
L__UART2_Write62:
;__Lib_UART_c67d67.mpas,202 :: 		
0x0024	0xFF73C03E  	MOVFF       FARG_UART2_Write_data_, TXREG2
;__Lib_UART_c67d67.mpas,203 :: 		
L_end_UART2_Write:
0x0028	0x0012      	RETURN      0
; end of _UART2_Write
_UART1_Write:
;__Lib_UART_c67d67.mpas,86 :: 		
;__Lib_UART_c67d67.mpas,87 :: 		
L__UART1_Write14:
0x002A	0xB2AC      	BTFSC       TXSTA, 1 
0x002C	0xD002      	BRA         L__UART1_Write15
0x002E	0x0000      	NOP
0x0030	0xD7FC      	BRA         L__UART1_Write14
L__UART1_Write15:
;__Lib_UART_c67d67.mpas,88 :: 		
0x0032	0xFFADC03E  	MOVFF       FARG_UART1_Write_data_, TXREG1
;__Lib_UART_c67d67.mpas,89 :: 		
L_end_UART1_Write:
0x0036	0x0012      	RETURN      0
Any ideas?
Thanks in advance.

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Uart1 and Uart2 problems

#2 Post by Dany » 18 May 2023 18:38

Hi,
UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
UART1_Write_Text("Ready 1")
UART1_Write(13) ' Line Feed
UART1_Write(10) ' Carriage Return
UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle) 'without this, always writes to UART1
UART2_Write_Text("Ready 2")
What you are doing with "Uart_Set_Active" followed by "Uart1_write" or "Uart2_write" does not work as you would expect.
After "Uart_Set_Active" you should use "Uart_write" (or "Uart_Read") without specifying what uart to use, the active one will be used then.
If you use "Uart1..." or "Uart2..." then "Uart_Set_Active" is not necessary (but harmless).

I do not know why it always writes to Uart1 if you do not use " UART_Set_Active(@UART2_Read, @UART2_Write..." Very strange.

Could you please also show your config file?
Thanks
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

dangerous
Posts: 748
Joined: 08 Mar 2005 16:06
Location: Nottinghamshire, UK

Re: Uart1 and Uart2 problems

#3 Post by dangerous » 18 May 2023 19:45

Thanks Dany,
It will be Monday now as the files are at work and I have reached that age where I can do four days a week,
The set active function is not well explained in the help file. Thanks for clarifying that.
I will post the config as soon as I can.
Kind regards.

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Uart1 and Uart2 problems

#4 Post by Dany » 22 May 2023 17:00

Hi Dangerous,
What I have noticed in the .list file is that L_UART2_Write16 checks the TXSTA2 bit 1 whilst L__UART1_Write14 checks TXSTA bit 1, not specifically TXSTA1, 1 Is this relevant?
According to the definition file TXSTA and TXSTA1 are thye same register, so it seems ok.
TXSTA : byte; absolute 0x0FAC; volatile; sfr;
TXSTA1 : byte; absolute 0x0FAC; volatile; sfr;

* Would it be possible for you to show the list code of 'Sub procedure U2_wr(dim inch as byte)'?

* Would it be possible to give the settings of SW1 and SW2 on your EasyPic v7 development board?
If I understand the circuit diagram well it is not possible to read AND write to 2 uarts. I should be possible to write to one and read from the other tough.
EasyPic v7, Uart1 is on COM3 via a USB to RS232(TTL level) converter to/from the PC and Uart2 is on the in built USB Uart on Com 11. I am using the MB Uart tool on COM3 to read and write to UART1, and Realterm capture program to monitor Uart 2.
Thanks in advance.
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

dangerous
Posts: 748
Joined: 08 Mar 2005 16:06
Location: Nottinghamshire, UK

Re: Uart1 and Uart2 problems

#5 Post by dangerous » 23 May 2023 08:20

Hi Dany,

I thought that I had replied Yesterday but it seems like not.

I had SW1 set to D7 and SW1 set to D6, both jumpers J3 & $ to USB UART. Adpater on flying leads to RC6(TX) RC7 (Rx) Gnd (0V). I had also tried reversing those connections between port C and D.
If I understand the circuit diagram well it is not possible to read AND write to 2 uarts. I should be possible to write to one and read from the other tough.
Yes, I am not trying to read from both, just to read from 1 and write to the other, but I wanted to echo back to UART1 for testing.

I did a re-think yesterday and re-arranged the writes to sub routines so that the USB active call was only needed once if I write more than one set of chars. It now works with received data from UART1 echoed back on UART 1 and copied to UART2.

This appears to have solved the issue. It does look like a long way round though, and each "set active" adds about 200 bytes of code. Not a lot in the greater scheme of things, but I hate code bloat. The only real difference is using the UART_set_ Active command with Uart_write(data)

I had a session on MPLABx ide yesterday (I still have headache!) and the same functions with setup by MCC occupy 246 bytes ROM, 31 bytes RAM, 7 bytes Config, 0 bytes EEprom and 8 bytes ID loctaion. My MB version uses 1014 bytes of ROM and 56 of RAM, but does not specify Config or ID.

Config attacdhed:

Code: Select all

 <?xml version="1.0"?>
<MCU_DEVICE_FLAGS>
  <DEVICE>
    <DEVICE_NAME>P18F45K22</DEVICE_NAME>
    <VALUE>
      <COUNT>11</COUNT>
      <VALUE0>
        <VAL>$300001:$0029</VAL>
      </VALUE0>
      <VALUE1>
        <VAL>$300002:$001F</VAL>
      </VALUE1>
      <VALUE2>
        <VAL>$300003:$003C</VAL>
      </VALUE2>
      <VALUE3>
        <VAL>$300005:$00BF</VAL>
      </VALUE3>
      <VALUE4>
        <VAL>$300006:$0081</VAL>
      </VALUE4>
      <VALUE5>
        <VAL>$300008:$000F</VAL>
      </VALUE5>
      <VALUE6>
        <VAL>$300009:$00C0</VAL>
      </VALUE6>
      <VALUE7>
        <VAL>$30000A:$000F</VAL>
      </VALUE7>
      <VALUE8>
        <VAL>$30000B:$00E0</VAL>
      </VALUE8>
      <VALUE9>
        <VAL>$30000C:$000F</VAL>
      </VALUE9>
      <VALUE10>
        <VAL>$30000D:$0040</VAL>
      </VALUE10>
    </VALUE>
  </DEVICE>
</MCU_DEVICE_FLAGS>
Revised Code:

Code: Select all

' *
' * Project name:
'     UART (Simple usage of UART module library functions)
' * Copyright:
'     (c) Mikroelektronika, 2011.
' * Revision History:
'     20110929:
'       - initial release (FJ);
' * Description:
'     This code demonstrates how to use uart library routines. Upon receiving
'     data via RS232, MCU immediately sends it back to the sender.
' * Test configuration:
'     MCU:             PIC18F45K22
'                      http://ww1.microchip.com/downloads/en/DeviceDoc/40001412G.pdf
'     Dev.Board:       EasyPIC7 - ac:UART
'                      http://www.mikroe.com/easypic/
'     **Oscillator:      ** Int HS PLL on = 64MHz.
       ' ** Was :HS-PLL 32.0000 MHz, 8.0000 MHz Crystal
'     Ext. Modules:    None.
'     SW:              mikroBasic PRO for PIC
'                      http://www.mikroe.com/mikrobasic/pic/
' * NOTES:
'     - Turn on RX and TX UART switches (SW1.1 and SW2.1). (board specific)
'     - Put RX and TX UART jumpers (J3 and J4) in RS-232 or USB position,
'       depending on your choice (board specific).
' *

program UART

dim din as byte
dim CRLF as string[2]



Sub procedure U1_wr(dim inch as byte)  'writes 1 x char(inch) to uart1
       UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
       UART1_Write(inch)
end sub
'
Sub procedure U2_wr(dim inch as byte) 'writes 1 x char(inch) to uart2
      UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle)
      UART2_Write(inch)
end sub
'
main:
  OSCCON = 0x70
  PLLEN_bit = true
  ANSELC = 0                           ' Configure PORTC pins as digital
  ANSELD = 0
  ANSELB = 0
  TRISB = 0
  LATB = 0
  CRLF =   (Chr(0x0d) + Chr(0x0a))
  UART1_Init(9600)                     ' Initialize UART module at 9600 bps
  Delay_ms(100)
  UART2_Init(9600)
  Delay_ms(100)                        ' Wait for UART module to stabilize
  UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
  Uart_write_text("Ready Uart 1" + CRLF)
  UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle)
  Uart_write_text("Ready Uart 2" + CRLF)

   While true
     If Uart2_data_Ready() then   'UART2 still active from above 
         din = UART2_read
         U2_wr(din)
         U1_wr(din)
         latb.0 = not latb.0
     end if
   wend

end.

dangerous
Posts: 748
Joined: 08 Mar 2005 16:06
Location: Nottinghamshire, UK

Re: Uart1 and Uart2 problems

#6 Post by dangerous » 23 May 2023 09:01

Hi Again,

I just commented out all the uart_set_active commands, erased the PIC compleletly and re-programmed. It still works with a more reasonable 668 bytes of ROM and 40 Bytes of RAM used. (684 ROM if I use the sub routine to send bytes.) This seems to be very much as it was when I started and had all sorts of problems. Maybe I was having a bad programming day!

I do wonder if the UART_Set_Active instruction is needed at all with fixed (as in non-remappable) Uarts. Is it neccessary or just advisable? I can send a (10 char + " " + CRLF) sequence at 5ms repeat time with no data loss. See attached pdf screen shot of UART2 on left (Real Term), Uart1 on right (MB terminal). This is after sending the string in MB term box at 5mS repeat rate to UART 1 with echo received and UART 2 written.

Revised code below:

Code: Select all

' *
' * Project name:
'     UART (Simple usage of UART module library functions)
' * Copyright:
'     (c) Mikroelektronika, 2011.
' * Revision History:
'     20110929:
'       - initial release (FJ);
' * Description:
'     This code demonstrates how to use uart library routines. Upon receiving
'     data via RS232, MCU immediately sends it back to the sender.
' * Test configuration:
'     MCU:             PIC18F45K22
'                      http://ww1.microchip.com/downloads/en/DeviceDoc/40001412G.pdf
'     Dev.Board:       EasyPIC7 - ac:UART
'                      http://www.mikroe.com/easypic/
'     **Oscillator:      ** Int HS PLL on = 64MHz.
       ' ** Was :HS-PLL 32.0000 MHz, 8.0000 MHz Crystal
'     Ext. Modules:    None.
'     SW:              mikroBasic PRO for PIC
'                      http://www.mikroe.com/mikrobasic/pic/
' * NOTES:
'     - Turn on RX and TX UART switches (SW1.1 and SW2.1). (board specific)
'     - Put RX and TX UART jumpers (J3 and J4) in RS-232 or USB position,
'       depending on your choice (board specific).
' *

program UART

dim din as byte
dim CRLF as string[2]



Sub procedure U1_wr(dim inch as byte)
       'UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
       UART1_Write(inch)
end sub
'
Sub procedure U2_wr(dim inch as byte)
      'UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle)
      UART2_Write(inch)
end sub
'
main:
  OSCCON = 0x70
  PLLEN_bit = true
  ANSELC = 0                           ' Configure PORTC pins as digital
  ANSELD = 0
  ANSELB = 0
  TRISB = 0
  LATB = 0
  CRLF =   (Chr(0x0d) + Chr(0x0a))
  UART1_Init(9600)                     ' Initialize UART module at 9600 bps
  Delay_ms(100)
  UART2_Init(9600)
  Delay_ms(100) 
  'UART_Set_Active(@UART2_Read, @UART2_Write, @UART2_Data_Ready, @UART2_Tx_Idle)
  Uart2_write_text("Ready Uart 2" + CRLF)                       ' Wait for UART module to stabilize
  'UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
  Uart1_write_text("Ready Uart 1" + CRLF)
  'tried either UART first - no change.

   While true
     If Uart1_data_Ready() then
         din = UART1_read
         'UART2_Write(din)
         'UART1_Write(din)
         U1_wr(din)
         U2_wr(din)
         latb.0 = not latb.0
     end if
   wend
  

end.
Just curious now.
As always, thanks for your help.
Screen.pdf
(448.53 KiB) Downloaded 40 times

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Uart1 and Uart2 problems

#7 Post by Dany » 23 May 2023 15:50

Glad you could solve it.
I do wonder if the UART_Set_Active instruction is needed at all with fixed (as in non-remappable) Uarts. Is it neccessary or just advisable?
No, it is not needed:

Code: Select all

UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)
UART_write(inch)
is exactly the same as

Code: Select all

UART1_write(inch)
alone.
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

dangerous
Posts: 748
Joined: 08 Mar 2005 16:06
Location: Nottinghamshire, UK

Re: Uart1 and Uart2 problems

#8 Post by dangerous » 24 May 2023 07:58

You have cleared the muddy waters for me again Dany.

Thanks. :D

Post Reply

Return to “mikroBasic PRO for PIC General”