Monday, September 19, 2016

Serial port example of PIC16F877a

CIRCUIT DIAGRAM






SOURCE CODE



#include <xc.h> // this file contains the SFR information of the chip
//----------------------------------------------------------------------------------
#define _XTAL_FREQ     4000000L
//Function prototypes
void port_initialise(void);
void init_variables (void);
void DelayMs(unsigned int msCount);
//--------------------------------------------------------------------------

#pragma config WDTE = OFF      
    #pragma config FOSC = HS
    #pragma config PWRTE = ON
    #pragma config BOREN = ON
    #pragma config LVP = OFF
    #pragma config CPD = OFF
    #pragma config WRT = OFF
    #pragma config DEBUG = ON
    #pragma config CP = OFF

//--------------------------------------------------------------------------
//#pragma udata access myaccess //Access RAM data which needs fast baccess
near volatile  struct // This is a structure to create logic flags.
{ // FLAGAbits
  unsigned FLAG0:1; //
  unsigned FLAG1:1; //
  unsigned FLAG2:1; //
  unsigned FLAG3:1; //
  unsigned FLAG4:1; //
  unsigned FLAG5:1; //
  unsigned FLAG6:1;
unsigned FLAG7:1;
} FLAGAbits;

//---------------------------------------------------------------------------
//#pragma udata // normal RAM data (not access)
// Variable dclarations(Global)
unsigned char digit1_var=0,digit2_var=0 ;// holds the digit to be dispalyed
unsigned char PORTDbackup;

//-------------------------------------------------------------------------
// Define

//----------------------------------------------------------------------------
//Function prototypes
void transmit_data(unsigned char tx_data);
unsigned char receive_data(void);
void usart_ini (void);
void lcdstringptr( const char *ptr, unsigned char lineNo);
void stringToSerialPort( const char *ptr);
void Timer1_ini(void );
//--------------------------------------------------------------------------
const char * welcomestring ={"This is PIC16F877A serial Port of your System!"};
//--------------------------------------------------------------------------
//This is the intruupt area.
void interrupt InterruptArea(void)
{

} //This return will be a "retfie".
//-------------------------------------------------------------------------------------------------------------
//#pragma code MainlineCode //****************************************************************************
void main (void)
{ // main loop starts-------------
unsigned char count;
unsigned char RxedData; // Controller starts with 48Mhx clock from 20Mhz Xtal and PLL for USB bootloader
  port_initialise(); // setting up I/O lines as input and output
  init_variables (); // variables are to be initialised
usart_ini(); // initialise serial port for 9600 baud
stringToSerialPort(welcomestring); // send a string to serial port


//---------------------------------------------------------------------------------------------------
while(1) // Normally, every MCU programe is a never ending loop. here starts it
{ //while 1 loop starts----------

} //while 1 loop ends------------
} // main loop ends--------------
///*********************************************************************************************************
//#pragma code functions
//-----------------------------------------------------------------------
void Timer1_ini(void )
{
//Timer1 initialisation
T1CON=0b00000001; // prescalar 1:1,internal clock, timer1 started.
PIR1bits.TMR1IF=0; // Timer1 interrupt flag cleared
PIE1bits.TMR1IE=1; // Timer1 interrupt enbled
INTCON |= 0b11000000; // enable app interrupts
}
//----------------------------------------------------------------------
void usart_ini()
{
SPBRG = 25; //baud rate 9600@4Mhx
TXSTA = 0B00100100;
RCSTA = 0B10010000; // see datasheet for configuration
TRISC   =0B11000000;// configure pins as input
PIE1 &=0b11001111; // disable transmit and receive interrupts
}
//-------------------------------------------------------------------------
unsigned char receive_data(void)
{
unsigned char rx_data;
while(!PIR1bits.RCIF);// wait for the rxbuffer to get filled
rx_data = RCREG ;
PIR1bits.RCIF = 0 ;//clear the flag and return
return(rx_data);

}
//--------------------------------------------------------------------------
void transmit_data(unsigned char tx_data)
{
TXREG = tx_data ;
while(!TXSTAbits.TRMT);// wait till transmition is over
}
//----------------------------------------------------------------------------
void stringToSerialPort( const char *ptr)
{
unsigned char loc;
while(1)
{
loc=*ptr;
if(!loc) //check weather value 0 ( id\f end of string ,it will be 0.
break; // compiler by default null terminates every string
transmit_data(loc); // send each data to serialport
*ptr++;
}

}
//****************************************************************************************

void port_initialise (void)
{
TRISD = 0X00; // LED port is made as output
PORTD = 0X00; // and cleared
ADCON1 = 0b10000100; // A/D module not ued.All pins digital
TRISA =  0b00001011;
PORTA = 0X00;
TRISC &= 0b11111110;
TRISE = 0B00000111;
PORTE = 0X00;
TRISB = 0b00000000;
PORTB = 0X00 ;
LEDenable=0; // led array enable transistor off
Digit1_En=0; // digits to be kept low
Digit2_En=0;
}
//*******************************************************************************************************
void init_variables (void)
{
digit1_var=0,digit2_var=0 ;
LCDiniFlag=0;
NOP();  // you can add any varibale initialisation here if required
}
//**************************************************************************
void DelayMs(unsigned int msCount)
{
unsigned int locCnt;
for(locCnt=0;locCnt<=msCount;locCnt++)
{
__delay_ms(1); // This XC8 function creates a delay of 1 millisecond
} // looping this msCount times will give that much milliseconds delay
}


EXPLANATION

This module actually configures the serial port (RS-232) in PIC to receive and send data at 9600 baud rate. We will demonstrate this by connecting to the serial port of the PC and running a windows application called terminal. The Training kit upon loading this module will listen to the serial port for any data. .
Even though this RS232 module is being demonstrated here as a communication to PC, it can be used to communicate to other devices which are having a standard serial port. In this module we are again doing Seven Segment display in Interrupt. There is a reason for that. Serial communication with 9600 baud rate is not a very fast communication when we are sending strings. So the Display may flicker because of time lags. To avoid this we again moved the display to interrupt so that display will be updated in time.
We need to configure the serial port initially as this is a general purpose peripheral which can handle a wide range of baud rates and a variety of modes.(RS-232 serial port in PC is operating in asynchronous mode, btw!) After we call the USART initialization function the module is ready to send and receive data. Receiving we are doing here on a character basis only, but in the case of transmission we accommodate for strings also. Just like in the case of LCD, we will be placing certain strings in the ROM and fetching them in sequence using pointers and sending them to serial port one by one to be shown in PC side as text.
transmit_data(0x0D);// Line feed and Carriage return to move
//to the next line
transmit_data(0x0A);
These are hex data send to PC after the end of strings. These are actually ASCII values for Carriage return and Line feed, which is the symbols to indicate applications to start new line (Almost like the function of enter key while typing in a word processing program.) We are sending this to host PC to make our strings arranged in lines for visual clarity.
The program logic is simple. After configuration the code will wait for a data to be received in the receive buffer. If received, it will be shown in LCD and in Seven Segment LED (if it is a number) and then echoed back to PC with accompanying sentences. And will wait for the next character to arrive.
The terminal software after starting should be adjusted for 9600 baud and the serial port number you have connected USBMM is also to be selected. Most of PCS will be having only one serial port as general purpose with a number as 1.
Here we are receiving characters only and it is in very low speeds also to be shown in LCD 1 by one. If we need to accept a string we need to avoid all those delays in the code and just push the received characters into a RAM array in PIC which later can be a string.

No comments:

Post a Comment