Hi all, New to this forum in a posting perspective but it's been a great help in a lot of areas from the start of my 8051 classes this year and last year so for that thanks. Im coming near the end of my final year project and I'v come across a slight problem with my interrupt implementation. I have RTFMed about all I can find on interrupts from any number of sources before you tell me to Please read the manual. The problem is that my ISR is triggered fine the first time sets a flag goes back carries out a function ... due to it not being a good idea to have function calls within an ISR ... resets flag and then sits reading the clock again however when I try to interrupt again it will not carry out the ISR this next time.
I have : reset external interrupt flag; reset condition variable flag; even attempted to re-enable external interrupt (even though this is probably not required);
The code is a long one so Id rather not post the entire thing here if anyone wants to take a look at it who has a good idea as to what I'm doing wrong or if anyone wants to suggest a specific part to post to look at the ISR or the menu its being called from please contact me. I will however not be sending this code on to anyone who's just looking for something to copy as I've read the manual to get it this far. I'd also be very happy to have someone look over the code in general for bad programming implementation if they would ... I'm a student in this subject but I've a keen interest in the field.
Also I'm Irish but this website is picking me up in America for some reason ?
Regards Robbie.
What I mean is, you need to construct a test that will indicate "fail" if any mismatch is found.
If your ISR is expected to trig by an external-interrupt pin, then you shouldn't also have any "receive()" in that interrupt.
Create a UART ISR that trigs, picks up single characters and places in a queue.
Then have other code consume characters from this queue to try to figure out if you have a complete code. Obviously taking into account incomplete transfers where the UART doesn't get a complete number for some reason and might later restart a new transfer.
If your RFID unit sends digits and ends the stream with a newline character, then you could have your serial code set a flag when it sees the newline, and the main loop reacts to the flag, scans the received data and accepts/rejects.
Too much data before the newline? Throw away all characters until you either gets a longer pause or a newline character.
Long pause after digits but before a newline? So timeout the received data and wait for a new transfer.
But don't try to do too much in an interrupt handler.
Right so in reply to Andrew(hope you don't mind me using your first name) I have changed the check to this:
if (card_id[13] == kite1[13]) { for (i=2;i<14;i++) { if (card_id[i]!=kite1[i]) { writedata('E'); writedata('R'); writedata('R'); writedata('O'); writedata('R'); writedata('1'); return; } } kite1_f = 1; delay(10000); IE = 0; }
Hope thats a bit better, kind of quickly thrashing out code here maybe I should take some time with the problem ?
In reply to Mr Westmark : Hello there and thanks would I be correct in assuming when you are talking about placing in a queue you are talking about an array or is there some other construct for this implementation? I'll show you my current recieve(); function below but it appears that my function is currently working for the first external interrupt but then failing to trigger in the second instance however from my debugging I can see its not sticking inside the ISR just not recognising it. Also go easy on me when you see this recieve function as it was the first time I wrote anything for serial communication.
void receive() //Function to receive data serialy from RS232 { unsigned char k; for(k=0;k<14;k++) { while(RI==0); card_id[k]=SBUF; RI=0; } }
Two things.
You have some paths of your ISR that do IE=0. But you also have paths that only do "return". Every single path out of your ISR must make sure that you leave the processor in a state where it will be able to react to a new interrupt.
Next thing.
And ISR should enter, do a very quick job and then leave.
You have an ISR that calls receive(). And receive() may take forever since it will not end until a fixed number of serial characters are received. But what if there are no characters to receive?
Rework it so you have zero delays and zero loops waiting for any events inside all of your interrupt handlers.
Yes - an array is a good primitive for creating a queue. Just that if you read up on "round robin" or "circular buffer", you'll see examples of how an array is used with one insert pointer and one read-out pointer, allowing an interrupt handler to insert received data, while the main loop reads out and processes data.
Such a buffer also works for outgoing data - you can insert multiple characters into a send buffert, and have a serial interupt handler pick up the characters one-by-one as the UART gets ready for more data. Your code that prints multiple characters in the interrupt handler will have to wait for the actual transmit speed of the UART since you emit multiple characters and then busyloops waiting for the ready flag from the UART.