Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Interrupt Based USART in PIC

Status
Not open for further replies.

Mani Yuvan

Member level 1
Joined
Jan 18, 2015
Messages
41
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Location
Tamilnadu , India
Activity points
321
I want receive and send the data when interrupt occurred. Im familiar with c18 syntax.
when the interrupt occurred i receive the data successfully but i can't receive continuously. i also try the for and while statement in the Service Routine but those not work. I m also newer to Programming..Any one guide me
 

Please post your code, and show us what you are doing
 

Hi,
this my interrupt handler for UART RX in STM8
Code:
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)                                      //uart receive interrupt
{
  if (RX.Counter < sizeof(RX.Buff))
  {
    RX.Buff[RX.Counter] = UART1->DR;
    RX.Counter++;
  }
  UART1->SR&= ~UART1_SR_RXNE;                                                   //clear IT pending bit
}
As you can see, we are checking that input buffer is not full. Than receiving a data, incrementing counter and clearing IT pending bit.
RX is a structure:
Code:
typedef struct
{
  char Buff[50];
  volatile u8 Counter;
}RX_StructTypeDef;
 

don't forget also, to treat error flags inside receive interupt , wich can block the flow of data.. especially with PIC18F

Frame eror and Overrun error ..
 

Please post your code, and show us what you are doing

Code:
#include<p18f452.h>
#include"H:\RECovery RObot\header files\lcd.h"
#define mybit PORTBbits.RB7
void chk_isr(void);
void INT0_ISR(void);
void RC_ISR(void);
void rx_data(void)
unsigned char longi_data[12];
unsigned char lati_data[12];
unsigned char PIR=0,i,data,c[];
#pragma interrupt chk_isr
void chk_isr(void)
{
if(INTCONbits.INT0IF==1)
INT0_ISR();
if((PIR1bits.RCIF)&&(PIR))
RC_ISR();

}
#pragma code My_Hiprio_Int=0X08
void My_Hiprio_Int(void)
{
_asm
GOTO chk_isr
_endasm
}
#pragma code
void main(void)
{
unsigned char a[]={0X38,0X01,0X0c,0X06,0X80};
TRISD=0;
ADCON1=0X07;
TRISEbits.TRISE0=0;
TRISEbits.TRISE1=0;
TRISEbits.TRISE2=0;
TRISBbits.TRISB0=1;
TRISBbits.TRISB7=0;
INTCONbits.INT0IF=0;
INTCONbits.INT0IE=1;
INTCONbits.PEIE=1;
PIE1bits.RCIE=1;
PIR1bits.RCIF=0;
INTCONbits.GIE=1;
en=0;
for(i=0;i<5;i++)
{
lcdcmd(a[i]);
Msdelay(2);
}
TXSTA=0X20;
RCSTA=0x90;
SPBRG=32;
TXSTAbits.TXEN=1;
RCSTAbits.SPEN=1;
RCSTAbits.CREN=1;
while(1)
{
;
}
}
void INT0_ISR(void)
{
mybit=~mybit;
PIR=1;
INTCONbits.INT0IF=0;

}
void RC_ISR(void)
{
PIR=0;
rx_data();

}
void rx_data(void)
{
for(i=0;i<10;i++)
{
data=RCREG;
while(PIR1bits.RCIF==0);
c[i]=data;
lcddata(c[i]);
}
}
this is my code when i check in simulation i receive only single letter or two letter. I m not get full string

- - - Updated - - -

don't forget also, to treat error flags inside receive interupt , wich can block the flow of data.. especially with PIC18F

Frame eror and Overrun error ..

why we clear the overrun error and what is frame error. And place the over run error in service routine ah???
 

Easyrider was referring to function rx_data() that you called in ISR
Code:
void RC_ISR(void)
{
PIR=0;
rx_data();
}

if dont receive data the program get stucks up in ISR.

instead raise some flags and call it in the main function.
 

don't forget also, to treat error flags inside receive interupt , wich can block the flow of data.. especially with PIC18F

Frame eror and Overrun error ..

I write the overun error but I don't know the frame error coding please provide the coding
 

I write the overun error but I don't know the frame error coding please provide the coding

just read deeply datasheet ...

Overrun_frame_error.jpg

example of coding for a 18Fx6K22

Code:
// Gestion IT UART1  sur  Serial com1 19200,N,8,1
  if ((PIE1bits.RCIE == 1)&&(PIR1bits.RC1IF==1)) // si une interruption arrive
  {
   c1 =Read1USART(); // le lire => RAZ  RCIF
  if(RCSTA1bits.FERR==1 )
   {
     RCSTA1bits.SPEN = 0 ;
     RCSTA1bits.SPEN= 1 ;
     c1=0;
      }
   if (RCSTA1bits.OERR==1)    // voir parag 16.1.26 p273
   {
       RCSTA1bits.CREN = 0 ;
       RCSTA1bits.CREN = 1 ;
     c1=0;
     } 
   // CR ou LF ou depassement buffer valide le buffer
   if((c1 != CR) && (c1 != LF) && (i1<=MAX_LEN1)) 
  {
      buff1[i1] = c1;      
      i1++; 
      DataReady1 = 0; 
     }
     else 
      {
      buff1[i1] = 0;         //  0 a la fin du string
      DataReady1 = 1;      // drapeau Data recue
      i1=0;
       }
    PIR1bits.RC1IF=0;      // Raz drapeau IT
  }
 

Now i able to receive data continuously but the problem is i receive misaligned data.:-(
some time undefined symbol also i received.
the modify code is show here.
Transmitting code:
Code:
void main(void)
{
unsigned char b[]={"helooworld"},i;
TRISBbits.TRISB1=0;
PORTBbits.RB1=1;
TXSTA=0X20;
SPBRG=32;
TXSTAbits.TXEN=1;
RCSTAbits.SPEN=1;
while(1)
{
for(i=0;i<10;i++)
{
while(PIR1bits.TXIF==0);
TXREG=b[i];
PIR1bits.TXIF=0;
}
}
}

and below the modify Isr in my receive part
Code:
void RC_ISR(void)
{
read=1;
i=0;
for(i=0;i<12;i++)
{
if(RCSTAbits.OERR)
{
RCSTAbits.CREN=0;
RCSTAbits.CREN=1;
data=0;
}
if(RCSTAbits.FERR)
{
RCSTAbits.SPEN = 0 ;
RCSTAbits.SPEN= 1 ;
     data=0;
      }
while(PIR1bits.RCIF==0);
data=RCREG;
c[i]=data;
PIR1bits.RCIF=0;
}
}

Code:
while(1)
{
if(read==1)
{
i=0;
while(i<12)
{
lcddata(c[i]);
i++;
}
read=0;
}
}

I also attach the proteus file also View attachment external int.zip
 

Please explain in detail about your requirement. I will write a code in mikroC PRO PIC Compiler and post it here.
 

Please explain in detail about your requirement. I will write a code in mikroC PRO PIC Compiler and post it here.

I want receive string nd display on lcd when external interrupt occurred . see my previous post I just transmit hello world! .when interrupt occur receive the string nd display it
 

What PIC and clock frequency are you using ?
 

At receiver side how do you decide that end of UART data is received ? At receiver INT0 can be used to enable or disable UART receive interrupt. How to you know that UART data comes only after INT0 is triggered ?
 

At receiver side how do you decide that end of UART data is received ? At receiver INT0 can be used to enable or disable UART receive interrupt. How to you know that UART data comes only after INT0 is triggered ?
Actually I'm not say like this when interrupt occurred enable serial interrupt nd we receive in buffer and show it on lcd
 

hello

you can decide when you receive the string
- by using a terminator like CR = 0x0D =13 at the end of sending string ("hello wordl \r")
- or by counting the number of char and limit to the LCD display useful width (ie 12 chars maxi)

you don't need to RAZ RCIF.. reading RCREG will do it ..



Code:
volatile int Cpt;
unsigned char c[12];
volatile unsigned char data;

void RC_ISR(void)
{
if(RCSTAbits.OERR)
{
RCSTAbits.CREN=0;
RCSTAbits.CREN=1;
data=0;
}
if(RCSTAbits.FERR)
{
RCSTAbits.SPEN = 0 ;
RCSTAbits.SPEN= 1 ;
     data=0;
  }
data=RCREG;
if ((data==13) || (Cpt >11)   // detecte Carriage return or overlap size of LCD buffer 
 {
 c[Cpt]=0; // string terminator
 Flag=1;
RCSTAbits.SPEN=0; // stop receiving char
 }
else
 {
 c[Cpt]=data;
 Cpt ++;
 }
}
//*************************************
void main()
{

.... etc ...

Cpt=0;
while(1)
{
 if(Flag==1)
 {
 i=0: 
 while(Cpt>0)
 {
  lcddata(c[i]);
  i++;
 Cpt - -;
 }
Flag=0;		// RAZ flag
RCSTAbits.SPEN=1;  // re-autorise reception cars
 } //if flag
} // while
} // main
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top