Hi, can someone help point me in the right direction. I have a simple program that takes push button inputs and then sends them by IR led link to a receiver. It uses the printf function to drive the LED and the KBI on P0 for the p/button inputs.
The program compiles ok and the printf works if I do a printf("rtrt") just before entering the main loop where the program is supposed to sit until a KBI is detected. Problem is I cannot trigger the interrupt. Additionally, I get an L16 'unused code, ignored for . . . etc' message for the interrupt service routine. So, I think that the compiler or linker is not seeing the isr. I don't think its a hardware issue. I've checked wiring and voltage level changes on the P0 pins.
Any thoughts on this?
thanks
Jason
"Additionally, I get an L16 'unused code, ignored for . . . etc' message "
I meant to say tha t this is the message I get when I compile my code.
"I get an L16 'unused code, ignored for . . . etc' message for the interrupt service routine."
You should never get that message for an ISR. If you've correctly created it as an ISR, the compiler would know implicitly that it gets called by the interrupt - so you must be doing some thing wrong.
Please carefully read & follow the instructions for posting source code; use spaces for layout, not TABs; use copy & paste - don't manually re-type; be sure to check it in the 'Preview' before posting!
Andy, here is the code I am using.
/*------------------------------------------------------------------------------ IR Link Jason van Ryan ------------------------------------------------------------------------------*/
extern void keypad_isr(void); /* prototype declaration for keypad iser */
#include <REG922.H> /* special function register declarations */ /* for the Philips P89C922 device */ #include <STDIO.H> /* prototype declarations for I/O functions */ /*----------------------------------------------------------------------------*/
/* push button function defines */ #define power 1 #define mute 2 #define vup 4 #define vdn 8 #define sel 16 #define bat 32 #define test 64 /* put the controller into continuous Tx mode which /* cycles through all the commands and measures battery */ #define bat_test 48 /* continuosly Tx the battery voltage */
/*----------------------------------------------------------------------------*/ void keypad_isr(void) interrupt 7 using 0 { unsigned int command; EKBI=0; /* disable the keypad int */
command = (P0 & 32); /* save the button status and the power status */ //pstat = (P0 & ~32); /* still to add pstat routines here */
TR0 = 1; /* start timer 0. the 38KHz carrier is now running */
switch (command) /* one of the input buttons was pushed - execute the command */ { case power: printf ("pwr\n"); case mute: printf ("mute\n"); case vup: printf ("vup\n"); case vdn: printf ("vdn\n"); case sel: printf ("sel\n"); case test: printf ("test\n"); }
TR0=0; /* done, turn the carrier off */ TxD = 0; /* make sure the TxD pin is LOW after transmission */ KBCON &= 0xFE; /* clear interrupt flag */ EKBI=1; /* enable the keypad interrupt again. Done and exit to main */ }
/*--------------------------------------------------------------------------------*/
void main() { /* first, set up the keypad */
EA=0; /* configure the ports - P0 is all inputs, TxD PP, P1.2 open drain */ P0M1 |= 0xFF; P0M2 &= 0x00;
P1M1 &= 0xFE; P1M1 |= 0x24; P1M2 &= 0xDF; P1M2 |= 0x05;
P3M1 |= 0x03; P3M2 &= 0xFC;
/* set up the keypad interrupt pattern */ KBPATN = 0x3F; // define pattern KBMASK = 0x3F; // define P0 pins that trigger interrupt - port line 0 to 5 KBCON = 0x00; // pattern must not match //KBCON = 0x02; // pattern must match - this line for test purposes
// set isr priority to 1 IP1 &= 0xFD; IP1H &= 0xFD; IP1 |= 0x02;
/* set up the carrier freq - use T0 and toggling P1.2 */ TMOD &= 0xF0; /* T0 is enabled with TR0 = 1; T1 is enables when INT1 is low */ TMOD |= 0x02; /* T0 is set to 8 bit auto reload timer - cycle time is 26.3uS = 37.4KHz */ TAMOD &= 0xFE; TH0 = 0xCF; /* this is the reload value for TL0. Note, the counter increments every 2 clock cycles */ TL0 = 0xCF; P1M1 |= 0x04; /* T0 pin is an open-drain output */ P1M2 |= 0x04; AUXR1 |= 0x10; /* enable toggle output - but do not run the timer until an interrupt */ /* enable keypad interrupt */
/* set up the UART */ SCON = 0x52; /* initialize UART */ BRGR0 = 0x01; /* 300 baud */ BRGR1 = 0x60; BRGCON = 0x03;
KBCON &= 0xFE; /* clear KBI interrupt flag */
EKBI = 1;
EA=1; T0=1; /* WERYRTY just to test if we are running */
printf ("test 123456789 123456789 \n"); TxD = 0; /* make sure TxD port line is LOW */ T0=0; /* turn carroer off */
while (1){}; /* wait here for keypad interrupt */
}
here is the message I am getting
'Warning, uncalled segment, ignored for overlay process SEGMENT: ?PR?Keypad_ISR?HELLO Program Size: Data 32.1 XDATA = 0 CODE = 1407 Creating hex file from Hello "Hello" O Errors 1 Warning
I said:
"Please carefully read & follow the instructions for posting source code; use spaces for layout, not TABs; use copy & paste - don't manually re-type; be sure to check it in the 'Preview' before posting!"
OK, here's a picture for you: www.danlhenry.com/.../keil_code.png
"Please carefully read & follow the instructions for posting source code ..."
Well, that was a bust.
I had a bored moment, so I attempted to tidy up the mess.
After seeing the use of printf in the ISR and the missing breaks, I've decided to not look any further at the OPs specific question.
/*------------------------------------------------------------------------------ IR Link Jason van Ryan ------------------------------------------------------------------------------*/ extern void keypad_isr(void); /* prototype declaration for keypad iser */ #include <REG922.H> /* special function register declarations */ /* for the Philips P89C922 device */ #include <STDIO.H> /* prototype declarations for I/O functions */ /*----------------------------------------------------------------------------*/ /* push button function defines */ #define power 1 #define mute 2 #define vup 4 #define vdn 8 #define sel 16 #define bat 32 #define test 64 /* put the controller into continuous Tx mode which /* cycles through all the commands and measures battery */ #define bat_test 48 /* continuosly Tx the battery voltage */ /*----------------------------------------------------------------------------*/ void keypad_isr(void) interrupt 7 using 0 { unsigned int command; EKBI=0; /* disable the keypad int */ command = (P0 & 32); /* save the button status and the power status */ //pstat = (P0 & ~32); /* still to add pstat routines here */ TR0 = 1; /* start timer 0. the 38KHz carrier is now running */ switch (command) /* one of the input buttons was pushed - execute the command */ { case power: printf ("pwr\n"); case mute: printf ("mute\n"); case vup: printf ("vup\n"); case vdn: printf ("vdn\n"); case sel: printf ("sel\n"); case test: printf ("test\n"); } TR0=0; /* done, turn the carrier off */ TxD = 0; /* make sure the TxD pin is LOW after transmission */ KBCON &= 0xFE; /* clear interrupt flag */ EKBI=1; /* enable the keypad interrupt again. Done and exit to main */ } /*--------------------------------------------------------------------------------*/ void main() { /* first, set up the keypad */ EA=0; /* configure the ports - P0 is all inputs, TxD PP, P1.2 open drain */ P0M1 |= 0xFF; P0M2 &= 0x00; P1M1 &= 0xFE; P1M1 |= 0x24; P1M2 &= 0xDF; P1M2 |= 0x05; P3M1 |= 0x03; P3M2 &= 0xFC; /* set up the keypad interrupt pattern */ KBPATN = 0x3F; // define pattern KBMASK = 0x3F; // define P0 pins that trigger interrupt - port line 0 to 5 KBCON = 0x00; // pattern must not match KBCON = 0x02; // pattern must match - this line for test purposes // set isr priority to 1 IP1 &= 0xFD; IP1H &= 0xFD; IP1 |= 0x02; /* set up the carrier freq - use T0 and toggling P1.2 */ TMOD &= 0xF0; /* T0 is enabled with TR0 = 1; T1 is enables when INT1 is low */ TMOD |= 0x02; /* T0 is set to 8 bit auto reload timer - cycle time is 26.3uS = 37.4KHz */ TAMOD &= 0xFE; TH0 = 0xCF; /* this is the reload value for TL0. Note, the counter increments every 2 clock cycles */ TL0 = 0xCF; P1M1 |= 0x04; /* T0 pin is an open-drain output */ P1M2 |= 0x04; AUXR1 |= 0x10; /* enable toggle output - but do not run the timer until an interrupt */ /* enable keypad interrupt */ /* set up the UART */ SCON = 0x52; /* initialize UART */ BRGR0 = 0x01; /* 300 baud */ BRGR1 = 0x60; BRGCON = 0x03; KBCON &= 0xFE; /* clear KBI interrupt flag */ EKBI = 1; EA=1; T0=1; /* WERYRTY just to test if we are running */ printf ("test 123456789 123456789 \n"); TxD = 0; /* make sure TxD port line is LOW */ T0=0; /* turn carroer off */ while (1) {}; /* wait here for keypad interrupt */ }
Why would you do that?
I'm not an expert Andy, that's why I've posted the problem up on the site
Why can't I use printf in an isr?
ok clear now. Thanks
Do not print in the ISR - just do the absolute minimum you can get away with there.
You define a constant here:
#define bat 32
How many bits are you extracting here?
command = (P0 & 32); /* save the button status and
Remember how many bits you extracted before - how many case statements are possible?
And what do you think happen after printf("pwr\n") - if we ignore the fact that you should not use printf() in the ISR unless someone have proven to you that printf() is reentrant and that your processor is fast enough to take a detour through one of the largest functions in the RTL.
there is nothing in the programming model that prevents you from using 'printf' in an ISR. but it is a "heavy" call in terms of time it takes to complete (bad idea for an ISR) and the code size it consumes (bad idea for a processor with limited on board flash size). it is possible and might be suitable for your needs - but it is not very likely.
Remember Tamir that this is a C51 thread. Consider what will happen if printf() is called from both the ISR and main() at the same time. And since printf() will call a lot of helper functions, a call to printf() may clash with a number of other RTL functions too.
yes of course I should have mentioned that, too.
I've just got the p/button switches connected straight to the input lines - so p/button 1 goes to P0.0, p/button 2 goes to P0.1 etc up to the 6th p/button on P0.5. There's no scanning or mux'ing.
This application is not time critical - there's plenty of time but the point on keeping th e isr's RTL lite is taken.
Specifically though, why is the MCU not jumping to the isr on KBI?
Note the title of my post - I didn't mention printf!
I queried the point of having a prototype for an ISR.
It is pointless - but is it harmless...?