I have PIC16F628A that I am trying to have read from UART. Without interrupts, it reads the first 3 bytes fine but hits an OERR. To combat this, I thought an interrupt would be good and load any received bytes into a buffer variable that could be read in later (ring buffer of array type char). But the interrupt is not triggering and I've run out of ideas.
CMCON = 0x07; //16F627/8 spcial function reg (RAx is port)
CCP1CON = 0b00000000; //Capt/Comp/PWM off
OPTION_REG = 0b00000000;
T1CON = 0;
INTCON = 0;
PIR1 = 0;
GIE = 0;
PIE1 = 0;
BRGH = 1; /* high baud rate */
SPBRG = 19200; /* set the baud rate */
SYNC = 0; //Async
TXEN = 0; //Disable transmit
TXIE = 0; //Disable transmit interrupt
RCIE = 1; //Enable Receive interrupt
SPEN = 1; //Enable serial pins
CREN = 1; //Enable continuous receive
SREN = 0;
TX9 = ninebits?1:0; /* 8- or 9-bit transmission */
RX9 = ninebits?1:0; /* 8- or 9-bit reception */
PEIE = 1; //Enable external interrupt
GIE = 1; //Enable global interrupt
I have simplified my interrupt to turning on a light:
extern interrupt isr(void)
{
RB5 = 1;
}
But it's not triggering. The project is reading a barcode scanner over serial and processing the barcode. Can anyone offer some assistance?
EDIT
Ok since you don't seem to understand. I'm going to post the actual routines:
void initialize()
{
CMCON = 0x07; //16F627/8 spcial function reg (RAx is port)
CCP1CON = 0b00000000; //Capt/Comp/PWM off
OPTION_REG = 0b00000000;
T1CON = 0;
INTCON = 0;
PIR1 = 0;
GIE = 0;
PEIE = 0;
PIE1 = 0;
sci_Init(BAUDRATE ,SCI_EIGHT);// Baud set and Bit set
TMR0 = 1000;
T0IE = 0;
PEIE = 1; //Enable external interrupt
GIE = 1; //Enable global interrupt
//Set inputs to input
SetButtons();
//Set relays to output
SetRelays();
TRISB5 = 0;
LEDStatus = 0;
}
unsigned char sci_Init(unsigned long int baud, unsigned char ninebits)
{
int X;
unsigned long tmp;
/* calculate and set baud rate register */
/* for asynchronous mode */
tmp = 16UL * baud;
X = (int)(FOSC/tmp) - 1;
if((X>255) || (X<0))
{
tmp = 64UL * baud;
X = (int)(FOSC/tmp) - 1;
if((X>255) || (X<0))
{
return 1; /* panic - baud rate unobtainable */
}
else
BRGH = 0; /* low baud rate */
}
else
BRGH = 1; /* high baud rate */
SPBRG = X; /* set the baud rate */
SYNC = 0; //Async
TXEN = 0; //Disable transmit
TXIE = 0; //Disable transmit interrupt
RCIE = 1; //Enable Receive interrupt
SPEN = 1; //Enable serial pins
CREN = 1; //Enable continuous receive
SREN = 0;
TX9 = ninebits?1:0; /* 8- or 9-bit transmission */
RX9 = ninebits?1:0; /* 8- or 9-bit reception */
rxBuffIndex = 0;
rxBuffRead = 0;
return 1;
}
void sci_LoadBuffer(void)
{
rxBuffer[rxBuffIndex] = RCREG;
rxBuffIndex = ++rxBuffIndex % MAXBUFFER;
}
unsigned char sci_ReadBuffer()
{
unsigned char byte;
do
{
byte = rxBuffer[rxBuffRead];
}while( byte == 0 ); //Block until valid data
rxBuffer[rxBuffRead] = 0;
rxBuffRead = (++rxBuffRead) % MAXBUFFER;
return byte;
}
void interrupt isr(void)
{
if(RCIF) sci_LoadBuffer();
LEDStatus = 1;
}
I know that's not EVERYTHING but that should be enough to diagnose why the interrupts aren't triggering. THAT'S ALL I NEED! Triggering the interrupts.
I'm using MPLab with Hi-Tech C Compiler. Which from the manual automatically saves state and restores it when entering/exiting the interrupt.
Best Answer
TRISB1 needs to be set to 1 to configure RB1 (RX) as an input. I'm not sure what the default is, so it may be ok.
You need to clear the receive interrupt flag (RCIF) by reading the receive register (RCREG). In addition, since the receive register is doubled-buffered, you may need to read it more than once.
So your interrupt routine needs to look more like this:
I don't know if that is your only problem, since you indicate you are not getting into the interrupt routine at all. But the above is the correct way to read the characters out of the receive buffer.
======================================
EDIT:
Don't know if this will help or not, but in this post, before enabling interrupts, the code clears out the FIFO first. (Their code also clears out the RCIF flag, but since it is readonly on your chip, that isn't needed.)