top of page
PIC16F88 USART Test

Date:  Nov 2021 Updated: 18 Sep 2023


A good starting point for a Microchip microcontroller project is to test the hardware setup and establish a comms link. Here a  twisted pair cable connects to MAX483 pins A and B with the other end going into a RS485 to USB converter plugged into a laptop running CuteCom terminal to send and receive character strings.
http://manpages.ubuntu.com/manpages/trusty/man1/cutecom.1.html  CuteCom details

RS485 allows more than two devices to share the bus/cable. A load of about 120 ohms is advised at the ends of the twisted pair to absorb reflections.

https://datasheets.maximintegrated.com/en/ds/MAX1487-MAX491.pdf


The MAX483 could be replaced by an RS232 device like MAX232

see https://github.com/DanMilliken/PIC16F88_UART_Demo/blob/master/Schematic.jpg

and if so the directional control line U1:RB3 is not needed

H8A:5 goes via ZTX300 transistor to drive an LED both on a 5v supply. THE LED is made to flash on power up to verify the PIC is alive and programmed ok.

zoneControllerPIC16F88wix.png

Above schematic /home/andymc/fotmus/webDesign/niaMondo/hal/zoneController/
zoneControllerPIC16F88wix.png
Dated: 03Nov2021

 

Main Requirements:

  • MPLAB IDE with 'c' Compiler XC8 v2.32 C99 enabled https://microchipdeveloper.com/xc8:moving-to-xc8-2-0

  • RS485 USB-485 Converter (Ebay about £1.30 in 2021)

  • 5v Power supply

  • Laptop with terminal eg CuteCom or Minicom

  • Devices under test as in above schematic

  • Programmer hardware (Used here PICkit3 as supported by MPLAB IDE)

/home/andymc/Ref/halk/PIC16F88supportOld/16F88uartTest2.X/xc8Test16f88uart2.c

Dated 07Nov2021

/******************************************************************************
* PIC16F88 UART Test
* With thanks to  Dan Milliken http://www.dmilliken.com/?p=5 2014-12-15
* https://github.com/DanMilliken/PIC16F88_UART_Demo
* and https://simple-circuit.com/mplab-xc8-uart-example-pic-mcu/
* Description: Demonstrates using the PIC16F88 Microcontroller with a MAX483 IC
* to produce RS485 output to a PC with USB.
* 16F88 data sheet/manual https://ww1.microchip.com/downloads/en/DeviceDoc/30487D.pdf

* Compiled under: MPLAB X IDE v5.50 on 03 Nov 2021
* Project and Program Name: 16F88uartTest2
*******************************************************************************/
#include <xc.h>         /* XC8 General Include File */
//Note #include <16F88.h> not called directly as it is included by #include <xc.h>
#include <stdio.h>         /* C standard IO */
#include <stdint.h>        // include stdint header amc added
#include <string.h>
#include <stdbool.h>
#include <stdlib.h> //for itoa see XC8 user guide

#pragma config LVP = OFF        // disable low voltage programming
#pragma config FCMEN = OFF      // disable fail safe clock monitor
#pragma config IESO = OFF       // disable internal/external oscillator switchover
#pragma config BOREN = OFF      // disable brown out reset
#pragma config PWRTE = ON       // enable power up timer
#pragma config WDTE = OFF       // disable watchdog timer
#pragma config FOSC = INTOSCIO  // Internal oscillator

#define _XTAL_FREQ 8000000 //8 Mz only needed for delay

#define TXDO PORTBbits.RB3 //PIN_B3 High is TX enable
#define REDLED PORTAbits.RA0 //LED on push switch, red 5v=LED on

void putch(char cDaita) {
  // https://microchipdeveloper.com/xc8:console-printing
  //This will be called automatically by printf()
  TXDO=1; //TX_Enable
  __delay_ms(5);  // wait
  while( ! PIR1bits.TXIF)          // wait until the transmitter is ready
     continue;
  while (TXSTAbits.TRMT == 0);  // wait for transmit shift register to be empty
  TXREG = cDaita;                     // send one character
  TXDO=0; //TX_Disable
}

//void putch(unsigned char data) {
void myputch(char cDaata) {
  //https://microchipdeveloper.com/xc8:console-printing
  //printf() calls this customised version of putch
  TXDO=1; //TX_Enable  
  while( ! PIR1bits.TXIF) // wait until the transmitter is ready
     continue;
  while (TXSTAbits.TRMT == 0);  // wait for transmit shift register to be empty
  TXREG = cDaata; // send one character
  TXDO=0; //TX_Disable
}

void UART_PutC(const char darta)
{
  TXDO=1; //TX_Enable
  //__delay_ms(20);  // wait 20 mS debug
  //while (TRMT == 0);  // wait for transmit shift register to be empty
  while (TXSTAbits.TRMT == 0);  // wait for transmit shift register to be empty
  TXREG = darta;       // update EUSART transmit data register
  TXDO=0; //TX_Disable
}

void UART_Print(const char *data)
{
  uint8_t i = 0;
  while (data[i] != '\0')
  UART_PutC (data[i++]);
}

void flashLED(void)
{
  int iz;
  for (iz = 1; iz < 3; ++iz)
  {
  REDLED=1;
  __delay_ms(1000);  // wait 1 second
  REDLED=0;
  __delay_ms(1000);  // wait 1 second
  }
}

void UART_Init(void)
{
  //OSCCONbits.IRCF = 0b110; // Set internal RC oscillator to 4 MHz
  //https://maker.pro/pic/tutorial/getting-started-with-pic-microcontrollers-internal-oscillator-and-io-pins
  OSCCONbits.IRCF = 0b111; // Set internal RC oscillator to 8 MHz
  while(!OSCCONbits.IOFS); // Wait for frequency to stabilise
  TXSTAbits.BRGH = 1; // high baud rate
  TXSTAbits.SYNC = 0; // Set Asynchronous Mode, ie UART
  TXSTAbits.TX9  = 0; // 8-bit transmission

  //SPBRG = 25;         // 9600 baud @ 4MHz with BRGH = 1
  SPBRG = 51;         // 9600 baud @ 8 MHz with BRGH = 1

  PIE1bits.RCIE  = 1; // AUSART Receive Interrupt Enable bit
  //SPEN & CREN set 1 is same as RCSTA = 0x90;  // serial port enabled, continues receive enabled
  RCSTAbits.SPEN = 1; // Serial port enabled (configures RB2/SDO/RX/DT and RB5/SS/TX/CK pins as serial port pins)
  RCSTAbits.CREN = 1; // Continuous Receive Enable bit
  TXSTAbits.TXEN = 1; // enable transmitter
  return;
}

const char sTestMsg[] = "ex-PIC16F887 UART example" ;
#define LTERM 0x0D //\r=cr=13=LTERM - End of message character
#define LGO '!' // Start of message character

// main function
void main(void)
{
  //Set port directions
  //RA5/MCLR is i/p only http://ww1.microchip.com/downloads/en/devicedoc/30487d.pdf
  char cInp;
  unsigned char chh;
  char comin_buf[30];  //input data buffer, A string literal in XC8 is a const array of char
  int iMsg;
  TRISBbits.TRISB3 = 0; // Set B3 as output TXDO controls MAX483 direction
  TRISAbits.TRISA0 = 0; // Set A0 as output see REDLED
  //OSCCON = 0x70;    // set internal oscillator to 8MHz
  TRISBbits.TRISB2 = 1; //Input RX for UART
  TRISBbits.TRISB5 = 1; //Input TX (as UART has its own driver!)

  UART_Init(); // 9600);  // initialise UART module with 9600 baud
  __delay_ms(2000);  // wait 2 seconds
  flashLED();

  UART_Print("Hello 16F88!\r\n");  // UART print
  __delay_ms(1000);  // wait 1 second
  UART_Print(sTestMsg);  // UART print message
  __delay_ms(1000);  // wait 1 second
   
  UART_Print("\r\n");  // start new line
  printf("Done with printf\r\n");
  myputch('X');  
  myputch('Y');  
  myputch('Z');  
  for (cInp = 'A' ; cInp <= 'Z' ; cInp++) {
  myputch(cInp);
  }
  putch('!');
  putch('h');
       
  while (1)
  {
  //RCIF == 1 then The AUSART receive buffer is full (cleared by reading RCREG) **
  //RCIF bit (register PIR1, bit 5)
  iMsg = 0;
  while ( RCIF == 1 )  // if 1 character(s) are available
  {
     //OERR: Overrun Error bit
     //1 = Overrun error (can be cleared by clearing bit CREN)
     //The USART can receive two characters before it overflows
     if (OERR)  // if there is overrun error
     {  // clear overrun error bit
       CREN = 0; //Clear overrun
       NOP();
       CREN = 1;
     }
     chh = RCREG; // read from EUSART receive data register, clears receive buffer **
     comin_buf[iMsg++] = (char)chh;
  }
  if (iMsg > 0)
  {
     comin_buf[iMsg++] = NULL;
     for (int ix = 0; ix < iMsg; ix++)
     {  
       putch(comin_buf[ix]);
     }
  }
  }  
} //end main
//========================================

 

Below the test input and echoed output is shown on the laptop terminal.

Character delay is set to 12 mS for this polling example.

CR/LF is appended to each line sent
File /home/andymc/fotmus/webDesign/niaMondo/hal/zoneController/
zoneControllerPIC16F88CuteComwix.png

zoneControllerPIC16F88CuteComwix.png

©2021 by Digital Thoughts. Proudly created with Wix.com

bottom of page