Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

UART interface with PIC16F886

Status
Not open for further replies.

ajit_nayak87

New Member
I am trying uart serial communication on pIC16F886 . I am using 20Mhz external oscillator frequency.For below code i am getting garbage value.

i have tested similar code on PIC18F24K40 where i am using 16Mz internal oscillator where i can able to send and receive data with same hardware . Here i am replacing MCU with PIC16F886 with external oscilator
Please let me know any problem doing while intialization
I am using asyn mode.16bit

Code:
#include <htc.h>
#include <stdio.h>
#include<pic.h>
#include<stdint.h>
#include "delay.h"
#define _XTAL_FREQ 20000000
unsigned int i=0; 
  unsigned char c=0;
  unsigned char ch;

#define SBIT_TXEN 5
#define SBIT_SPEN 7
#define SBIT_CREN 4




#define LED_RX RC7 // Pin assigned RX LED
#define LED_TX RC6 // Pin assigned TX LED
#define LED RC2 // Pin assigned for LED 
#define DE RC5
#define RECEIVE 0
#define TRANSMIT 1
#define READ_REG 3
#define WRITE_REG 6
#define ILLEGAL_DATAVALUE 0x03
#define FALSE 0
#define TRUE 1
#define METER_ID 1
unsigned int j=0;
unsigned char* str;
unsigned int count = 0;
char data = 0;
unsigned char rxbuf[50];
unsigned char ser_data[95];
unsigned char crc_data[95];
unsigned char Max_scroll = 0;
unsigned char buff[10];
volatile uint8_t index = 0, rec_flag = 0, Delay_count = 0, Id[10], Buffer_count = 0, Cal_count = 0, Disp_count = 0, inc = 0, One_sec_update = 0, Auto_scroll_count = 0;
char data1[10];
unsigned char buf[20];







unsigned short int cnt, num,Dgt=0;

unsigned int j;
#define Notes_Index 25

unsigned int Toff_counter=0;
unsigned int POn_Flag=1;
unsigned int Poff_Flag=0;




void Serial_1_Send_byte(uint8_t trbuf1) 
{
 TXREG = trbuf1;
  while(TXIF==0); // Wait till the transmitter register becomes empty
}


void Send_string_uart1(const unsigned char *string) 
{
    unsigned char i = 0;

    do {
        TXREG = string[i++];
        while(!TXIF); // Wait till the transmitter register becomes empty
    } while (string[i] != '\0');
}

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

char usart_RxString()
{

   while(*str !='\0')
   { // while not end of string
      while(0==PIR1bits.RCIF);
       RCREG = *str; // read next character 
       str++; // increment pointer to next character
   }
       return RCREG; // return the contents of uart
}

/*
void UART_Init(int baudRate)
{ 
    TRISC=0x80; // Configure Rx pin as input and Tx as output 
   // TXSTA=(1<<SBIT_TXEN); // Asynchronous mode, 8-bit data & enable transmitter
   // RCSTA=(1<<SBIT_SPEN) | (1<<SBIT_CREN); // Enable Serial Port and 8-bit continuous receive
    TXSTA=0b00100010; // Low Speed mode 
 RCSTA=0b10010000;
    SPBRG = (20000000UL/(long)(64UL*baudRate))-1; // baud rate @20Mhz Clock
}
*/

void UART_TxChar(char ch)
{
    while(TXIF==0); // Wait till the transmitter register becomes empty
    TXIF=0; // Clear transmitter flag
    TXREG=ch; // load the char to be transmitted into transmit reg
}


char UART_RxChar()
{
    while(RCIF==0); // Wait till the data is received 
    RCIF=0; // Clear receiver flag
    return(RCREG); // Return the received data to calling function
}



  void Timer1_Interrupt()
 {

  INTCON = 0b00000000;
  PIE1=0b00000001;
  PIR1=0x01;
  TMR1H=0x0B;
  TMR1L=0xDC; 
  T1CON=0x31;
    TMR1IE = 1;
 TMR1IF = 0;
 // T1CON=0x01;
 }


 void Init_Controller()
 {
  cnt=100; 
    TRISC = 0x80; //RX port configured as input
 PORTC = 0x80;
 TRISB=0X00;
 PORTB = 0X00;
 TRISA=0X00; 
    PORTA=0X00; 
    ANSELH=0x00; 
 ADCON0 = 0b00000000;
 ANSEL = 0b00000000;
 Timer1_Interrupt();
    LED=0;

 }

//Below code make Ton and Toff time in equal Interval


void interrupt isr(void)
 {
    if(TMR1IF==1)
   {

                    //EA60=45ms CB20 =107ms 
             TMR1H=0xEA; //load the time value(0x0BDC) for 100ms delay
    TMR1L=0x60; //Timer1 Interrupt for 65000
    TMR1IF=0; // Clear timer interrupt flag
          Dgt++;
             if( Dgt>=10)
                  {
                   // LED = !LED; 
                   
                  } 
                 
           
    } 
                 
  } 


void Serial_1_Init()
{ 

  BAUDCTL=0b01001000; //16bit baudrate has used
 INTCON = 0b00000000;
    RCIE=1;
 RCIF=0;
     CCP1IE=1;
    RCSTA=0b10010000;
    SPBRG = 0x81;
    SPBRGH= 0x00; // 9600 Baud Rate for 64Mhz
 TXSTA=0b00100010; // Low Speed mode 
   
}


void EUSART_Initialize(void)
{
    // disable interrupts before changing states
    RCIE = 0;
    TXIE = 0;
    BAUDCTL=0X09; //16bit baudrate has used

    // SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled; 
    RCSTA = 0x90;

    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave; 
    TXSTA = 0x22;

    SPBRG=81;

SPBRGH=00;
RCIE = 1;
}


void main(void)
  {

             Init_Controller();
            Serial_1_Init();
       //UART_Init(9600);
      /* GIE=1;
     PEIE=1;
     TMR1IE=1; */

   

  while(1)
   {
        LED =1;
        DelayMs(250);
       Send_string_uart1("hello");
        LED =0;
        DelayMs(250);
 
   
   }


}
 
Your baudrate calc is slightly wrong,
SPBRG = (20000000UL/(long)(64UL*baudRate))-1; // baud rate @20Mhz Clock
should be,
SPBRG = (20000000UL/(long)(64UL*(baudRate-1))); // baud rate @20Mhz Clock

You also don't include your config values so you may be using the internal clock.

Mike.
 
Ian Rogers
I always use the TXIF to know when to send the next char and have not experienced any problems. Can you elaborate?

Mike.
 
datasheet said:
TXIF is also not cleared immediately upon loading TXREG,
but becomes valid in the second instruction cycle following
the load instruction. Polling TXIF immediately following a
load of TXREG will return invalid results.

Meaning if you load the txreg at the point the TXIF is set, sometimes it doesn't shift in correctly!!

I use Radio's and I need to ensure transmit is done...
 
I've learnt something new, missed that in the datasheet. I guess I've never been bitten because I check the flag before writing rather than directly after.

Mike.
 
I've learnt something new, missed that in the datasheet. I guess I've never been bitten because I check the flag before writing rather than directly after.

Mike.
If you look through the source that comes with C18, that's how its done...
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top