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.

Interrupt Service Routine blocks microcontroller

Status
Not open for further replies.

DiogoMS

New Member
Hi everyone! I'm developing a project with pics and now i'm testing serial communication through rs232, using a pic, a max232 converter and my laptop.
The problem is simple to explain, but i don't know how to get over it and what i'm doing wrong..
When i establish a communication without using interrupts (Interrupt Service Routine), the communication works just fine. The problem is that i need to use the ISR on the main project. To test the communication with ISR, i created this simple program, but it doesn't work.
Can someone see any programming error or have any suggestion to help me solve this situation?
I'm using MPLAB IDE to develope code, using the compiler HI-Tech ANSI C Compiler..
Thanks in advance!


Here goes the code:



#include <htc.h>

#if defined(_16F877)

__CONFIG(UNPROTECT & XT & DEBUGDIS & LVPDIS & WDTDIS & PWRTDIS & LVPDIS & BORDIS);
#endif


void RS232Conf(void);
void DataArrival(unsigned char Data);
void interrupt rsi(void);
void RS232Tx(unsigned char Tx);


void main(void)
{
unsigned char Rx;

SYNC=0;
TX9=0;
CREN=1;
TXEN=1;
SPEN=1;
BRGH=1;
SPBRG=25;
TRISB=0;
RCIF=0;
TXIF=0;
RCIE=1;
TXIE=0;
PEIE=1;
GIE=1;



RS232Tx('h');
RS232Tx('i');
RS232Tx('!');

while(1)
{
RB3=1;
if(RCIF==1)
{
Rx=RCREG;
DataArrival(Rx);
}
}
}

void DataArrival(unsigned char Data)
{
TXREG=Data;
}


void RS232Tx(unsigned char Tx)
{
while(TRMT==0);
TXREG=Tx;
TXIF=0;
}

void interrupt rsi(void)
{
unsigned char Rx;

if(RCIF==1)
{
Rx=RCREG;
DataArrival(Rx);
}
}
 
Code Correction

That's not the code that i used, that doesn't compile.


#include <htc.h>

#if defined(_16F877)

__CONFIG(UNPROTECT & XT & DEBUGDIS & LVPDIS & WDTDIS & PWRTDIS & LVPDIS & BORDIS);
#endif


//

void RS232Conf(void);
void DataArrival(unsigned char Data);
void interrupt rsi(void);
void RS232Tx(unsigned char Tx);


void main(void)
{
unsigned char Rx;

// RBIE=0;
SYNC=0;
TX9=0;
CREN=1;
TXEN=1;
SPEN=1;
BRGH=1;
SPBRG=25;
TRISB=0;
RCIF=0;
TXIF=0;
RCIE=1;
TXIE=0;
PEIE=1;
GIE=1;


RS232Tx('h');
RS232Tx('i');
RS232Tx('!');

while(1)
{
RB3=1;
//if(RCIF==1)
//{
// Rx=RCREG;
// DataArrival(Rx);
//}
}
}
//


void DataArrival(unsigned char Data)
{
TXREG=Data;
}
//

void RS232Tx(unsigned char Tx)
{
while(TRMT==0);
TXREG=Tx;
TXIF=0;
}
//

void interrupt rsi(void)
{
unsigned char Rx;

if(RCIF==1)
{
Rx=RCREG;
DataArrival(Rx);
}
}
 
The above code works ok for me in ISIS .... However I'm using the built in terminal.... There is a danger that if the data coming in is too fast the "DataArrival()" may still be executing when the ISR triggers again.... This will generate a recursive loop which would bomb out very quickly.

either buffer your input, or slow down incoming data.
 
The problem is that phisically, the pic doesn't even start.. =/

If you think the PIC is not running, then strip out everything and just flash an LED. When you get it running then add your functions back one at a time and debug as you go. One thing I noticed is that you call another function from within the ISR. This is not good practice; a better way is to use a flag variable and set the flag in the ISR, then poll for the flag in your loop.
 
i've made the changes that you all suggested, but the pic doesn't even start too. I've removed the interrupt routine, it works fine. But i need to use other interrupts, far ahead, so i can't skip the interrupt problem because it will happen later.
I've changed the code, but still with no results.. This is the new version but with the same results..

#include <htc.h>


void RS232Conf(void);
void DataArrival(unsigned char Data);
void interrupt peee(void);
void RS232Tx(unsigned char Tx);


int ale=0;
unsigned char Rx;


void interrupt peee(void)
{
if(RCIF==1)
{
Rx=RCREG;
ale=1;
}

}

void main(void)
{

SYNC=0;
TX9=0;
CREN=1;
TXEN=1;
SPEN=1;
BRGH=1;
SPBRG=25;
TRISB=0;
RCIF=0;
TXIF=0;
RCIE=1;
TXIE=0;
PEIE=1;
GIE=1;
RB1=0;
RB2=0;
RB3=0;
RB4=0;
RB5=0;
RB6=0;
RB7=0;


RS232Tx('h');
RS232Tx('i');
RS232Tx('!');

while(1)
{
RB3=1;
if(ale==1)
{
DataArrival(Rx);
}

}
}



void DataArrival(unsigned char Data)
{
TXREG=Data;
ale=0;
}


void RS232Tx(unsigned char Tx)
{
while(TRMT==0);
TXREG=Tx;

}





//Any help will be appreciated, thanks
 
i've made the changes that you all suggested, but the pic doesn't even start too. I've removed the interrupt routine, it works fine. But i need to use other interrupts, far ahead, so i can't skip the interrupt problem because it will happen later.
I've changed the code, but still with no results.. This is the new version but with the same results..
void interrupt peee(void)
{
if(RCIF==1)
{
Rx=RCREG;
ale=1;
}

}

//Any help will be appreciated, thanks

You are missing something in your interrupt routine, a return..
From the HiTechC manual
int tick_count;
void interrupt tc_int(void)
{
if (T0IE && T0IF) {
T0IF=0;
++tick_count;
return;
}
// process other interrupt sources here
}

Hope that helps...
I am not good with interrupts either...
 
try

void interrupt peee(void)
{
if(RCIF==1)
{
RCIF=0 //clear flag
Rx=RCREG;
ale=1;
}
}
 
Last edited:
Yep, in ISIS it works fine.
I'm using a PICDEM 2 PLUS DEMO BOARD, with nothing connected to the INT pins. If i remove the interrupt function, it transmits fine, and if i don't use the interrupt function and use other way to read the RCIF, it communicates just fine. But there's some problem with the Interrupt function..

By the way, when i build the code, it warns me for "missing newline" ...
 
I am missing the
#include "usart.h"
it is also better to

if (RCIF) // usart received char
{
input=getch();

switch (input) // define char weight eq soh etx dle cr lf
{

.... start your protocol when needed
.... update or reset pointer
.... define conditions for wanted

}

if (wanted)

{

Receive_string[pointer]=input

}

}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top