PDA

View Full Version : Am I stupid? Goto does not GOTO??? Where's the bug??



xnihilo
- 13th October 2008, 14:17
I have this code in an int handler




'check what pin triggered the int
'we have the time of the header pulse to manage that work
if (head == 0) THEN
pin = 0 'set the number of the pin for the score managment (update_scores)
GOTO got_pin 'bypass
ENDIF
if (front == 0) THEN
pin = 1
GOTO got_pin 'bypass
ENDIF
if (back == 0) THEN
pin = 2
GOTO got_pin 'bypass
ENDIF
if (larm == 0) THEN
pin = 3
GOTO got_pin 'bypass
ENDIF
if (rarm == 0) THEN
pin = 4
GOTO got_pin 'bypass
ENDIF
'if (porta.5 == 1) THEN
' pin = 5
' GOTO got_pin 'bypass
'ENDIF
'ELSE:
LCDOUT $fe,1,"0pin = ",#pin
PAUSE 2000

pin = 111

got_pin:

'TEST block
LCDOUT $fe,1,"1pin = ",#pin
GOTO finish



I was expecting to have a display of "1pin = " and the pin nr but guess what I guess:

"0pin = " and the pin number.
It completely ignores my GOTO got_pin.
How can it be??
I've spen many hours working on my program so maybe the error is so obvious I don't see it...

Could someone open my eyes please?

Bruce
- 13th October 2008, 14:40
What happens if you insert a PAUSE 2000 after the LCDOUT in got_pin?

Or try goto finish just above got_pin so it doesn't fall-through to got_pin
on 2nd entry if no pins are 0?

Edit: Also, make sure when you GOTO another routine from your interrupt
that the routine isn't outside the DISABLE/ENABLE block. If you do it returns
to the beginning of your interrupt handler.

xnihilo
- 13th October 2008, 15:58
I don't know because I changed the code meanwhile but anyway, as there is an LCDOUT $fe,1 the next LCDOUT would overwrite "0pin..." and it does not.
"finish" is the label at the bottom of the int handler and nothing else will overwrite what is displayed so it shows the GOTO is ignored.

Ever worse, in another part of the code I'm checking what pin has triggered the interruption and I can read port 0 to 3 but not port 4.

I was wondering,... is there a limit to the number of GOTO we can use in a program? Is there such limitation?

"Also, make sure when you GOTO another routine from your interrupt
that the routine isn't outside the DISABLE/ENABLE block. If you do it returns
to the beginning of your interrupt handler. "
-> actually I don't GOTO to something outside the int handler.

Jerson
- 13th October 2008, 16:07
the problem may not be so obvious with just the code fragment you posted. I suggest you post your entire interrupt code so that we can see what else is in there which can affect your desired outcome. I usually consider it a bad idea to have functions like LCDOUT in the interrupt handler. If the interrupts are not disabled, that statement itself, in the interrupt, may cause immense pain to a coder.

Jerson

xnihilo
- 13th October 2008, 17:41
the problem may not be so obvious with just the code fragment you posted. I suggest you post your entire interrupt code so that we can see what else is in there which can affect your desired outcome. I usually consider it a bad idea to have functions like LCDOUT in the interrupt handler. If the interrupts are not disabled, that statement itself, in the interrupt, may cause immense pain to a coder.

Jerson

Yes, I will post the code but the entire interrupt code is pretty huge.

As far as I know, using
DISABLE - (int handler) - RESUME - ENABLE should take care of the INT disabling while in the interrupt routine, am I wrong?

About LCDOUT, they are especially useful to debug the code but can lead to unexpected behaviors, I agree. They are to be deleted when debugging is finished because it woud slow down my handler anyway.

What is so weird is that I seem to be able to get an interrupt on RA4 like I do with the other pins on this port but when in the int handler, it's dead, as if it cannot read the incoming pulses.

Now I'm reading again the fuctions for this pin and I see CLOCKOUT (which should not be a problem as I disabled CLOCKOUT in the CONFIG words and this pin is an input anyway).
I also see 'T1G_' (TIMER1 GATE INPUT)! As I'm using TIMER1 to measure/time the pulses incoming on the pins, IF I didn't set the TIMER1 registers right, then this pin is thinking a LOW going pulse is a Timer1 gate input...?
My current TIMER1 settings are:
T1CON = %00011100 '1:2 prescale for 1US increments, timer 1 is stopped

I'm not sure exactly what settings I should use as the datasheet is not very clear to me.
BIT7: I will invert the gate (which is by default: low) so it will not interfer with my pulse (my TSOP IR sensors pulls low the pin when getting IR signal)
BIT6: (Time1 gate enable bit): it says if TIMER1 is on, "0" is 'Timer1 is on', "1" is 'Timer1 is on if Timer1 gate is not active'... what a strange and complicated way to say things... !!! Well, I think I should clear this bit...
I will try with the register set to : T1CON = %10010100

Why do the datasheet have to be soo intricate...

Acetronics2
- 13th October 2008, 18:01
Hi

And what about changing "==" to "=" ???

Just an idea ...

Alain

xnihilo
- 13th October 2008, 21:53
Hi

And what about changing "==" to "=" ???

Just an idea ...

Alain

? Why? If I remember well, it is supposed to be exactly the same.

Manual says:
"4.18. Comparison Operators
= or ==
used for
Equal"



Manual says also:
"2.6.4. GOTO
Try not to use too many GOTOs. While GOTOs may be a necessary evil, try to minimize their use as much as possible. Try to write your code in logical sections and not jump around too much. GOSUBs can be helpful in achieving this."

What do they mean "as much as possible"??? How many? What problem may arise otherwise?

xnihilo
- 13th October 2008, 22:27
What is so weird is that I seem to be able to get an interrupt on RA4 like I do with the other pins on this port but when in the int handler, it's dead, as if it cannot read the incoming pulses.

Now I'm reading again the fuctions for this pin and I see CLOCKOUT (which should not be a problem as I disabled CLOCKOUT in the CONFIG words and this pin is an input anyway).
I also see 'T1G_' (TIMER1 GATE INPUT)! As I'm using TIMER1 to measure/time the pulses incoming on the pins, IF I didn't set the TIMER1 registers right, then this pin is thinking a LOW going pulse is a Timer1 gate input...?
My current TIMER1 settings are:
T1CON = %00011100 '1:2 prescale for 1US increments, timer 1 is stopped

I'm not sure exactly what settings I should use as the datasheet is not very clear to me.
BIT7: I will invert the gate (which is by default: low) so it will not interfer with my pulse (my TSOP IR sensors pulls low the pin when getting IR signal)
BIT6: (Time1 gate enable bit): it says if TIMER1 is on, "0" is 'Timer1 is on', "1" is 'Timer1 is on if Timer1 gate is not active'... what a strange and complicated way to say things... !!! Well, I think I should clear this bit...
I will try with the register set to : T1CON = %10010100

Why do the datasheet have to be soo intricate...

Well.
I've tried the T1CON = %10010100 and it works.
I will test again but it seems to be the solution. My signal pulse was pulling the pin low as it would have been TIMER1 INPUT.
Always check the various functions of a pin.
I already had the surprise when connecting an I2C EEPROM to ports that would be set as ANALOG or DIGITAL and using a bigger PIC I didn't expect anything else than ANSEL but there was ANSELH too :p

rmteo
- 13th October 2008, 22:30
GOTO's (and GOSUB's) can cause "spaghetti code" to be the end result. Unfortunately, if the compiler does not support functions and procedures (what is commonly referred to as "structured programming") you may not have a choice.

Best to follow what the manual says "While GOTOs may be a necessary evil, try to minimize their use as much as possible."

xnihilo
- 13th October 2008, 23:00
GOTO's (and GOSUB's) can cause "spaghetti code" to be the end result. Unfortunately, if the compiler does not support functions and procedures (what is commonly referred to as "structured programming") you may not have a choice.

Best to follow what the manual says "While GOTOs may be a necessary evil, try to minimize their use as much as possible."

Right, but I need them to have bypass when multiple IF statements are used so not all IF are checked.

Archangel
- 13th October 2008, 23:22
Right, but I need them to have bypass when multiple IF statements are used so not all IF are checked.
Select Case will exit as soon as true.

rmteo
- 13th October 2008, 23:29
Select case only works with a single variable. The OP is testing several different variables.

Archangel
- 13th October 2008, 23:51
OK, so he is using PortB as inputs, so assuming only 1 leg is triggered at a time then PORTB.0 = 1 then PORTB = 1, PORTB.1 = 1 then PORTB = 2, PORTB.2 = 1 then PORTB = 4 . . . a lookup table could be used to assign whatever point value he wants.


Index = PortB

Lookup2 Index,[100,200,300,400,500], pin

xnihilo
- 14th October 2008, 14:20
OK, so he is using PortB as inputs, so assuming only 1 leg is triggered at a time then PORTB.0 = 1 then PORTB = 1, PORTB.1 = 1 then PORTB = 2, PORTB.2 = 1 then PORTB = 4 . . . a lookup table could be used to assign whatever point value he wants.


Index = PortB

Lookup2 Index,[100,200,300,400,500], pin


PORTA, actually.
And more than one pin at a time may be triggered.
There is no such thing as SWITCH (C language)?

Archangel
- 14th October 2008, 21:48
Ok Port A, b whichever. A port Typically has 8 I/O lines and can be read like any register, and can hold the value 0 to 255 counting in binary. In "C" they call it SWITCH CASE in PBP it is SELECT CASE.

xnihilo
- 15th October 2008, 10:31
Thank you for this info.