Electrical – PIC16F1619 curiosity- UART communication

communicationpicserial

I am using the PIC16F1619 microcontroller within the curiosity board, MPLAB IDE x and XC8 compiler. I am currently trying to get my board to read an analog value and then to transmit this value through a UART-USB ADM00559 breakout board, which uses the MCP2221 board.

I have read the datasheet and have set all associated registers that I can see and am currently trying to get the board to simply send any value, for example 'a' or 0x32 to the TX1REG register. I am using a program called 'Terminal' to see the incoming messages. I have set the Baud rate to 9600, data bits to 8, Parity to none, stop bits to 1, no handshaking. However currently I am getting just 0's out of the communication no matter what value I assign to the TX1REG. Possible things of note/problems:

  1. I've set the Tx pin to RC6, RC6PPS = 0x12, using the relevant PPS code and disabled the analog output functionality of as prescribed in the datasheet

  2. I've set the SPxBRGH, SPxBRGL to a value of 52 according the 32MHz clock rate, this was done with SP1BRGH = 51 and SP1BRGL = 1, is this correct, or does it need to be some sort of equal pairing?

MAIN PROGRAM

[/code]

/*
* File:   ledblink.c
* Author: Patrick
*
* Created on July 24, 2016, 12:09 PM
*/
#include <xc.h>                 // XC8 compiler header file
#include <stdlib.h>
#include <stdio.h>
#include "uart.h"

#define _XTAL_FREQ 32000000     // Define PIC16F1619 clock freq - 32MHz

// Above is header files - xc is for compiler, stdlib is for general  function 
//and stdio is for I/O. Below is the bit configuration

#pragma config FOSC = INTOSC    // Oscillator Selection Bits 
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select 
#pragma config CP = OFF         // Flash Program Memory Code Protection 
#pragma config BOREN = ON       // Brown-out Reset Enable 
#pragma config CLKOUTEN = OFF   // Clock Out Enable
#pragma config IESO = ON        // Internal/External Switch Over
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection 
#pragma config PPS1WAY = ON     // Peripheral Pin Select one-way control
#pragma config ZCD = OFF        // Zero Cross Detect Disable Bit 
#pragma config PLLEN = ON       // PLL Enable Bit (4x PLL is always enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable 
#pragma config BORV = LO        // Brown-out Reset Voltage Selection 
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset 
#pragma config LVP = ON         // Low-Voltage Programming Enable

// CONFIG3
#pragma config WDTCPS = WDTCPS1F// WDT Period Select (Software Control
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config WDTCWS = WDTCWSSW// WDT Window Select 
#pragma config WDTCCS = SWC     // WDT Input Clock Selector

int result;                     //variable to store our ADC result

int main() {  
    TRISAbits.TRISA5 = 0;           // Set pin as output for LED Flash
    UART_Init(9600);                // Call UART initialisation function
    TRISCbits.TRISC6 = 0x00;        // Set pin RC6 as output
    TRISBbits.TRISB6 = 1;
    //Main while loop
    while(1)
    {
        TX1REG = 'a';
        // UART_Write(PORTBbits.RB6);
        // UART_Write('a');
        LATAbits.LATA5 = 1;      // Turn on the LED
        __delay_us(10000);
        LATAbits.LATA5 = 0;      // Turn off the LED
        __delay_us(10000);
        return 0;
    }
}          

UART header file

char UART_Init(const long int baudrate)
{
    ANSELCbits.ANSC6 = 0;   // Disable Analog function of pin RC6/AN8
    RC6PPS = 0x12;          // Sets RC6 to PPS Transmit Serial Data
    SP1BRGL = 0x32;           // Initialising SPxBRGH & SPxBRGL register pair  (BAUD)
    SP1BRGH = 0x1;           // Initialising SPxBRGH & SPxBRGL register pair     (BAUD)
    BRGH = 0;               // Initialising BRGH and BRG16 register pair (BAUD RATE)
    BRG16 = 0;              // Initialising BRGH and BRG16 register pair (BAUD RATE)
    SYNC = 0;               // Clearing SYNC bit (TXxSTA reg)|Configures EUSART for asynchronous operation
    SPEN = 1;               // Enables EUSART and configures TX/CK I/O pin as output
    TXEN = 1;               // Enables Transmitter circuitry
}

char UART_TX_Empty()
{
    return TRMT;
}

char UART_Data_Ready()
{
    return RCIF;
}

char UART_Read()
{
    while(!RCIF);
    return RCREG;
}

void UART_Read_Text(char *Output, unsigned int length)
{
    unsigned int i;
    for(int i=0;i<length;i++)
        Output[i] = UART_Read();
}

void UART_Write(char data)
{
    while(!TRMT);
    TX1REG = data;
}

void UART_Write_Text(char *text)
{
    int i;
    for(i=0;text[i]!='\0';i++)
        UART_Write(text[i]);
}

Best Answer

With your present config, your baud rate is probably 250k - a little higher than your planned 9600.

When BRG16 is 0 you're telling the PIC that you only want to use an 8-bit baud-rate divisor, so the SPxBRGH register is ignored.
So load your calculated value into SPxBRGL.

If you did want to use a 16-bit divisor (and set BRG16 to 1), then the SPxBRGH/SPxBRGL registers are paired together and their values are used as a 16-bit value with SPxBRGH contributing the 8 MSBs and SPxBRGL contributing the 8 LSBs.