PDA

View Full Version : slow return from subrutine



servo260
- 22nd January 2005, 05:43
Hi, I have a problem with the return from a subrutine. It works fine but It takes aprox. 20sec. I don't if it's a software or hardware problem.
I have all unused input pins tied to groun and the ones I'm using have a pull up resistor.
Here is the code

define osc 4

TRISA = %00010000
TRISB = %10001111

intcon = 0


clear

num var byte
x var word
pulsos var byte
cuenta var byte
velocidad var word
circunferencia var byte
demora var byte

t1 var portb.4
t2 var portb.5
t3 var portb.6

timer con 9

data @0, 1


goto start

on interrupt goto tiempo

start:
OPTION_REG = %10000111
INTCON = %10100000
read 0, circunferencia
goto main

main:

if portb.3 = 0 then gosub setup

if intcon.1 = 1 then
pulsos = pulsos + 1
intcon.1 = 0 ; pongo a 0 el flag de la interrupcion en Rb0
endif

if cuenta = 4 then
cuenta = 0
velocidad = pulsos * circunferencia * 100 ; *100 para dividir por .25seg que esta multi * 100 para pasarlo a 250
velocidad = velocidad / 25 ; dividio .25seg por 100
velocidad = velocidad * 36 ; 3600seg / 1000metros = 3.6 const para convertir a k/h * 10 para poder trabajarlo
velocidad = velocidad / 400 ; velocidad /10 por multiplicar 3.6 *10 y /4 ya que tengo .25 segundos (1/4seg) velo/10/40 = velo/40
x = velocidad
pulsos = 0
endif

gosub display

goto main


display:
num = x dig 0 ; unidad de X y lo manda a num
porta = num
high t1
pause 1
pause 1
pause 1
low t1
num = x dig 1 ; decena de X y lo manda a num
porta = num
high t2
pause 1
pause 1
pause 1
low t2
num = x dig 2 ; centena de X y lo manda a num
porta = num
high t3
pause 1
pause 1
pause 1
low t3
return




setup: ; entra en la configuracion de la circunferencia
disable
if portb.2 = 0 then
return ; HERE IS THE PROBLEM IT TAKES 20 SECONDS TO RETURN
enable
endif
x = circunferencia
for demora = 1 to 20
gosub display
next
if portb.3 = 0 then
circunferencia = circunferencia + 1
if circunferencia = 216 then circunferencia = 0
endif


goto setup

disable
tiempo:

cuenta = cuenta + 1

TMR0 = timer
INTCON.2 = 0

resume
enable

Archilochus
- 22nd January 2005, 17:54
Hi servo260,
Don't know if this could cause the problem...

Is this IF...THEN statement proper? I don't know if it's OK to use a GOSUB like that.
---
main:
if portb.3 = 0 then gosub setup
---
Maybe try this:

IF portb.3 = 0 THEN
gosub setup
EndIF


Arch

Acetronics2
- 22nd January 2005, 18:11
Hi, 260

I feel a little strange the 2 last lines of your code ...
it never re-enables interrupts after the interrupt stubb

doesn't sound good to me ... enable should be BEFORE resume.

Alain

mister_e
- 22nd January 2005, 20:56
it's easier than this. Let's look at the setup SUB :



setup: ; entra en la configuracion de la circunferencia
disable
if portb.2 = 0 then
return ; HERE IS THE PROBLEM IT TAKES 20 SECONDS TO RETURN
enable
endif

x = circunferencia
for demora = 1 to 20
gosub display
next

if portb.3 = 0 then
circunferencia = circunferencia + 1
if circunferencia = 216 then circunferencia = 0
endif


goto setup

yes you enter to your setup sub but

1. where is the return when PORTB.2=1 ??? Not really sure but, Now your looping maybe too much.... using a WHILE loop can maybe solve something

2. IF PORTB.2=0 ... must be ENABLE before RETURN


try this


[code]

setup: ; entra en la configuracion de la circunferencia
disable

WHILE portb.2

x = circunferencia
for demora = 1 to 20
gosub display
next

if portb.3 = 0 then
circunferencia = circunferencia + 1
if circunferencia = 216 then circunferencia = 0
endif

WEND

enable

return



also i don't believe if it's a good practice to use those :

goto start

on interrupt goto tiempo

start:


remove the goto start line can maybe do something too.

This one is funny


goto main

main:


Why ?!?

Alain


Hi, 260

I feel a little strange the 2 last lines of your code ...
it never re-enables interrupts after the interrupt stubb

doesn't sound good to me ... enable should be BEFORE resume.

Look into the PBP 2.45 page 106

servo260
- 22nd January 2005, 23:58
Hi thanks, for the "while" code, it is smaller. But I still have the problem.
I didn't mention the pic is a 16f84a.
I have 2 microswitch connected to portb.2 and portb.3
I have 3 bc548 connected through a resistor to portb.4, .5 and .6.
On portb.0 I have a photomicrosensor.
I hope that helps.
BTW, If I rotate the last 2 lines of code, the interrupt stop working.

mister_e
- 23rd January 2005, 00:04
Do you have any External Pullups for your micro-Switch ????

servo260
- 23rd January 2005, 00:47
Yes, each one has a 10k pullup

servo260
- 23rd January 2005, 00:51
Could it be a chip problem? Because when portb.2 = 0 the setup subrutine continue functioning. And after aprox 20 sec It returns.
I tried changing portb.2 with portb.3 and vice versa but is was the same.

servo260
- 25th January 2005, 02:59
HI, I simulated the circuit and the program in proteus and I get a similar result, the only diference is that in proteus never returns from the subrutine.
So know I think it must be a software and not a pic problem, although I can't figure it out.

mister_e
- 25th January 2005, 03:30
what about


setup: ; entra en la configuracion de la circunferencia
INTCON.7=0 'disable all interrupt
WHILE portb.2

x = circunferencia
for demora = 1 to 20
gosub display
next


if portb.3 = 0 then
circunferencia = circunferencia + 1
if circunferencia > 215 then 'lets say its=216
circunferencia = 0
endif
endif

WEND
INTCON.2=0
INTCON.1=0
INTCON.7=1 'enable all interrupt

return



and what about if you rename setup to Mysetup? timer to MyTimer?

Redefine all your math variable to WORD size can also do something. Case not, i'll try it on-board. Looks weird.

Could you axplain, brief, how your hardware/software is suppose to work? And if you can provide some schematic too it can be handy.

servo260
- 25th January 2005, 06:21
Thaks Steve for your help.
Here is the schematic, I hope It'll help.
And the modified program.
What I notice is that if I press the 2 buttons at the same time then it returns to the main program in aprox. 3 sec. instead of 20.
It's a bike speedometer, you help me before with this. It works great, beside the slow return.
I also tried putting all the vars to word sized but it never return from the subrutine (at least I got tired of pressing the button)
Perhaps when this works ok the write command will too.

servo260
- 25th January 2005, 06:21
And the code

mister_e
- 26th January 2005, 00:13
Before i give a try, one thing spring to mind... you're using 100 ohm resistor to the Transistor base.

5Volt/100 ohm = 50mA... should be max 25ma, try something higher like 300 ohm - 1K first.

Also, i'm sure it's a mistake when you draw it, great short to the supply line with your push-button ;)

servo260
- 26th January 2005, 00:38
Yes, I drew bad the buttons ;), sorry.
I tried with 300ohm resistors, but It works the same.

servo260
- 2nd March 2005, 02:43
Hi, it's been a long time. I'm now donig the test with a 16f627. Up to now I am geting the same results, so it must be a soft problem. Any more ideas?

servo260
- 2nd March 2005, 16:40
I changed the pins used by the buttons. Now the used porta.6 and porta.7, because I'm using internal osscilator. But the result it's the same (it takes less time with the 627 than 84a, around 10 sec).

servo260
- 3rd March 2005, 04:26
I just remember that when I drive the 4511 with portb the subrutine works fine, then when I began to use porta all the problems started, but now I can't change it (at least I don't know how).
Is there any difference betwen both ports?

mister_e
- 3rd March 2005, 04:36
difference...

RA4 is always an open drain output
CMCON=7 ' to disable analog comparator on PORTA.. but i think you already do this
RA5 is an input only


i'll review previous post and place it on a board... i'll let you know if i found something.

servo260
- 3rd March 2005, 05:42
Thanks a lot, I'm going crazy with this.

Warrier
- 5th March 2005, 17:08
a few, perhaps irrelevant, comments:

why store the value of circunferencia as 1 (data @0,1) and the use Read 0, circunferencia at power up to read it? why not set the variable to 1 (circunferencia=1) at start up and not worry about EEPROM?

why use Pause 1 three times for turning on the display when you could use Pause 3?

It is nice to have an End statement somewhere.

PIC MCU has output drive limitations - that's why Steve commented on using 300ohms to keep it within spec. Besides, the transistors have quite large hFE so you don't need to drive the base that hard to turn on the 7segments!

SENSOR? what kind of output? since there is no pull up (or pull down) on this line make sure logic 1 and 0 are true and the line doesn't float as you have disabled the internal port B pullups.

-warrier

servo260
- 5th March 2005, 21:03
I use the eeprom because I wanted to later modified that value, but I need It to not get lost when I turn off the power. But so far I was unnable to write something in the eeprom using the write command, it does nothing, and I tried it on a 16f84a and a 16f627. Not only with this code, I have made some simple codes to test it and the result is always the same.
The pause 3 times were some stupid test I made, I already changed that.
I already changed the resistor, first I tried with 300ohm, and now with 470ohm.
But nothing changed.
The sensor is a photomicrosensor, so RB0 is connected to a phototransistor, with their respective resistors.
I tried disconecting it and puting the pin to gorund but, again, nothing changed.

servo260
- 8th March 2005, 17:33
well, I have tried with 3 buttons now (the third to return from the subrutine) and it continue taking 20 sec to return. I'm very sure It must be a PBP issue, because with simple test programs the speed is fine.
Can I have some corrupt file inside PBP?