soft_uart.c - Demonstrates software-driven UART TX/RX using PIO pinsΒΆ

 
#include "pic24_all.h"

/// Soft UART Config
#define CONFIG_STX() CONFIG_RB2_AS_DIG_OUTPUT()
#define STX _LATB2     //STX state
#define CONFIG_SRX() CONFIG_RB3_AS_DIG_INPUT()
#define SRX _RB3     //SRX state
#define DEFAULT_SOFT_BAUDRATE 19200
uint16_t u16_softBaudRate = DEFAULT_SOFT_BAUDRATE;

void doBitDelay (uint16_t u16_baudRate) {
  if (u16_baudRate == 9600) {
    DELAY_US(106);
  } else if (u16_baudRate == 19200) DELAY_US(52);
}

void doBitHalfDelay (uint16_t u16_baudRate) {
  if (u16_baudRate == 9600) {
    DELAY_US(53);
  } else if (u16_baudRate == 19200) DELAY_US(26);
}

void outCharSoft(uint8_t u8_c) {
  uint8_t u8_i;
  STX = 0;
  doBitDelay(u16_softBaudRate);
  for (u8_i=0; u8_i<8; u8_i++) {
    if (u8_c & 0x01)
      STX = 1;
    else STX = 0;
    doBitDelay(u16_softBaudRate);
    u8_c = u8_c >> 1;
  }
  STX = 1;
  doBitDelay(u16_softBaudRate);
}

uint8_t inCharSoft(void) {
  uint8_t u8_i, u8_c;

  u8_c = 0x00;
  while (SRX) doHeartbeat();
  doBitHalfDelay(u16_softBaudRate);
  for (u8_i=0; u8_i<8; u8_i++) {
    doBitDelay(u16_softBaudRate);
    if (SRX) u8_c = u8_c | 0x80;
    if (u8_i != 7) u8_c = u8_c >> 1;
  }
  doBitDelay(u16_softBaudRate);
  return(u8_c);
}



int main (void) {
  uint8_t u8_c;

  configClock();
  configHeartbeat();
  /** GPIO config ***************************/
  CONFIG_STX();      //software TX
  STX = 1;           //should be high
  while (1) {
    u8_c = inCharSoft();      //get character
    u8_c++;               //increment the character
    outCharSoft(u8_c);    //echo the character
    doHeartbeat();
  }

End program

  return 0;
}