Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] PIC32MX795F512L on Explorer 16 demo board: use of UART through multiplexers

Status
Not open for further replies.

Drugo

Junior Member level 2
Joined
Feb 23, 2011
Messages
20
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,537
Hello everyone,

this is the first time I'm using this forum, please I desperately :cry: need someone's help because I'm stuck with my project. The problem is related to the communication of 2 UARTs through the two multiplexers (CD74HCT4053PWR) of the PIC EXPLORER 16 board (U6 and U7 at page 42 of the Explorer User's Guide: **broken link removed**).

uC I'm using: PIC32MX795F512L
Purpose of the board: it has to communicate via 4 RS-232, SPI and I2C with a couple of external devices. Now SPIs and I2Cs are neither used nor configured.
UARTs "incriminated": UART1A (also called UART1) and UART1B (also called UART4) (I must use these UARTs and not others because I will have to use also SPI, I2C. In addition UART3A and UART3B are currently used and work perfectly)
UART1A pins: RF2 (rx), RF8 (tx)
UART1B pins: RD14 (rx), RD15 (tx)

As indicated by Microchip at page 34-35 of the Explorer User's Guide, I set pins RB14 and RB13 to make work, respectively, UART1A and UART1B. I also program AD1PCFG = 0Xffff to enable PORTB digital pins and, obviously, set these two pins as output. They actually work, I checked with the multimeter.

PROBLEMS:
1. RF8 output does not change the state, it's always at 0V. Instead, RF2, RD14 and RD15, can change the state without any problem (all the hw connections are ok).
2. Even if RD14 and RD15 of UART1B elettrically work, the UART doesn't rx and tx anything. The software I used it's the same of the other two UARTs (UART3A and UART3B), where I obviously changed the speed and the UART index. Here attached you can find the init and send functions of UART1B (i.e. UART4).

As I'm using this PIC32MX on this Explorer to test if the uC I chose for this application is okay (so that we can develop a final board), I hope someone can help me because I really don't know what the solution could be.

Thanks a lot in advance!
Drugo
 

Attachments

  • UARTs_pbm_code.txt
    1.2 KB · Views: 137

have you read the information sheet on the PIC32MX795F512L PIM?
**broken link removed**

some of the pins shown in the Explorer 16 documentation are mapped to different locations, see TABLE 1: 100-PIN TO 100-PIN PIM
 
  • Like
Reactions: Drugo

    Drugo

    Points: 2
    Helpful Answer Positive Rating
Horace1, many many thanks for your very helpful hint! I found that the numbering mapping from uC and PIM module is different in 1 pin. It's the following one:
(pin42) RB13 > (pin42) RB13
(pin43) RB14 > (pin43) RB14
(pin47) RD14 > (pin47) RD14
(pin48) RD15 > (pin48) RD15
(pin52) RF2 > (pin52) RF2/U1RX
(pin53) RF8 > (pin51) RF3/U1TX

I forgot to specify the mapping equivalence between uC numbering and the one used in the uC header and library files. That is:

UART1A = UART1
UART2A = UART3
UART3A = UART2
UART1B = UART4
UART2B = UART6
UART3B = UART5

I changed UART1A TX connection from RF8 to RF3 (PIM map) but UART1A (UART1) and UART1B (UART4) ARE STILL NOT WORKING...

I really don't understand where the problem is, because the code attached in my initial message is correct and the wiring connections too.

Hope that someone can give me a help. Many thanks again
 

not sure what is going wrong for you - the PIC32MX360F512L UART1 Rx and Tx is mapped correctly to RF2 and RF3 on the PIM header and appear Ok on the J5 connector of the explorer 16
when I run my UART1 code (below) it sends and receives OK (I looped RF2 and RF3 on a prototype board) and I can see the signals on an oscillosope
Code:
// UART1.c -  UART1 for PIC32 either polled or interrupt driven

// to use for another UART
//    1.  copy this file uart2.c (to uart4.c say) and change references to uart2 to uart4
//    2. copy uart2.h (to uart4.h say) and edit the defines to suit UART4
#include "UART1.h"

#ifdef UART_RX_INTERRUPT
// buffer and pointers for received data under interrupts
#define BUFFER 100
static unsigned char UARTx(rxBuffer)[BUFFER]={0},  * UARTx(rxIn)=0, * UARTx(rxOut)=0;
static int UARTx(number)=0;		// number of characters in buffer
int UARTx(error)=0;    			// number of buffer overflows
#endif


//******************************************************************************
// Constants
//******************************************************************************

#define BRG_DIV2        16
#define BRGH2           0

//  initialize UART
//   Input: baud rate
//   Output: 1 for OK, 0 if baud rate error > 3%
int UARTx(Init)(const long int BAUDRATE)
{
    int error;
	// This initialization assumes 36MHz Fpb clock. If it changes,
	// you will have to modify baud rate initializer.
    UARTConfigure(UART1, UART_ENABLE_PINS_TX_RX_ONLY);
    UARTSetFifoMode(UART1, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
    UARTSetLineControl(UART1, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
    UARTSetDataRate(UART1, GetPeripheralClock(), BAUDRATE);
    UARTEnable(UART1, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
#ifdef UART_RX_INTERRUPT
	// Configure UART1 RX Interrupt
	INTEnable(INT_SOURCE_UART_RX(UART1), INT_ENABLED);
    INTSetVectorPriority(INT_VECTOR_UART(UART1), INT_PRIORITY_LEVEL_2);
    INTSetVectorSubPriority(INT_VECTOR_UART(UART1), INT_SUB_PRIORITY_LEVEL_0);
    // configure for multi-vectored mode
    INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
    // enable interrupts
    INTEnableInterrupts();
    UARTx(rxIn)= UARTx(rxOut)= UARTx(rxBuffer);
    UARTx(number)=UARTx(error)=0;
 
#endif
    error = (int) (100 *( (long int) UARTGetDataRate(UART1, GetPeripheralClock())- BAUDRATE)/BAUDRATE);
    if (error > 2) 
       { printf("\n\n" UARTNAME " baud rate shold be %ld is %lu error %d\n", BAUDRATE, UARTGetDataRate(UART1, GetPeripheralClock()), error);  return -1; }
    printf(""UARTNAME " baud rate %ld set up\n", BAUDRATE);
    return 0;
}

#ifdef UART_RX_INTERRUPT
// UART 2 interrupt handler - it is set at priority level 2
//void __ISR(_UART1_VECTOR, ipl2) IntUart2Handler(void)
void UART_RX_INTERRUPT
{
	// Is this an RX interrupt?
	if(INTGetFlag(INT_SOURCE_UART_RX(UART1)))
		{
		// Clear the RX interrupt Flag
		INTClearFlag(INT_SOURCE_UART_RX(UART1));
   	 	*UARTx(rxIn)++ = UARTGetDataByte(UART1);						// read character into buffer
    	if(UARTx(rxIn) >= UARTx(rxBuffer)+BUFFER) UARTx(rxIn)=UARTx(rxBuffer);	// check for end of buffer
    	if(UARTx(number)++>=BUFFER) {  UARTx(rxIn)= UARTx(rxOut)= UARTx(rxBuffer);  UARTx(number)=0; UARTx(error)++;}
 		// Toggle LED to indicate UART activity
		//mPORTAToggleBits(BIT_7);
		}
}
#endif

// Function: UART flush - flush input data
void UARTx(flush)(void)
{
#ifdef UART_RX_INTERRUPT
    UARTx(rxIn)= UARTx(rxOut)= UARTx(rxBuffer);
    UARTx(number)=UARTx(error)=0;
#endif
}


//Function:UART CharReady - return true if there is a new byte in UART reception buffer.
char UARTx(CharReady)()
{
#ifdef UART_RX_INTERRUPT
    return  UARTx(rxIn) != UARTx(rxOut);		// pointers different - if so characters in buffer
#else
	return UARTReceivedDataIsAvailable (UART1);					// none zero if UART has received data
#endif
}

//Function:UART GetChar : waits for a byte to be received.  It then returns that byte.
char UARTx(GetChar)()
{
    char Temp;
#ifdef UART_RX_INTERRUPT
    while(UARTx(rxIn) == UARTx(rxOut)) Nop();		// wait for character
    Temp = *UARTx(rxOut)++;					// get character
    UARTx(number)--;
    if(UARTx(rxOut) == UARTx(rxBuffer)+BUFFER)  UARTx(rxOut)=UARTx(rxBuffer);	// check for end of buffer
#else
    //while(! _UARTx(RXIF));						// wait for data
    Temp= UARTGetDataByte(UART1);						// read character into buffer
//	_UARTx(RXIF) = 0;							// clear interrupt flag
#endif
    return Temp;
}

// Function:UART GetString - read a string until \n received or length reached
void UARTx(GetString)(char *str , int length) 
{
    char ch=0;
    while(ch != '\n')
       if(UARTx(CharReady)())
          { 
           ch=*str=UARTx(GetChar)(); 
           str++; 
           *str=0;
           if(--length<1) return;
          }
}

// Function:UART PutChar - This routine writes a character to the transmit FIFO
void UARTx(PutChar)(const char ch )
{
    while(!UARTTransmitterIsReady(UART1));
    UARTSendDataByte(UART1, ch);				// transmit character
}

//Function:UART PrintString - prints a string of characters to the UART.
void UARTx(PrintString)(const char *str )
{
    char c;
    while( (c = *str++) )
       UARTx(PutChar)(c);
}

//Function:UART PrintBytes - prints byte array of specified length to the UART.
void UARTx(PrintBytes)(const unsigned char *str, int length )
{
    int i;
    for(i=0;i<length;i++)
       UARTx(PutChar)(str[i]);
}
 
  • Like
Reactions: Drugo

    Drugo

    Points: 2
    Helpful Answer Positive Rating
Many thanks again Horace1,
I checked your very helpful file and found that, from a configuration point of view (except the fact I don't use INTSetVectorSubPriority(..) function), it's the same I use. I actually configure all UARTs interrupts in just one routine not reported in the file I posted, but it's the same (in fact UART3A and UART3B work perfectly).
In this moment I don't have an oscilloscope, but on Saturday I'm going to have it so I can check better the hardware. In fact RF2 pin, when I drive it ON and OFF for testing, has a low value of about 0.12V and not 0V. Therefore I think there is something wrong in the hardware.

And congratulation for the excellent sw programming style you used in your code!
 

as least you appear to be narrowing down the problems!
I find an oscillosope is an essential tool when working on these problems - got a none working USB on a PIC24FJ256GB110 based system at the moment !

the PIC32 is very impressive ! we are looking to upgrade one of our PIC18F87J60 projects (it has integrated Etherenet 10baseT), which has grown out of control with a lots of pheripheral chips, up to a PIC32 with integrated 10/100baseT soon.
 

yes, I think that once I'll have the oscilloscope I'll understand where the problem is. I will need soon to add USB too once the final hardware will be ready, and there will be much more problems I think! :)
other thann USB also SPI and I2C communication with some sensor and SD memory card. In these condition, without an oscilloscope, I would be lost...

thanks again for your precious help!
 

We have build four or five systems recently with USB using PIC24s and never had problems (there are only teo lines and the Microchip APIs doing everything for you) - I thing we may have a PCB fault!
I find oscillosopes particularly useful for SPI interfaces - you can check enable, the clock and data lines to see if anything is there (programmable pheripheral pins on some PIC24s can be a problem) and if the relationship of the signals is correct.
Looks as though the PIC32MX795F512L should do your project OK - wish we had had them years ago, we would have dumped the PIC18F87J60 sooner!
 

the presence of the Microchip USB library comforts me a lot, because I read the USB drivers are really complicated.
I was wondering if it was possible to have your UART1.h header file - if it's not a problem for you - so that, to be sure 100%, I can test my board also with your code.

I'm actually porting the software of my project from a PIC24F256GB110 to the PIC32MX described above. I find the PIC24F more flexible, for example regarding the remappable pins. But I actually need higher speed and modules.
thanks a lot!
 

USB is complex. I usualy take one of the Microchip example programs and adapt it to do what I want ! saves reinventing the wheel !
header file for UART1 (I think I adapted it from the Microchip PIC32 examples)
Code:
// UART1.h  for PIC32 either polled or interrupt driven

#include "hardware.h"

// undefine any previous definitions
#undef UARTNAME
#undef UARTx
#undef UART_RX_INTERRUPT

// definitions for this UART
#define UARTNAME "\nUART1"				// UART name as a string
#define UARTx(text) UART1##text

// if not using interrupts comment out next line
// defines UART 1 interrupt handler - it is set at priority level 2
#define UART_RX_INTERRUPT __ISR(_UART1_VECTOR, ipl2) IntUart1Handler(void)

//extern int UARTx(number);		// number of characters in buffer
extern int UARTx(error);    	// number of buffer overflows

//  initialize UART
//   Input: baud rate
//   Output: 1 for OK, 0 if baud rate error > 3%
int UARTx(Init)(const long int BAUDRATE);

//Function:UART CharReady - return true if there is a new byte in UART reception buffer.
char UARTx(CharReady)();

//Function:UART PrintString - prints a string of characters to the UART.
void UARTx(PrintString)(const char *str );

//Function:UART GetChar : waits for a byte to be received.  It then returns that byte.
char UARTx(GetChar)();

// Function:UART GetString - read a string until \n received or length reached
void UARTx(GetString)(char *str , int length) ;

//Function:UART PrintBytes - prints byte array of specified length to the UART.
void UARTx(PrintBytes)(const unsigned char *str, int length );

// Function:UART PutChar - This routine writes a character to the transmit FIFO
void UARTx(PutChar)(const char ch );

// Function: UART findString
//  check for character string received
//  if ASCII character add it to string data
//  if \n return number of characters in string
// if timeout and no characters received return -1 else number of characters in string
int UARTx(findString)(char *find, char *data, const int length, const int timeout);
yes, we have found the PIC24F256GB110 Peripheral pin select is very useful in particular for simplifing PCB layout. We also find low pin count devices like the PIC24FJ64GB002 is good for student projects. The 28 pin SPDIP makes it easy to build PCBs and they then map the peripherals required at run time.
 
  • Like
Reactions: Drugo

    Drugo

    Points: 2
    Helpful Answer Positive Rating
many many thanks again, tomorrow I'm going to try your code on my system. I want to be sure 100% that the problem is not in my software. I'll let you know
 

Hi horace1, I tried your software and it's still not working. Therefore I'm sure it's a hardware problem. I'm going to test it better on Sunday with the oscilloscope.
Thanks a lot for all your collaboration
 
Hi horace1,
I finally found the solution using the oscilloscope. I feel ashamed admitting my mistake, but two solderings of the two "incriminated UARTs" were weak, so the signal didn't pass through them. But checking the wire connection with the multimeter it was ok because of the small pressure of the probes. I lost time for a stupid oversight.
In any case your initial suggestion about PIM pins was absolutely fundamental. Thanks again!
 

Good to hear you tracked down the problem.
Managed to get our USB going today - looked at D+ and D- with a oscillosope and could see we had problems with the signal levels. Found the VSUB supply had somehow been missed from the PCB!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top