View previous topic :: View next topic |
Author |
Message |
ra03
Joined: 29 Nov 2012 Posts: 3 Location: London
|
12F683 Development |
Posted: Thu Nov 29, 2012 8:13 am |
|
|
Hello
This is the first time I have needed to use a forum, but this problem has really got me stumped.
I was trying to measure a pulse width using TIMER1, as an internal timer using the gate function on port GP4 of this device. I also enabled INT_RA and tested if GP4 was low (pulse had ended) in the interrupt.
The problem was that interrupts were always occurring ... so I simplified code to that shown below. Interrupts still occur, GPIO register always shows 0x00 and TRISIO shows 0xBF (GP5 and GP3 set) although I set TRIS_A to 0x00 all outputs. I would expect GP3 to be set as it is an input, but not GP5. Lastly I tie GP3 to GND so it is always low and cannot cause interrupt.
Hardware is a 12F683 header assembly (14 pin bonded out device) and REAL-ICE. Although MICROCHIP claims it is a fully bonded-out device allowing the use of all pins, I have my doubts especially as it will not program with GP3 tied to ground. My final attempt was to try a new development board and another REAL-ICE - still the same.
Unfortunately MICROCHIPS Technical Support is unobtainable having some fault!!!! so i turn to you guys - anybody have experience with this device?
Code: |
#FUSES NOWDT, NOPUT, NOPROTECT, NOMCLR, NOPROTECT, NOBROWNOUT
#USE fast_io(a)
#int_RA
void pulse_int(void){
int myvar;
disable_interrupts(INT_RA); // stop angular pulse
myvar = 1;
enable_interrupts(INT_RA); // re-enable angular pulse
}
//*****************************************************************************
void main(void){
setup_oscillator(OSC_8MHZ);
set_tris_a(0b00000000);
enable_interrupts(INT_RA); // interrupt on change of angular pulse
enable_interrupts(GLOBAL);
while(true);
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Thu Nov 29, 2012 8:24 am |
|
|
Key thing with all 'interrupt on change' interrupts, is they can't be cleared, till you read the port pin. This clears the change latch. If the change latch is set, the interrupt _will_ occur (and keep occurring). The latch can't be set once the pin is set as an output, but can _already_ be set (often is at boot). Since you don't read the pin, the interrupt will occur for ever.....
Other comment, there is no point in enabling/disabling the interrupt in the handler. The _hardware_ disables all interrupts when the handler code is called, and only re-enables them the instruction _after_ the return.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
ra03
Joined: 29 Nov 2012 Posts: 3 Location: London
|
|
Posted: Thu Nov 29, 2012 10:34 am |
|
|
Thanks Ttelmah
Code: |
void pulse_int(void){
int1 myvar;
myvar = input(pin_A0);
}
|
As you suggest this fixes it, although it never goes there!! I did know that it was necessary to read the port to clear the latch but am surprised that the latch can get set especially as there is only 1 instruction before I force all pins to be outputs by writing a zero and the state at power-up is latch cleared.
Perhaps it's a peculiarity with this device - never seen it before.
Anyway many thanks - Also I was not aware that CCS interrupt handler disabled and re-enabled interrupt, and I've used them for a long time... |
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu Nov 29, 2012 11:06 am |
|
|
Quote: | Also I was not aware that CCS interrupt handler disabled and re-enabled interrupt, and I've used them for a long time... |
No. The PIC disables interrupts when it goes into the interrupt routine and re-enables them on leaving the routine via the GIE bit. It's not the CCS compiler doing it. For most interrupts, the CCS compiler deals with the individual interrupt flags, interrupt on change being one of the exceptions.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Nov 30, 2012 3:57 am |
|
|
ra03 wrote: | ... but am surprised that the latch can get set especially as there is only 1 instruction before I force all pins to be outputs by writing a zero and the state at power-up is latch cleared. | I don't exactly understand what you mean by '1 instruction'. Which instruction do you mean? The setting of the TRIS-A register? Or another instruction not shown in your code here?
The thing is that before the first C-instruction in your main is executed, the compiler has inserted some start-up code and the delay is a bit longer than you might think.
Also, as I understand it, the write to the TRIS register doesn't clear any INT_RA conditions. Only a read or write to the GPIO register does. |
|
![](templates/subSilver/images/spacer.gif) |
ra03
Joined: 29 Nov 2012 Posts: 3 Location: London
|
|
Posted: Fri Nov 30, 2012 5:42 am |
|
|
Thanks everybody for contributing on this one!
OK to make my point clear - my original code:
Code: |
setup_oscillator(OSC_8MHZ);
set_tris_a(0b00000000);
|
Set all GPIO as outputs (except GP3 of course) so there was only 1 'C' command before this. I accept however that there may well be several lines of instructions generated from/before this.
and the interrupt code:
Code: |
void pulse_int(void){
int myvar;
disable_interrupts(INT_RA); // stop angular pulse
myvar = 1;
enable_interrupts(INT_RA); // re-enable angular pulse
}
|
This code was mainly put there during my attempts at debugging to try to ensure it worked properly.
However interrupts were continuously generated (when enabled) even though all GPIO was set to output and GP3 was tied to GND, INTCON and IOC are set to zero at startup.
Changing the interrupt routine code as suggested to:
Code: |
void pulse_int(void){
int1 myvar;
myvar = input(pin_A0);
}
|
Read (any) pin (latch) fixed this problem - although (according do REAL ICE debugger) it never goes there!
See my point! |
|
![](templates/subSilver/images/spacer.gif) |
|