Hot!Establishing UART communication using PIC16F886

Author
AMPS
Super Member
  • Total Posts : 359
  • Reward points : 0
  • Status: offline
2018/11/02 02:24:55 (permalink)
0

Establishing UART communication using PIC16F886

Dear all.
 
I am trying to build simple UART communication using interrupt. I have attached code for reference. I have used 8Mhz external crystal with 9600 baud rate . In below code i could able to print "WELCOME" properly when i observe red via DOCKLIGHT . 
 
I am trying to receive character and send same character .While send and receive i get garbage value.
Even i tried sending only Transmitting default value .But it display garbage values.
Is this code correct? why i cant able to receive single character 
/*
void Serial_1_Send_byte(uint8_t trbuf1)
{
 TXREG=trbuf1;
 while(0==TXIF);
 }*/


void Serial_1_Send_byte(uint8_t trbuf1)
{
 TXREG=trbuf1;
 while(0==TRMT);
}

char Serial_Receive_byte()
{
   
   while(0==RCIF);
    return RCREG;
    
}

 
 
post edited by ajitnayak87 - 2018/11/02 02:33:39

Attachment(s)

Attachments are not available: Download requirements not met
#1

11 Replies Related Threads

    hexreader
    Super Member
    • Total Posts : 1026
    • Reward points : 0
    • Joined: 2008/05/04 03:06:55
    • Location: England
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 03:11:34 (permalink)
    0
    I think that you may have mis-counted zeros:
     
     
    #define _XTAL_FREQ 80000000


    Experienced Hobbyist
    #2
    AMPS
    Super Member
    • Total Posts : 359
    • Reward points : 0
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 03:36:34 (permalink)
    0
    I checked. It wont cause any Problem. I have changed results are same. I could not able to receive byte. i can send strings
    #3
    hexreader
    Super Member
    • Total Posts : 1026
    • Reward points : 0
    • Joined: 2008/05/04 03:06:55
    • Location: England
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 04:06:05 (permalink)
    0
    I do not think I can help further.
    I am not familiar with Hitech C.
     
    Seems the code is incomplete anyway. I am guessing that there should be header files to go with it?
     
    Sending a welcome string for every interrupt seems like a really bad idea to me. I would have thought incoming characters would be missed during the time it takes to send the message.
    post edited by hexreader - 2018/11/02 04:17:19

    Experienced Hobbyist
    #4
    qhb
    Superb Member
    • Total Posts : 9614
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 04:17:15 (permalink)
    +1 (1)
    You are totally misusing interrupts.
    Turn interrupts off, and get some simple functionality going without them.
    Don't even try to use interrupts until you have some basic communication working.
    #5
    AMPS
    Super Member
    • Total Posts : 359
    • Reward points : 0
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 04:20:59 (permalink)
    0
    qhb
    You are totally misusing interrupts.
    Turn interrupts off, and get some simple functionality going without them.
    Don't even try to use interrupts until you have some basic communication working.


    It has worked for me PIC16F1938. Below is interrupt code for PIC16F1938.I have used Mplab X ide with MCC generated file.
    Let me know if any mistake in pIC16F886 with initialization. Same way i initialize 
     
    void Serial_Interrupt()
     
    {

    if((PIE1bits.RCIE==1)&&(PIR1bits.RCIF=1))
    {
    //PIR1bits.RCIF=0;
    for(index=0; index<8; index++)
    {
    rxbuf[index] = Serial_Receive_byte();

    }
    __delay_ms(10);
     
    if(index>=8) {

    rec_flag = 1;DE=1;

    }
     
    if(index>=20)
    {

    index=0;
    }
     
    if(1==RCSTAbits.FERR)
    {

    RCSTAbits.SPEN=0;
    RCSTAbits.SPEN=1;
    // DE=1;
    }
    if(1==RCSTAbits.OERR)
    {

    RCSTAbits.CREN=0;
    RCSTAbits.CREN=1;
    // DE=1;
    }

    // PIR1bits.RCIF=0;

    }
    CLRWDT();
    }
     
     

    #6
    qhb
    Superb Member
    • Total Posts : 9614
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 04:22:53 (permalink)
    0
    Even that code is totally misusing interrupts.
    You should NOT be staying inside the interrupt service to read more than one byte.
    If you are happy to write totally incorrect code, I'll leave you to it.
     
    #7
    AMPS
    Super Member
    • Total Posts : 359
    • Reward points : 0
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 04:27:25 (permalink)
    0
    I wanted to read single byte and transmit single byte.Weather intilization is wrong??

    void InitUART(void) {
    unsigned int BAUDRATE=9600;
    TRISC6 = 1; // TX Pin
    TRISC7 = 1; // RX Pin
    // SPBRG = ((_XTAL_FREQ/16)/BAUDRATE) - 1;
    BRG16=1;
    BRGH = 1; // Fast baudrate
    SYNC = 0; // Asynchronous
    SPBRG =207;
    SPEN = 1; // Enable serial port pins
    CREN = 1; // Enable reception
    SREN = 0; // No effect
    TXIE = 0; // Disable tx interrupts
    RCIE = 1; // Enable rx interrupts
    TX9 = 0; // 8-bit transmission
    RX9 = 0; // 8-bit reception
    TXEN = 0; // Reset transmitter
    TXEN = 1; // Enable the transmitter
    }

    Refered below code
    https://exploreembedded.com/wiki/Serial_Communication_with_PIC16F877A
     
    #8
    AMPS
    Super Member
    • Total Posts : 359
    • Reward points : 0
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 04:32:34 (permalink)
    0
    Even it wont work.Receive single byte and print same byte
    void interrupt isr(void)
    {
    ch = Serial_Receive_byte(); // Receive a char from serial port
    Serial_1_Send_byte(ch); // Transmit the received char

    }
    #9
    qhb
    Superb Member
    • Total Posts : 9614
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 04:35:48 (permalink)
    +1 (1)
    Sorry, I' not going to waste any more time here if you're going to keep faffing around inside interrupt services.
     
    #10
    AMPS
    Super Member
    • Total Posts : 359
    • Reward points : 0
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/02 21:37:13 (permalink)
    0
    Here is my code. Below code work fine on PIC18F24K40 but not on PIC16F886
    i am facing issue while receive character and send same character
     

    #include <htc.h>
    #include <stdio.h>
    #include<pic.h>
    //#include<stdint.h>
    #include"delay.h"
    #define _XTAL_FREQ 80000000
    unsigned int i=0;
    unsigned char get_value;

    unsigned char c=0;
    unsigned char ch;
    #define SBIT_TXEN 5
    #define SBIT_SPEN 7
    #define SBIT_CREN 4
     

    #define LED RC2
    #define LED_RX RC7 // Pin assigned RX LED
    #define LED_TX RC6 // Pin assigned TX 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 short int cnt, num,Dgt=0;
    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 int index=0;
    unsigned int rec_flag = 0;

    //__CONFIG( HS_OSC & WDTE_OFF & PWRTE_ON & CP_OFF & BOREN_ON & LVP_OFF & CPD_OFF & DEBUG_OFF);
    __CONFIG( FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF & BOREN_ON & LVP_OFF & CPD_OFF & DEBUG_OFF);

    void Serial_1_Send_byte(unsigned char trbuf1) {
    TXREG=trbuf1;
    while(0==TRMT);
    }

    char Serial_Receive_byte() {
    while(!RCIF);
    return RCREG;
    }
    void Send_string_uart1(const unsigned char *string) {
    unsigned char i=0;
    do {
    TXREG=string[i++];
    while(TXIF==0);
    TXIF=0;
    } while(string[i]!='\0');
    }
    void interrupt isr(void) {
    unsigned char ch;
    //ch=RCREG;
    // Serial_1_Send_byte(ch);
    __delay_ms(5);
    if((PIE1bits.RCIE==1)&&(PIR1bits.RCIF=1)) {
    PIR1bits.RCIF=0;
    //Send_string_uart1("UART TEST");
    // Send_string_uart1("\n");
    //Serial_1_Send_byte(10);
    ch=RCREG;
    Serial_1_Send_byte(ch);
    index++;
    if(index>=20) {
    index=0;
    }
    if(index>=8) {
    rec_flag = 1;
    DE=1;
    }
    }
     
    if(1==RCSTAbits.FERR) {
    RCSTAbits.SPEN=0;
    RCSTAbits.SPEN=1;
    }
    if(1==RCSTAbits.OERR) {
    RCSTAbits.CREN=0;
    RCSTAbits.CREN=1;
    }
    }
     
    void Serial_1_Init() {
    BRG16=1;//1-> 16 bit 0-> 8 bit
    SYNC=0; //0->ASYN 1-SYNC
    BRGH=1;// 0 for LOW baudrate 1 for High
    SPBRG = 207;
    RCIDL=1;
    TXEN=1;//1->Transmit enable 0-> transmit disble
    SPEN=1;//1->enable serial port 0->disable
    CREN=1; //1-> enable continous receive 0-> disble receiver
    INTCON = 0X00;
    TRMT=1;// 1-> Transmit register is empty 0-> full
    CCP1IE=1;
    RCIE=1;
    RCIF=0;
    // TXEN=0;//1->Transmit enable 0-> transmit disble

    }
     
     
    void Timer1_Interrupt() {
    INTCON = 0b00000000;
    PIE1=0b00000001;
    PIR1=0x01;
    TMR1H=0xF8;
    TMR1L=0xAD;
    T1CON=0x31;
    }
     
    void Init_Controller() {
    cnt=100;
    //OSCCON=0X71;
    TRISC = 0x80;
    PORTC = 0x80;
    TRISB=0X00;
    PORTB = 0X00;
    TRISA=0x00;
    PORTA=0x00;
    ADCON0= 0x00;
    ANSEL = 0b00000000;
    Timer1_Interrupt();
    }
     
    void main(void) {
    Init_Controller();
    Serial_1_Init();
    GIE=1;
    PEIE=1;
    TMR1IE=1;

    while(1) {

    }

    }
     

    Attachment(s)

    Attachments are not available: Download requirements not met
    #11
    Aussie Susan
    Super Member
    • Total Posts : 3518
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: Establishing UART communication using PIC16F886 2018/11/04 20:02:45 (permalink)
    +3 (3)
    As others have said, you are going about this in the wrong way.
    The 'Serial_1_send_byte' function should check that the TX side of the UART is ready for you to give it a character and THEN send it. At least in that way, you can leave the hardware to get on with the job while your code does something else.
    However, be aware that whichever way the  the function is written, it is 'blocking' - which means that it will possibly wait for up to the time taken to send a complete character before returning.
    Your 'Serial_receive_byte' function is also blocking.
    Blocking functions are not a problem UNLESS you call them from an ISR. The general principle of an ISR is that is should be quick to run. Remember that while an ISR is running, no other code can be executed.
    What is the point of using Timer1 in this code - you have set it to interrupt but are not processing it in the ISR. This is really bad for you because you are NOT clearing the TMR1IF bit and so, once the timer sets this bit, it will continuously trigger the ISR over and over again. As I said above, while the ISR is running, no other code is executing!
    Take a step back, clear out all of the code except that to initialise the oscillator and the UART, and have your main loop poll for receiving a character and, when it does, check that it can be written to the UART's TX buffer and send it off.
    Once you can echo characters, then start introducing the more advanced techniques (such as interrupts).
    Susan
    #12
    Jump to:
    © 2019 APG vNext Commercial Version 4.5