Electronic – UART strange behavior with PIC32

microcontrollerpicuart

I am new to PIC32 MCU, I wrote a small piece of code to run the UART.

The MCU is the Microchip PIC32MX795F512H, the code uses interrupts to handle reception and transmission on the UART channel 5 (UART5), basically the code returns the user input.

The code is almost functional just a weird behavior: the first 8 bits are returned correctly and then 3 characters are transmitted to the console.

The input is azertya and the MCU returns: azertyaaaa (it adds aaa,the letter a was the first character inputed) and sometimes azertyaÿÿÿ; then for one characters input it returns the characters and three others (not random).

Main.c

            #include <p32xxxx.h>
            #include <plib.h>
            #include "uart.h" 

            #define GetSystemClock()                (80000000ul)
            #define GetPeripheralClock()                (GetSystemClock()/(1 << OSCCONbits.PBDIV))
            #define GetInstructionClock()               (GetSystemClock())

            #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
            #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1

            #define US_TO_CT_TICKS      (CPU_CT_HZ/1000000UL)   

            #define UARTCH1 UART5


            /*------------------------- Interruptions -----------------------------------*/


            void __ISR(_UART_5_VECTOR, ipl2) IntUART5Handler(void){


                if(INTGetFlag(INT_SOURCE_UART_RX(UARTCH1)))
                {

                        INTClearFlag(INT_SOURCE_UART_RX(UARTCH1));


                        PutCharacter(UARTGetDataByte(UARTCH1), UARTCH1);

                        mPORTBToggleBits ( BIT_12 );
                }


                if ( INTGetFlag(INT_SOURCE_UART_TX(UARTCH1)) ){

                        INTClearFlag(INT_SOURCE_UART_TX(UARTCH1));

                        PutCharacter(UARTGetDataByte(UARTCH1), UARTCH1);

                        mPORTBToggleBits ( BIT_15); 
                }
            }
            /*---------------------------------------------------------------------------*/

            int main (void){

                    SYSTEMConfig(GetSystemClock(), SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

                    ConfUART(UARTCH1); 

                    mJTAGPortEnable(DEBUG_JTAGPORT_OFF);
                    mPORTBClearBits( BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0 );
                    mPORTBSetPinsDigitalOut( BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0 );

                    WriteToUART("Test1_Test2_Test3_Test4_Test5\n", UARTCH1);

                return 0;

            }

UART.c

            #include <plib.h>

            #define GetSystemClock()        (80000000ul)
            #define GetPeripheralClock()        (GetSystemClock()/(1 << OSCCONbits.PBDIV))
            #define T_RATE_X                    (9600) 

            void WriteToUART(const char *string, char UARTCH){ 

                while(*string != '\0')
                {
                    while(!UARTTransmitterIsReady(UARTCH));
                    UARTSendDataByte(UARTCH, *string);
                    string++;
                    while(!UARTTransmissionHasCompleted(UARTCH));
                }
            }

            void PutCharacter(const char character, char UARTCH){

                while(!UARTTransmitterIsReady(UARTCH));

                    UARTSendDataByte(UARTCH, character);

                    while(!UARTTransmissionHasCompleted(UARTCH));
            }

            void ConfUART(char UARTCH){

                UARTConfigure           (UARTCH, UART_ENABLE_PINS_TX_RX_ONLY);
                UARTSetFifoMode     (UARTCH, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
                UARTSetLineControl  (UARTCH, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1); /* 8 Bits, Pas de parité, 1 STOP Bits */
                UARTSetDataRate     (UARTCH, GetPeripheralClock(), T_RATE_X);
                UARTEnable              (UARTCH, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));

                INTEnable                           (INT_SOURCE_UART_RX(UARTCH), INT_ENABLED);
                INTSetVectorPriority            (INT_VECTOR_UART(UARTCH), INT_PRIORITY_LEVEL_2);
                INTSetVectorSubPriority     (INT_VECTOR_UART(UARTCH), INT_SUB_PRIORITY_LEVEL_0);


                INTConfigureSystem      (INT_SYSTEM_CONFIG_MULT_VECTOR);


                INTEnableInterrupts();

            }

Best Answer

Your UART write function is built to stop transmitting when it finds NULL character in your string ('\0' or 0x00). You don't null-terminate your strings. It doesn't know when to stop sending, so it keeps going and sends everything it finds until it finds a NULL character.

To fix this, whenever you send a string you have to add '\0' to the end of it.

EDIT: Okay, the PutChar function fixes that - do you need to clear the interrupt manually? It looks like there's two sub-sources that are OR'd together to cause the main interrupt - you clear them but do you need to clear the main interrupt as well? That could cause this issue. Have you probed your UART Tx line and checked the baud rate that way? That could be a problem - if you're using a low-accuracy clock source you may not be spot on the baud rate.

Also edit: do you see your port toggle each time it sends the extra bytes?