It is currently 25 Feb 2018 00:49

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: PIC18F47K40 uart problem
PostPosted: 29 Jul 2017 20:19 
Offline

Joined: 07 Jan 2017 14:59
Posts: 6
Hello

I have a problem when using both uarts on the PIC18F47K40 and need some help.

UART2 is remapped to PORTD (RD2=RX, RD3=TX) and UART1 is on it's default pins on PORTC. Both have a low baud rate of 300.
When using only one of the uarts, UART1 or UART2, everything works as it should. When both are initiated only UART1 is working.
The receive for both uarts are handled by interrupt and there is also an TMR0 interrupt. When UART1 is initiated the UART2 isr seem not to respond.

I have tried different ways to init the uarts, setting bits directly in registers and also with mikroe-libs. Have also tried interrupt priority in different
combinations for UART1, UART2 and TMR0 but the result is the same.

Has someone seen this before or is it me missing something?
Screenshots of interrupt and init of uarts attached. It looks a bit messy after all tests.... UART1 is not initiated in the jpg.


//Lars


Attachments:
interrupt.JPG
interrupt.JPG [ 91.74 KiB | Viewed 612 times ]
init uarts.JPG
init uarts.JPG [ 49.18 KiB | Viewed 612 times ]
Top
 Profile  
 
PostPosted: 31 Jul 2017 17:47 
Offline
User avatar

Joined: 21 Mar 2017 16:57
Posts: 527
Hello,

Due to some specifics in PPS, UARTs on this device have to be addressed via the UART_SET_ACTIVE.
You can init them both, even on a different baudrate, then when you want to work with the UART1, you should first set it active. Take a look at the following snippet of code, from the compiler's HELP:
UART1_Init(115200);                    // initialize UART1 module
UART2_Init(9600);                    // initialize UART2 module

RS485Master_Init();                  // initialize MCU as Master

UART_Set_Active(&UART1_Read, &UART1_Write, &UART1_Data_Ready, &UART1_Tx_Idle); // set UART1 active
UART_Write_Text("message1");        // send message through UART1

UART_Set_Active(&UART2_Read, &UART2_Write, &UART2_Data_Ready, &UART2_Tx_Idle); // set UART2 active
UART_Write_Text("message2");        // send through UART2

In the provided listing, I see that you were mixing the mikroE libraries and you were also trying to write values into the registers directly. I wouldn't recommend mixing those two, as you can't know what is happening inside the libraries to be able to set the corresponding registers accordingly.

Best regards


Top
 Profile  
 
PostPosted: 31 Jul 2017 23:34 
Offline

Joined: 07 Jan 2017 14:59
Posts: 6
Hello Darko and thanks for the answer.

Unfortunately UART_Set_Active() did not seem to work, the result was as before. When initiating both uarts only uart1 was working and that could not be changed by UART_Set_Active(&UART2,,,).

I did some more testing and found if uart1 also is remappad (actually I did a fake remap to the default pins) both uarts works as supposed. The Mikroe PPS-Lib, with or without the UART Remappable Lib, did not do the trick. The remapping was done according to PIC data sheet. Maybe there is bug....

The code used for testing is attached if someone else has uart problems with this PIC-family.

/************************************************************************
Test program for PIC18F47K40

-UART1, UART1 and TMR0 Interrupt.
-UART2 remapped to pins RD2 and RD3.
************************************************************************/
// Variables and more *******
#define toggleRx1 LATD.B4
#define toggleRx2 LATE.B0

char rxByte1 = 0;
char rxByte2 = 0;
char testSym = 'T'; //Test symbol to send periodically (~500ms?)
unsigned int testTime = 0;
//**************************
void Interrupt() // Check interrupts
{
   if (TMR0IF_bit) // Timer0 has interrupted 1ms has passed.
   {
     TMR0IF_bit   = 0;
     TMR0L        = 5;
     testTime++; // For sending test data
   }
  if(RC1IF_bit == 1) //
   {
      toggleRx1 = ~toggleRx1; // Toggle led
      rxByte1 = UART1_Read();
   }
   if(RC2IF_bit == 1) //
   {
      toggleRx2 = ~toggleRx2;
      rxByte2 = UART2_Read();
   }
}
// Init******************
void init()
{
   ANSELA = 0x03; // Select analog inputs (RA0, RA1 = analog)
   ANSELB = 0x00;
   ANSELC = 0x00;
   ANSELD = 0x00;
   ANSELE = 0x00;

   ADCON0 = 0b10000100; //Fosc, AD0, AD_ON
   ADCON1 = 0b00000000; // Right just.
   ADCLK = 0x01; // Fosc / 4  '
   ADREF = 0x03;
   FVRCON = 0xC2; // +Vref = 2.048V
   
   TRISA = 0b00111111; // PORTA = Set as inputs.
   TRISB = 0b00000000; //
   TRISC = 0b11011110;
   TRISD = 0b00001111;
   TRISE = 0b00001100;

   //**** Set pins and init UART1 and UART2 (RD3 = TX, RD2 = RX)
   // UART1 at default pins
   RX1PPS = 0b00010111; // RX1 pin = RC7 (default...)
   RC6PPS = 0b00001001; // TX1 pin = RC6    -"-
   RX2PPS = 0b00011010; // RX2 pin = RD2 (Remapped)
   RD3PPS = 0b00001011; // TX2 pin = RD3 (Remapped)
   // "Fake remap", UART1 makes both UARTS work.
   // Mikroe's PPS-Lib seem not to work.
   //**** Init UART1 (RC6 = TX, RC7 = RX)
   UART1_Init(300); // Init serial port @ 300bit/s
   RC1IE_bit = 1; //enable Interrupt.
   //**** Init UART2 (RD3 = TX, RD2 = RX)
   UART2_Init(300);
   RC2IE_bit = 1; //enable interrupt.
   //***********************
   //******** Set up Timer0
   //Prescaler 1:4; TMR0 Preload = 5; Actual Interrupt Time : 1 ms
   T0CON0      = 0xC0;
   T0CON1      = 0x42;
   TMR0L       = 0x05;
   T0EN_bit    = 1; // Enable timer 0
   TMR0IE_bit  = 1;
   //**********
   IOCIE_bit   = 0; // Make sure no Interrupt on change
   PEIE_bit    = 1; //Enable peripheral interrupts
   GIE_bit     = 1; //Enable global interrupts
}
//***********************
// Main******************
void main()
{
   init(); //Init functions and pin's.
   Delay_ms(100); //

   while(1) // main-loop
   {
      if(testTime >= 500) // 500ms since last test, run another.
      {
         UART1_Write(testSym); // Send "T" as uart test
         UART2_Write(testSym); // Send "T" as uart test
         testTime = 0; // Reset
      }
   }
}
//***********************



// Lars


Top
 Profile  
 
PostPosted: 01 Aug 2017 11:31 
Offline
User avatar

Joined: 21 Mar 2017 16:57
Posts: 527
Hello,

Yes, there are certainly some issues with the UART on that MCU. This code is working fine on my EasyPIC V7 and PIC18F47K40 though, so I will attach the code here for you to test. I was switching between the 2 UARTs by changing the DIP switch setting, that's why I have chosen those pins. Also in order to work with the PPS, you need to set the PPS Lock bit to allow multiple reconfigurations in your Project Settings window. This code works even with the PPS lock bit set to a single reconfiguration, You can take a look at it too, as it is rather short:
void main()
{
  ANSELA = 0x00;
  TRISA = 0x00;
  LATA = 0x00;

  Unlock_IoLock();
  PPS_Mapping_NoLock(_RC7, _INPUT, _RX1PPS);
  PPS_Mapping_NoLock(_RC6, _OUTPUT, _TX1PPS);
  PPS_Mapping_NoLock(_RD7, _INPUT, _RX2PPS);
  PPS_Mapping_NoLock(_RD6, _OUTPUT, _TX2PPS);
  Lock_IoLock();

  Uart1_Remappable_Init(9600);
  Uart2_Remappable_Init(9600);

  while (1)
  {
    UART_Set_Active(&UART1_Remappable_Read, &UART1_Remappable_Write, &UART1_Remappable_Data_Ready, &UART1_Remappable_Tx_Idle);
    UART1_Remappable_Write_Text("TEST_1\n\r");
    Delay_ms(500);
    LATA = ~LATA;
   
    UART_Set_Active(&UART2_Remappable_Read, &UART2_Remappable_Write, &UART2_Remappable_Data_Ready, &UART2_Remappable_Tx_Idle);
    UART2_Remappable_Write_Text("TEST_2\n\r");
    Delay_ms(500);
    LATA = ~LATA;
  }
}


Attachments:
UART PIC47K40_C.zip [3.5 KiB]
Downloaded 24 times
Top
 Profile  
 
PostPosted: 01 Aug 2017 12:27 
Offline

Joined: 07 Jan 2017 14:59
Posts: 6
Hello Darko,

An addition to my previous post.

I used the init and interrupt parts from my test program.
In the project all I/O-pins are in use. It was found that RB7 (used as output) did not shift logic state as it should.

When initating UART2 (remapped) the following is needed:
   //**** Init UART2 (RD3 = TX, RD2 = RX)
   UART2_Remappable_Init(300);


If using the standard:
UART2_Init(300);


I guess the default UART2 TRIS-bits, TRISB.B6 (TX) is set low for output and TRISB.B7 (RX) is set high for input.
Now the program runs as it should, UART_Set_Active(....) was not used, both uarts, interrupts and all I/O-s works fine.

Thanks for your support.

//Lars


Top
 Profile  
 
PostPosted: 01 Aug 2017 14:36 
Offline
User avatar

Joined: 21 Mar 2017 16:57
Posts: 527
Hi,

Set Active doesn't make sense if you have your own code which handles the UART RX and TX. Set Active will only affect the code written using our UART library.
We will investigate into this matter and if needed - we will correct the libraries. For now, this 'workaround' is good for those who would like to use mE UART libraries.

Quote:
// Mikroe's PPS-Lib seem not to work.

PPS library certainly works, since it has mapped the pins in my example as supposed.
In any case, thanks for the notice

Best regards


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: