|
|
View previous topic :: View next topic |
Author |
Message |
crukid88
Joined: 04 Oct 2007 Posts: 14
|
USART interrupt on 16F876A,can anyone examine? |
Posted: Tue Oct 09, 2007 6:59 am |
|
|
I am a newbie and trying to experiment with interrupts. I browsed the examples included with my compiler. I checked the example and found this part of the code:
#int_rda
void serial_isr() {
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
I was thinking that bgetc() and serial_isr() is a self made function. I hope I am right. So I assumed and made my one but it seems that my PIC freezes. Any tutorial for this topic,pls help. Here is my code below:
#include "C:\Documents and Settings\Crux\Desktop\Design Thesis Research & Development Files\Interrupt Experiment using 16F876A\Interrupt_implementation.h"
char interrupt_message[];
#int_RDA
int RDA_isr()
{
return 1;
}
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
// TODO: USER CODE!!
enable_interrupts(global);
enable_interrupts(int_rda);
putc(21);
Delay_ms(50);
putc(22);
putc(17);
Delay_ms(50);
while(1)
{
if(RDA_isr() == 1)
{
putc(22);
Delay_ms(50);
putc(12);
putc(128);
printf("Interrupt is in");
Delay_ms(1000);
}
putc(22);
Delay_ms(50);
putc(12);
putc(128);
printf("No Interrupts yet");
Delay_ms(250);
printf(".");
Delay_ms(250);
printf(".");
Delay_ms(250);
printf(".");
Delay_ms(250);
}
} |
|
|
Ttelmah Guest
|
|
Posted: Tue Oct 09, 2007 8:00 am |
|
|
The first reason for the freeze is simple. The RDA interrupt handler only gets called, when a character iswaiting to be fetched. The 'interrupt' that causes this, only gets _cleared_, when the waiting character is read. Unless you read the character, the RDA routine will be continuously called, and the program will stop.
Second though, the interrupt routine, is called by the _hardware_. It must _never_ be called from the program, and _must not_ return anything. If you look at the original example you post, it transfers the received byte into a global buffer, and does not attempt to return anything.
To do what you show, use:
Code: |
int1 char_seen=FALSE;
#int_RDA
int RDA_isr() {
int8 dummy;
char_seen=TRUE;
dummy=getc(); //read the character to clear the interrupt
}
//Then in the main, instead of:
if(RDA_isr() == 1)
if (char_seen) {
char_seen=FALSE; //reset this to wait for another character
//Code here to do when the interrupt is seen
|
Best Wishes |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Oct 09, 2007 8:14 am |
|
|
You might want to insert 'ERRORS' into your #use rs232. This will clear any overrun error and keep things from locking up from that.
Ronald |
|
|
crukid88
Joined: 04 Oct 2007 Posts: 14
|
|
Posted: Wed Oct 10, 2007 6:24 am |
|
|
I have a follow questions about the rs232 interrupt,
1.) When an interrupt is invoked is the flag bit automatically turned off when a function is done already on that particular interrupt?
2.) About how many functions can we do on an interrupt?
3.) Is it possible to take strings on a USART interrupt?
4.) How can I retrieve that string? |
|
|
Ttelmah Guest
|
|
Posted: Wed Oct 10, 2007 7:31 am |
|
|
1) - Depends on the interrupt. The compiler automatically clears the interrupt flag, _but_, for things triggered by certain types of hardware event (such as a character waiting), _you_ must clear the event, or the flag will immediately reset.
2) - You should always do as little as possible in an interrupt. The longer you take to handle an interrupt, the greater the risk of missing other interrupt events. Also, to prevent 're-entrancy' (code being called inside itself), _any_ function used in an interrupt, will have the interrupt disabled inside it, if it is used elsewhere outside the interrupt. Interrupt handlers should just handle the interrupt, nothing else.
3) - Characters, are characters. A 'string' in C, is just a sequence of characters, terminated with a '0'. There is nothing special about these characters. The data received by ex_sisr, can be numeric, or text 'strings', and it'll function exactly the same. 'Strings', are not normally sent as 'strings' (the terminating '0', is normally not sent), instead (typically), a character like the line feed, is used as a terminator.
4) - Ex_sisr, shows how. If you want to handle a 'string' specially, then look at the input.h include file, at the function 'get_string', and rewrite this to use the buffered data. ideally monitor the incoming characters in the interrupt, and when the terminator is seen, set a flag. Then in the 'main', when this flag is set, call the function to retrieve the 'string'. This way the code can do other things while waiting (the whole 'point' of the interrupt driven approach).
Best Wishes |
|
|
crukid88
Joined: 04 Oct 2007 Posts: 14
|
|
Posted: Wed Oct 10, 2007 8:00 am |
|
|
I am confused about character waiting,what is that? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|