1. 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.
    Dismiss Notice

UART interface with PIC16F886

Discussion in 'Microcontrollers' started by ajit_nayak87, Dec 1, 2017.

  1. ajit_nayak87

    ajit_nayak87 New Member

    Joined:
    Nov 25, 2017
    Messages:
    6
    Likes:
    0
    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 (text):



    #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);
     
       
       }


    }


     
     
  2. Ian Rogers

    Ian Rogers User Extraordinaire Forum Supporter Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,802
    Likes:
    958
    Location:
    Rochdale UK
    ONLINE
    One thread on the same subject is enough!! I deleted the other thread!
     
  3. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,715
    Likes:
    421
    Location:
    Brisbane Australia
    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.
     
  4. dave miyares

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    2
    Likes:
    -10


     
  5. Ian Rogers

    Ian Rogers User Extraordinaire Forum Supporter Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,802
    Likes:
    958
    Location:
    Rochdale UK
    ONLINE
    Also This:-
    Code (c):

    while(TXIF==0); // <-  character to send!
     
    Will give you trouble... Use this instead..

    Code (c):

    while(TRMT==0); // <- shift reg empty / full
     
     
  6. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,715
    Likes:
    421
    Location:
    Brisbane Australia
    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.
     
  7. Ian Rogers

    Ian Rogers User Extraordinaire Forum Supporter Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,802
    Likes:
    958
    Location:
    Rochdale UK
    ONLINE
    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...
     
  8. dave miyares

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    2
    Likes:
    -10


     
  9. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,715
    Likes:
    421
    Location:
    Brisbane Australia
    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.
     
  10. Ian Rogers

    Ian Rogers User Extraordinaire Forum Supporter Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,802
    Likes:
    958
    Location:
    Rochdale UK
    ONLINE
    If you look through the source that comes with C18, that's how its done...
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice