+ Post New Thread
Results 1 to 2 of 2
  1. #1
    Member level 2
    Points: 353, Level: 4

    Join Date
    Aug 2018
    Posts
    46
    Helped
    0 / 0
    Points
    353
    Level
    4

    UART communication using intrrupt on PIC16F886

    I am using PIC16F886 to build Interrupt code serial.i Have tested code with pic18F24K40 and its working fine. I have attached code and image for reference. pic18F24k40 uses MPLAB X ide with MCC code configuration. for PIC16F886 it uses MPLAB IDE8.86 code version.I am facing issue in PIC16F886 with receive single byte and transmit single byte of data.

    Here is my code for PIC16F886. if i am trying to send any character like 01 it printing 00 instead of 01
    Code:
    #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) {
    
    
    	}
    
    
    }
    PIC18F24K40

    Code:
    #include "mcc_generated_files/mcc.h"
    #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], ser_data[100], crc_data[100], 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 k;
    
    void Serial_1_Send_byte(uint8_t trbuf1) {
    	TX1REG = trbuf1;
    
    	while (0 == PIR3bits.TXIF);
    
    //while (!TX1IF);
    
    }
    
    
    void Send_string_uart1(const unsigned char *string) {
    	unsigned char i = 0;
    
    	do {
    		TX1REG = string[i++];
    		while (0 == TX1STAbits.TRMT);
    	} while (string[i] != '\0');
    }
    
    char Serial_Receive_byte() {
    
    	while(0==PIR3bits.RCIF);
    	return RC1REG;
    
    }
    
    char usart_RxString() {
    
    	while(*str !='\0') {
    		// while not end of string
    		while(0==PIR3bits.RCIF);
    		RCREG = *str;            // read next character
    		str++;                    // increment pointer to next character
    	}
    	return RC1REG;    // return the contents of uart
    }
    
    
    void UART_ISR() {
    	if((PIE3bits.RCIE==1)&&(PIR3bits.RCIF=1)) {
    		PIR3bits.RCIF=0;
    		rxbuf[index] = Serial_Receive_byte();
    		Serial_1_Send_byte(rxbuf[index]);
    		index++;
    		if(index>=20) {
    			index=0;
    		}
    		if(index>=8) {
    			rec_flag = 1;
    			DE=1;
    		}
    
    	}
    
    
    
    	if(1==RCSTA1bits.FERR) {
    		RCSTA1bits.SPEN=0;
    		RCSTA1bits.SPEN=1;
    	}
    	if(1==RCSTA1bits.OERR) {
    		RCSTA1bits.CREN=0;
    		RCSTA1bits.CREN=1;
    	}
    
    }
    
    
    void main(void) {
    	// Initialize the device
    	SYSTEM_Initialize();
    
    	while (1)
    
    	{
    		__delay_ms(100);
    
    	}
    
    //}
    
    }


    Click image for larger version. 

Name:	Uart_string_print.png 
Views:	6 
Size:	102.8 KB 
ID:	149832Click image for larger version. 

Name:	uart_char_print.jpg 
Views:	5 
Size:	202.2 KB 
ID:	149831Click image for larger version. 

Name:	PIC18F24k40.JPG 
Views:	4 
Size:	210.5 KB 
ID:	149830Click image for larger version. 

Name:	Send_receive error.jpg 
Views:	4 
Size:	171.3 KB 
ID:	149829

    •   AltAdvertisement

        
       

  2. #2
    Super Moderator
    Points: 80,586, Level: 69
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    13,205
    Helped
    4410 / 4410
    Points
    80,586
    Level
    69

    Re: UART communication using intrrupt on PIC16F886

    Never going to work!

    Your ISR is quite wrong. Never add delays inside an ISR and certainly never try to re-transmit an incoming byte from within the ISR. Consider that the TX and RX baud rates are the same so the time to transmit and receive a byte is the same. By waiting to receive a byte to start the ISR then within it waiting for a byte to be sent (polling TMRT) you are almost certain to miss the next incoming byte and cause an overflow condition.

    Your ISR should detect the RX interrupt, recover the incoming byte and exit as quickly as possible so further interrupts can be processed. Let the 'main()' part of your code handle the transmitting routines.

    Brian.
    PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
    It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.



--[[ ]]--