Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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()
{
char uart_read_value;

init_comms();
RCIE = 1;
GIE = 1;
//uart_read_value = getch();
//putch(uart_read_value);
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. :mad:

Kindly let me know the solution to this..

Regards

Sachin
 
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.
 
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
 
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))
        ............
        ADIF=0
    endif

Mike.
 
Last edited:
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))
        ............
        ADIF=0
    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:
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.

Latest threads

New Articles From Microcontroller Tips

Back
Top