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.

[SOLVED] PIC18F Interrupt on Change, without a change!?!?

Status
Not open for further replies.

milesguidon

Member level 2
Joined
Dec 4, 2010
Messages
52
Helped
8
Reputation
16
Reaction score
8
Trophy points
1,288
Location
Los Angeles, CA
Activity points
1,753
Hi,

I think I'm seeing my microcontroller behave in an unpredictable way, and I know I'm wrong because computers usually have a good reason to do what they're doing...but I still can't figure it out.

I have configured the PIC18F to interrupt on a logic transition at pin RB5. It does work, and inside the ISR I can perform logic tests such as "if PORTBbits.RB5==1, do this" and "if PORTBbits.RB5==0, do this". I have a logic analyzer and I am seeing everything clearly as far as logic transitions and indications that my routines are taking place successfully (I usually use a dedicated LED, and insert blink() commands to see if something has happened predictably or not).

My problem right now is in my ISR--I am incrementing a counter every time there is a low-to-high or a high-to-low transition, so every time the ISR runs, the counter is incremented. In my main routine, I have a blink() command set to execute every time the counter reaches a value of 20. When the counter reaches 20, there's a blip on the logic analyzer, and the counter resets. My problem is that *this blip happens after only FOURTEEN low-to-high or high-to-low transitions*, as I count them by sight on the logic analyzer!! The logic transitions on the input pin are clear as day--it's a SMPTE timecode signal, which is something like a Manchester encoded signal at 2.4kHz.

I am thinking that there is some sort of odd condition that is causing the interrupt on change to interrupt twice while the input is high, but my logic input is coming from a comparator output with a 3kohm pull-up resistor.

Does this problem sound familiar to anybody? Thanks!
 

Hi,

Decimal 20 = Hex 14 - have you got your counters mixed up somewhere ?
 

Hmm...that's true, but that may be a coincidence? My counter is an "unsigned long", and my action in the ISR is "transitionCounter++;"

Would this really take only 14 instances of "transitionCounter++;" for an "if (transitionCounter==20)" statement to be true?
 

Hmm...that's true, but that may be a coincidence? My counter is an "unsigned long", and my action in the ISR is "transitionCounter++;"

Would this really take only 14 instances of "transitionCounter++;" for an "if (transitionCounter==20)" statement to be true?

Hi,

Afraid I cannot help with the C code, but to find yor problem I would remove the existing signal and replace it with a switch and pull up and manually operate it and see what happens on 14 or 20 switches ? You might have to add a small delay to act as a switch debounce.

Also if you have a Pickit or ICD run your program in Debugger mode using a breakpoint in the ISR, then single step though the ISR so you can check the registers and your variables being updated in the Watch window.

Not sure how its worked in C but is RB5 the only port enabled for interrupt on change, are the others RB4-7 also enabled, are they pulled up or left floating ?
 

20/14 seems to be a coincidence.

What's the max frequency (min period) of your signal/transition? What's the sampling rate of you logical analyzer?
 

The pulse width minimum is 220microseconds, and my internal oscillator is 16MHz. I realize I only have 220*16 clock cycles to do what I want, so my ISR has to be very lean, and especially so, since I'm writing in C.
 

The pulse width minimum is 220microseconds, and my internal oscillator is 16MHz. I realize I only have 220*16 clock cycles to do what I want, so my ISR has to be very lean, and especially so, since I'm writing in C.

That's a quite low frequency as far as the capacity of a logical analyzer is concerned. Almost every logical analyzer can correctly handle that.

One debug technique I'm using is to use an unused pin as output and change its level at the beginning and end of the ISR and observe this change with an LA. By observing both RB5 and this pin with 2 separate channels would give you an idea of whether all events have been properly dealt with.
 
Last edited:
I suppose I misunderstood your question--the logic analyzer can sample much more quickly than my signal period--I'm having no issues with what I'm seeing on my logic analyzer. I am doing what you said about pulling a pin high and low at the beginning and end of the ISR--the curious thing I am seeing is that it takes about 200us after a pulse rising edge for the pin to get pulled high, even though pulling the pin high is virtually the first thing that the ISR is instructed to do.

Logic change -> ISR -> Clear RABIF interrupt flag -> Pull test pin high -> store result of ReadTimer0() in variable -> increment counter variable -> pull test pin low

I see (on my logic analyzer) that the test pin going high and low somewhere in the middle of the pulse. It SHOULD be going high at the rising edge, I think, and low shortly thereafter. I see no reason for a delay of >200us before the test pin is pulled high. Maybe I have some unseen behavior going on in the PIC behind the scenes? Maybe I have not disabled some default functionality, and it is unexpectedly slowing me down?
 

Hi,

Assume you haven't got a frequency counter to check how many pulses are actually coming in, despite your LA viewing.

Your earlier comment of 220 x 16 is not correct.

16Mhz oscillator is /4 for a machine cycle, many 18F instructions take 2 or 3 cycles ( in assembler form ) so you doubtless have less time than you thought.

Why don't you set up a much more simpler pulse counter test with your pic, just loop / read the state on an i/o pin and increment a counter when it changes, that only takes a few instructions and all the delays of the ISR with be eliminated.
When the counter get to 20, rather than blip why not just toggle an i/o so that you can see a high or low on your LA for the duration of hopefully 20 pulses rather than your blip.

hth
 
This is good advice--start simple.

I suppose I dove right in, focusing too much on my decoding algorithm (it's SMPTE timecode I'm trying to decode), rather than fully understanding the basics.

Thanks for continuing to offer advice. I'll keep with this thread and let you know how it goes.
 

when you get the IOC interrupt are you doing a READ of the port BEFORE clearing the interrupt? and do this at the end of your isr ?

ie MOVF _ISerialRxPort,0 ;read the port
BCF INTCON,RAIF

retfie


also additionally to handle your IOC in the isr along with other interrupt sources (flags) you should check IOC enabled flag because the int flag gets invariably set when doing io
 
Last edited:

I suppose I misunderstood your question--the logic analyzer can sample much more quickly than my signal period--I'm having no issues with what I'm seeing on my logic analyzer. I am doing what you said about pulling a pin high and low at the beginning and end of the ISR--the curious thing I am seeing is that it takes about 200us after a pulse rising edge for the pin to get pulled high, even though pulling the pin high is virtually the first thing that the ISR is instructed to do.

... ...

Yes, the test pin's transit timing should align with RB5 change pulses quite perfectly.

1. Could you post your configuration settings?
2. Try to isolate the bug by disabling the irrelevant code temporarily.
 

Thank you all for your help. I decided to stop hammering my way through this using an interrupt-on-change, and just switch the microcontroller to a PIC with an input capture module that could capture input on a L2H and H2L transition. The PIC I was using did have input capture, but not on both L2H *and* H2L transitions, which is what I needed.

Anyway, I switched to a PIC24F04KA200 (the only other one I had in my components cabinet), and the capture worked flawlessly. I was able to develop my algorithm, and I've reached my end goal--which was to wirelessly receive an audio signal containing Manchester-encoded SMPTE timecode from a film studio, decode it, and display it real-time on an LCD display.

Thanks everybody.
 

As far as I know, the CCP module of PIC18F is capable of capturing L2H and H2L transitions. (This switching back and forth should be implemented in program dynamically.) Indeed I'm using it (a PIC18F4550) for IR signal decoding.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top