Hi Olin Thanks again for your help. You are preaching to the choir. I am a true believer that knowing what is going on underneath things is the only way to go. (So I will continue to ask questions till you either tire of me or the light comes on which could take a while[:o) I don't know about making sense but it does fix my problem. I have two ISR's in my program. One is a timer that expires so I can check/scan/de-bounce button presses and the other receives characters on the first serial port. Below is the code of my timer/button ISR routine below. Look at the first line. If I comment it out my program will no longer work. If I halt the debugger whilst it is commented out it stops in this routine that is being called over and over....because the hardware is transferring control to this routine? I do believe that it is doing a retfie (underneath) because I don't enable PIR2bits.TMR3IF on exit and it works fine the next time. So I don't believe you when you say that the hardware disables interrupts during an ISR event.....now I may be mixing my chickens with my ducks because my button ISR is a low level ISR and the original serial IRS was a high level but disabling interrupts does fix them both. I think my problem was that my serial ISR was reading the char and clearing the interrupt before control was transferred again by the hardware...at least most times as long as the characters arrived slowly enough when I started sending characters relentlessly eventually the ISR fell behind and before it could read the last char the hardware tried to transfer control to the ISR or some nonsense....as you can see I'm much clearer on what fixed it than what was going wrong.... I also agree that high level languages are no panacea. I have done four projects in the last two years a two 18F452s (assembler), 16F676/690 (assembler) and now this 18F6520 in C. The two first ones have been in the field and I have yet to see a reported bug / failure so whilst my code writing is very slow and there is zero chance I will win any awards for writing efficient code when the stupid stuff is removed what remains usually works ok. My experience is that using a high level language has not even been that much more productive over the assembler I used to write the first projects. My hope is that it will be easier to modify later because this product has some growth into newer products in the near future and I'll have to design some RF stuff then expand this code and that it will be easier for me to pick up where I left off in C than in assembler. void detect_button_push_ISR(void) { PIR2bits.TMR3IF = 0; //disable the timer3 interrupt WriteTimer3(BUTTON_TIMER_RELOAD_4MHZ_CLK); if (!PORTBbits.RB3) { UP_cnt++; // if this bit is low then you have a button/switch closure don't be confused by the UP it is the button switch name not something going up or down } else { UP_cnt =0; //if it did not last for number_of_samples timeouts then it is noise so reset the counter look for antoher button/switch press } if (UP_cnt == number_of_samples) { UP_valid = 1; // we got requisite number_of_samples so must be a valid button press UP_cnt = 0; // now I'm looking for a switch open unless of course hold_it is true. } if ((PORTBbits.RB3) && (UP_valid) && (!(hold_it))) // need a button/switch open if hold_it is false { UP_valid = 0; push_button_event(up); } if ((UP_valid) && (hold_it)) { UP_valid = 0; //if you have pushed a command for a valid event then clear it and start over push_button_event(up); //if the hold_it bit is set then we push a command without waiting for the switch/button to be opened } if (!PORTBbits.RB4) { DN_cnt++; // if this bit is low then you have a button/switch closure don't be confused by the DN it is the button/switch name name not something going up or down } else { DN_cnt =0; //if it did not last for number_of_samples timeouts then it is noise so reset the counter look for antoher button/switch press } if (DN_cnt == number_of_samples) { DN_valid = 1; DN_cnt = 0; } if ((PORTBbits.RB4) && (DN_valid) && (!hold_it)) { DN_valid = 0; push_button_event(dn); } if ((DN_valid) && (hold_it)) { DN_valid = 0; //if you have pushed a command for a valid event then clear it and start over push_button_event(dn); //if the hold_it bit is not set then we push a command without waiting for the switch/button to be opened } if (!PORTBbits.RB5) { ENTR_cnt++; // if this bit is low then you have a button/switch closure don't be confused by the ENTR it is the button/switch name } else { ENTR_cnt =0; //if it did not last for number_of_samples timeouts then it is noise so reset the counter look for antoher button/switch press } if (ENTR_cnt == number_of_samples) { ENTR_valid = 1; ENTR_cnt = 0; } if ((PORTBbits.RB5) && (ENTR_valid)) { ENTR_valid = 0; push_button_event(enter); } } Thanks in advance Olin et al. Phillip Things should be as simple as possible but no simpler Phillip Coiner CTO, GPS Source, Inc. Your source for quality GNSS Networking Solutions and Design Services, Now! -----Original Message----- From: piclist-bounces@mit.edu [mailto:piclist-bounces@mit.edu] On Behalf Of Olin Lathrop Sent: Wednesday, June 28, 2006 6:58 AM To: Microcontroller discussion list - Public. Subject: Re: [PIC] C18 resource remaining metric/test Phillip wrote: > I was not disabling interrupts during my ISR. > Now that interrupts are off and I'm not calling my c routine recursively > things are much better behaved. This again makes no sense. The hardware disables interrupts when the ISR is entered. The ISR re-enables interrupts by using the RETFIE instruction when it returns to the foreground code. You should not otherwise be messing with interrupt enable/disable in the ISR. > I'm not sure why calling the getcUSART1 from my ISR is such a bad idea. Using a high level language, particularly in the ISR, is a bad idea especially when you're not clear what is really going on. Many people here, including me, always say to do your first few PIC projects in assembler until you have a solid understanding of the machine and the instruction set. Only then should you be allowed to use a high level language. Otherwise you run into exactly the kind of situation you did, where strange things are happening and you can't figure out what because things are going on under the hood that you don't understand. Let this be a lesson to you and everyone else from the instant gratification crowd that thinks they can get away with not understanding the low levels and jump right into using a HLL on a PIC. Other reasons for avoiding HLL in the ISR is that the compiler has to save/restore a lot more state than really neccessary (take a look at the generated instructions some time), if any code is speed-critical it's probably the ISR, and calling subroutines from the ISR uses up stack locations not available to any other code. ****************************************************************** Embed Inc, Littleton Massachusetts, (978) 742-9014. #1 PIC consultant in 2004 program year. http://www.embedinc.com/products -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist