Usart issue on pic16f

Thread Starter


Joined Mar 9, 2022
Hi guys,

I'm using Mplab for a project (with pic16f1788), where I use USART communication and I2C as well. At the time being I'm using USART to communicate with a BLE module.

I'm not getting any message from the BLE module, so I verified my USART communication. On the oscilloscope, I see the character I'm sending. I used an arduino at the same time, to use the serial monitor, and check again, but on the arduino, I'm not recieving anything.

So it seems as the Usart commmunication is not working perfectly.

I put in the the attach files, the Mplab code, arduino code, as well as a photo of the oscilloscope signal.

Does any one have an idea please ?


// ----------------Mplab Code ------------------------

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>

#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config VCAPEN = OFF     // Voltage Regulator Capacitor Enable bit (Vcap functionality is disabled on RA6.)
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low Power Brown-Out Reset Enable Bit (Low power brown-out is disabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

#define _XTAL_FREQ 16000000

void init_UART()
TXSTA = 0x24;
RCSTA = 0x90;
SPBRG = 407;  // Baud = 9600    Fosc = 16 MHz
BAUDCON = 0x08;       // 16-bit Baud Rate Generator is used
APFCON1bits.TXSEL = 0;


void UART_Tx (char data)
    while (TXIF == 0){}
         TXREG = data; 
char UART_Rx()
    while (RCIF ==1){}
    return RCREG;

void main(void)
   TRISCbits.TRISC6 = 0;   // Tx
   TRISCbits.TRISC7 = 1;   // Rx
   int i=0;
   char data = 'U';   // U - 0b01010101  just for testing
   OSCCON = 0x7A; // 16 MHz
   //OSCCON = 0x72; // 8 MHz


// ----------------  Arduino Code ------------------------

void setup()

void loop()
char data;
while (Serial.available())
      data =;



Joined Jun 4, 2014
For such a serial link to work both ends, transmit and receive need to agree on a lot of parameters - voltage levels, signal polarity, baud rate, stop bits, handshaking.

That being said that doesn't look like a good uart output. Change the value of 'data' being sent to 0xC0 and post a picture of the waveform.

Thread Starter


Joined Mar 9, 2022

The voltage level is the same ( 5V ), signal polarity on mplab is the default one (not inverted), on the arduino I guess it's the same.
The baud rate of both is 9600 (an error of 0.16% on the pic ). The stop bit I guess it's generated automatiquely once the transmission ends.

And the handshaking don't know what is it ?

I'll send 0xC0 and post the picture.


Joined Oct 2, 2009
'U' is a good test character since it is 0x55.

You cannot see the START and STOP bits because you are sending characters one after the other.
Send only one character followed by a delay (greater than 2ms) in an endless loop.

Your oscilloscope trace is showing a bit width of about 35μs which is about 28600 baud.


Joined Jun 5, 2013
If the clock is indeed 16 MHz and you use the high speed option, here is how you calculate the divisor to get the bit clock:

16,000,000 / 4 = 4,000,000 / 9600 = 416. the value of BRG should be 415.

But your speed seems to be 3 times higher than that, so something is wrong.


Ian Rogers

Joined Dec 12, 2012
ANSELC turns off the AtoD on port c. This chip is designed to be a PSU switched mode supply driver... All the outputs can be used for PSU functionality.. I just ensured they were off..