# Regading UART Interrupt on PIC16F877

Status
Not open for further replies.

#### tiwari.sachin

##### New Member
Hello

I am trying the code for uart in interrupt mode.

My code works fine when i am not using it in interrupt mode.

Somewhere round my interrupt service routine seems to be wrong. I am not really familiar with interrupt usage.

My main code is as follows

#include<htc.h>
#include "usart.h"

int main()
{

init_comms();
RCIE = 1;
GIE = 1;
while(1)
{
CLRWDT();
}
}

void interrupt ISR_high(void)
{
char input;

if((RCIF) && (RCIE))
{
// Overrun error bit
//if(OERR) //
//{ //
// CREN=0; // Restart USART
// CREN=1; //
//} //

// If error ...
//if(FERR)
//{
// Flush buffer
// RCREG=RCREG;
// RCREG=RCREG;
// RCREG=RCREG;
//}
//else
//{
input = RCREG;
putch(input);
//}
}
}

usart.c

#include <htc.h>
#include <stdio.h>
#include "usart.h"

void
putch(unsigned char byte)
{
/* output one byte */
while(!TXIF) /* set when register is empty */
continue;
TXREG = byte;
}

usart.h

#ifndef _SERIAL_H_
#define _SERIAL_H_

#define BAUD 9600
#define FOSC 4000000L
#define NINE 0 /* Use 9bit communication? FALSE=8bit */

#define DIVIDER ((int)(FOSC/(16UL * BAUD) -1))
#define HIGH_SPEED 1

#if NINE == 1
#define NINE_BITS 0x40
#else
#define NINE_BITS 0
#endif

#if HIGH_SPEED == 1
#define SPEED 0x4
#else
#define SPEED 0
#endif

#if defined(_16F87) || defined(_16F88)
#define RX_PIN TRISB2
#define TX_PIN TRISB5
#else
#define RX_PIN TRISC7
#define TX_PIN TRISC6
#endif

/* Serial initialization */
#define init_comms()\
RX_PIN = 1; \
TX_PIN = 1; \
SPBRG = DIVIDER; \
RCSTA = (NINE_BITS|0x90); \
TXSTA = (SPEED|NINE_BITS|0x20)

void putch(unsigned char);

I am confused with void interrupt ISR_high(void) call for ISR, Is it right what i am doing. If not what should i be doing..

I can see RCIF and RCIE bit being set and RCREG also has the uart value in it.

When i have a breakpoint in ISR, the code never comes there.

I am not clear how to call the ISR.

Kindly let me know the solution to this..

Regards

Sachin

#### Pommie

##### Well-Known Member
Your interrupt is not working because you aren't enabling peripheral interrupts. Try adding the line in red,

Code:
RCIE = 1;
[COLOR="Red"]PEIE=1;[/COLOR]
GIE = 1;

Mike.

#### tiwari.sachin

##### New Member
Your interrupt is not working because you aren't enabling peripheral interrupts. Try adding the line in red,

Code:
RCIE = 1;
[COLOR="Red"]PEIE=1;[/COLOR]
GIE = 1;

Mike.

Thanks Pommie

Will check and see if it works

Can you let me know how can i write ISR names. I am quite confused with this. There is a particular address from where the ISR should start.

On what parameters should I decide these names.

If I am using say ADC INTR and UART INTR, how should I write.

Kindly Help

#### Pommie

##### Well-Known Member
You can call your ISR anything you want. The important thing is the interrupt keyword, this tells the compiler to point the interrupt vector to this routine.

You can only have one interrupt. If you have multiple devices interrupting then you have to poll their flags. As you are doing for the RCIF you would do the same for the ADIE and ADIF. IE,
Code:
    if((ADIF) && (ADIE))
............
endif

Mike.

Last edited:

#### tiwari.sachin

##### New Member
You can call your ISR anything you want. The important thing is the interrupt keyword, this tells the compiler to point the interrupt vector to this routine.

You can only have one interrupt. If you have multiple devices interrupting then you have to poll their flags. As you are doing for the RCIF you would do the same for the ADIE and ADIF. IE,
Code:
    if((ADIF) && (ADIE))
............
endif

Mike.

Thanks Pommie

I was under the impression that we need to have different names for different interrupts.

So its just a single ISR and i need to keep a check on flags to see what needs to be serviced.

But it does take a few extra machine cycles. Cant i write different ISR for different interrupts.

Anyways first things first. I would first check out this and then go on with next part.

Thanks again

Last edited:

#### Pommie

##### Well-Known Member
On the 16 series chips there is only 1 interrupt vector and so you have to poll if you have more than 1 enabled. On the 18 series there are two vectors with different priorities.

Mike.

Status
Not open for further replies.

Replies
1
Views
1K
Replies
8
Views
2K
Replies
3
Views
2K
Replies
2
Views
2K
Replies
5
Views
3K