Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

pickit2, HiTech C, and 44pin demo board

Status
Not open for further replies.

pmsmith711

Newbie level 3
Joined
Mar 6, 2012
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Southern Cal
Activity points
1,326
I've been working with a new pickit2 using HiTech C and the 44 pin MicroChip demo board (pic 16f887). I've been able to to write short code segments to detect the 'button push' using the INTE interrupt, also I've had success with the Timer0 (TOIE) interrupt, and the A/D converter is working for me. I hit the wall when I attempted to use the ISR. From what I've read all I need to do is build a subroutine in the form "void interrupt <name> (void) {}" and when a flag for an enabled interrupt is set (i.e., INTE is enabled and INTF is triggered), program control should jump to the ISR. Of course the Global (GIE) has to be enabled as well. I can verify that my interrupts are enabled, I can watch the interrupt occur (and the associated flag get set), but I never make the jump to the ISR.

I imagine that this is a common question, yet I haven't found another posting. So here I am. I have a feeling that I'm just doing something globally stupid, but I just don't see it.

Can anyone suggest a setting or configuration parameter that I'm missing? Or perhaps a troubleshooting suggestion?

Thanks in advance.
 

Hi,

I don't do C, but saw this example code for a 877 chip that might help you ...?

// INTEXT.C MPB 10-4-07
// Demo external interrupt RB0 low interrupts foreground output count
#include " 16F877A.h "
#use delay(clock = 4000000)
#int_ext // Interrupt name
void isrext() // Interrupt service routine
{ output_D(255); // ISR action
delay_ms(1000);
}
void main() //********************************************
{
int x;
enable_interrupts(int_ext); // Enable named interrupt
enable_interrupts(global); // Enable all interrupts
ext_int_edge(H_TO_L); // Interrupt signal polarity
while(1) // Foreground loop
{
output_D(x); x + + ;
delay_ms(100);
}
}
 

From what I've read all I need to do is build a subroutine in the form "void interrupt <name> (void) {}" and when a flag for an enabled interrupt is set (i.e., INTE is enabled and INTF is triggered), program control should jump to the ISR. Of course the Global (GIE) has to be enabled as well. I can verify that my interrupts are enabled, I can watch the interrupt occur (and the associated flag get set), but I never make the jump to the ISR.

...
...

Can anyone suggest a setting or configuration parameter that I'm missing? Or perhaps a troubleshooting suggestion?

The issues you are experiencing could be due to several factors.

Please post your code using the CODE Tags (# button) so that one of us can review your code and offer meaningful advice.

BigDog
 

Thanks for the quick replys, i do appreciate it.

As to calling the ISR subroutine ISREXT, the manual states that the name isn't important as long as it is declared with the "interrupt" declaration. I believe that this is working because if I try to force a jump to the subroute (I call it ISR), the compiler faults telling me that programmed jumps to Interrupt Service Routines are illegal (as you might expect). So the compiler (or linker) knows that this is an Interrupt Service Routine. That said, I will try your suggestion.

I'll add the code here, per a request. I've pulled out stuff that I don't think enters into the picture (yeah, I could be wrong). But I believe that this is representative of the problem without alot of clutter.


At the line ( if ( INTCON & 0x02 ) { ), if I have pushed the button, I can see the INTF flag get set. The logic in the 'if' statement works and we drop into the 'if block'. What I expected was to jump to the ISR subroutine as soon as the INTF flag set. I never get to ISR routine.

Thanks again for looking.

Code:
#include <htc.h>

void interrupt ISR(void)
{

//stuff in here;

}

void main(void)
{

unsigned char Bit,Holder, Holder1;	//debug stuff
unsigned char Mask=0xaa;			//debug stuff
unsigned char ByteSize=8;			//debug stuff
int i, Count=0;						//generic counters

static bit TF, IF, ADF;				//flag for the various tests
TF=0;								//Timer test flag
IF=1;								//Interrupt test flag
ADF=0;								//A to D test flag



//Ext Int setup
if (IF) {
  OPTION_REG=0x00;
  INTCON=0x10;		// set INTE; clear GIE, INTF, RBIE, RBIF, TOIE, TOIF
  IOCB=0x03;			// set IOCB0
  PIE1=0x00;
  PIE2=0x00;
  OSCCON=0x60;		//4Mhz internal clock
  ANSEL=0x00;
  ANSELH=0x00;
  WPUB=0x03;			// set pull-ups on INT pins
  TRISB=0x03;
}

TRISC=0x00;
TRISD=0x00;
PORTC=0x00;
PORTD=0xf0;


while (IF) {
  INTCON |= 0x40;				//set PEIE
  INTCON |= 0x80;				//set GIE
  if ( INTCON & 0x02 ) {
    INTCON &= 0x6f;				//disable INTE, GIE
    INTCON &= 0xfd;				//clear INTF
    INTCON |= 0x10;				//enable INTF
	Mask=0x99;
  }
}

}  //end main
 

Just glancing at your code, you should enable the enable both the Peripheral Interrupts and the Global Interrupt in the initialization area of code, outside of the "while" loop.

Try adding these statements to the end of the following block:

Code:
//Ext Int setup
if (IF) {
  OPTION_REG=0x00;
  INTCON=0x10;		// set INTE; clear GIE, INTF, RBIE, RBIF, TOIE, TOIF
  IOCB=0x03;			// set IOCB0
  PIE1=0x00;
  PIE2=0x00;
  OSCCON=0x60;		//4Mhz internal clock
  ANSEL=0x00;
  ANSELH=0x00;
  WPUB=0x03;			// set pull-ups on INT pins
  TRISB=0x03;
[COLOR="#FF0000"]  INTCON |= 0x40;				//set PEIE
  INTCON |= 0x80;				//set GIE[/COLOR]
}

You should also never allow code execution from exiting main(), through the use of a Super Loop "while(1)" or similar structure.

Unlike systems with OSs, Embedded System without an RTOS or scheduler have no way of controlling the flow of code execution once it has left main().

There maybe other issues as well.

BigDog
 

Just to add fuel to the fire, I should mention that the code works (the way I expect) if I run it on the MPLAB simulator. When I toggle the RB0 pin with a 'Stimulus' trigger, the ISR routine is called.

For those of you waiting for the next installment of this tragic story: It seems that the code works (the way I expect) not only when I run on the MPLAB simulator, but also on the pickit2 if I let the MPLAB Debugger 'run'. By 'run' I mean not in 'animated' mode, and not in any sort of step mode. I can set a breakpoint, let the Debugger run, do a 'button push' causing the INT0 line to toggle. The interrupt is detected (as always), but the code is vectored to the ISR. So it seems that something about moving through the code slowly (animated mode or step mode) causes the interrupt to be recognized but not serviced. I still think I have something setup incorrectly and would love some enlightenment or advice.

Thanks.
 
Last edited:

Just glancing at your code, you should enable the enable both the Peripheral Interrupts and the Global Interrupt in the initialization area of code, outside of the "while" loop.

Try adding these statements to the end of the following block:

Code:
//Ext Int setup
if (IF) {
  OPTION_REG=0x00;
  INTCON=0x10;		// set INTE; clear GIE, INTF, RBIE, RBIF, TOIE, TOIF
  IOCB=0x03;			// set IOCB0
  PIE1=0x00;
  PIE2=0x00;
  OSCCON=0x60;		//4Mhz internal clock
  ANSEL=0x00;
  ANSELH=0x00;
  WPUB=0x03;			// set pull-ups on INT pins
  TRISB=0x03;
[COLOR="#FF0000"]  INTCON |= 0x40;				//set PEIE
  INTCON |= 0x80;				//set GIE[/COLOR]
}

You should also never allow code execution from exiting main(), through the use of a Super Loop "while(1)" or similar structure.

Unlike systems with OSs, Embedded System without an RTOS or scheduler have no way of controlling the flow of code execution once it has left main().

There maybe other issues as well.

BigDog

BigDog,

Thanks for the help and advise. I've been remiss at getting back to you, but I'd like to know more about your comment regarding the Super Loop. This sounds like a mistake I'd do well to avoid. So are you saying that calling a function from with a permanent while {while(1)} is dangerous. Or shifting control to an ISR from a permanent while is dangerous? I'm afraid that I don't quite see the structure to which you refer. If you get a minute and can expand a bit on the explanation, I'd appreciate it.

Thanks.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top