PDA

View Full Version : Getting Stuck in loop



Frozen001
- 14th November 2008, 15:57
I have the following code for an 18f8722:


Low PortF.3
Low PortF.6
REPEAT
UNTIL PortA.5 = 0
High PortF.6
REPEAT
UNTIL PortA.5 = 0
Pauseus 1
Location1=PortJ
REPEAT
UNTIL PortA.5 =0
pauseus 1
CharLow=PortJ
REPEAT
UNTIL PortA.5 = 0
pauseus 1
CharHigh=PortJ

Occasionally it will randomly get stuck in one of the repeat-until loops. Any ideas on how to prevent this??
I have tried to add in a counter to jup out after so many loops, but that slows my code down so much that I miss the data on PortA.5.

Also if I use while:wend instead of the repeat:until this code does not work.

mister_e
- 14th November 2008, 16:49
Could you explain what you need to do and post your whole setup code?

mackrackit
- 14th November 2008, 16:49
There is more to the code..correct?
It will help to see it all.

mister_e
- 14th November 2008, 16:51
There's a strong smells of ...
http://www.picbasic.co.uk/forum/showthread.php?t=561

Frozen001
- 14th November 2008, 18:35
The complete code is pretty long.... but here are the settings I am using. The code I posted prior is first few lines I have to run in the code. After that is is just decoding the data so I can send it to a display. The 3 8-bits of data that I read from PortJ are characters that used to be sent to a 16segment display, which I am working to replace with a modern dot-matrix dispaly.


' Genenal Register Settings, Port Settings and System Definitions



CMCON = 7 ' Disables the Comparitor Pins
ADCON1 = 15 ' Disables the A/D Converter Pins
TRISA = $FF ' Define Port A(0-7) as Input
' (Host TTL inputs, RA7 unused)
TRISB = $E0 ' Define Port B(0-4) as Output
' (RB0-4 Character Output; RB5-7 are programming port)
TRISC = $00 ' Define Port C(0-2) as Outputs
' (Left=C0; Middle=C1; Right=C2 displays)
TRISD = $00 ' Define Port D(0-7) as Output
' (Character Data Outputs)
TRISE = $FF ' Define Port E(0-7) as Inputs
' (Ext. Keyboard Inputs)
TRISF = $F0 ' Define Port F(0-3) as LED Outputs, F(4-5) as
' Test SW inputs and F(6-7) as Display Int and Kbd Int I/O
TRISG = $F0 ' Define Port G0 as I/O for Reset, G1-3 as Rd/Wr/Fl Outputs
TRISH = $FF ' Define Port H(0-7) as Inputs
TRISJ = $FF ' Define Port J(0-7) as Inputs (Host TTL inputs)

Define OSC 20 ' Sets Oscillator Speed at 20Mhz
Define BUTTON_PAUSE 100 ' Sets Button Debounce time to 100 ms
Define I2C_SLOW 1 ' Sets I2C Speed to 100KHz

Bruce
- 14th November 2008, 18:50
Stuff you want to REPEAT needs to be in between the REPEAT
UNTIL.

Like

REPEAT
this
UNTIL this

Not

REPEAT
UNTIL this
do this

Frozen001
- 14th November 2008, 19:08
Stuff you want to REPEAT needs to be in between the REPEAT
UNTIL.

Like

REPEAT
this
UNTIL this

Not

REPEAT
UNTIL this
do this

I am using the repeats as delays so the pic waits for the data basically. The data being sent comes in as 3 seperate 8-bits in sequence. The data is read off of PortJ. The data always comes after PortA.5 goes low. Ant it is always in a specific order. If I miss any 1 of the three I cannot tell what the actuall character is.

mister_e
- 14th November 2008, 19:21
How neat the signal on PORTA.5 is? Where this signal come from?

Acetronics2
- 14th November 2008, 19:29
Hi,

1) @20Mhz ... min Pauseus is ... 3µs !!!

2) UNTIL NOT PortA.5 is much quicker than UNTIL PortA.5 = 0

3) PortF.6 = 1 is much quicker than HIGH PortF.6

4) Instead of Repeat - Until NOT PortA.5, try While PortA.5 - Wend ...

Alain

mister_e
- 14th November 2008, 19:31
In fact, you should use LATF.x instead of PORTF.x ...
Alain, OP says WHILE:WEND didn't work.. not sure why... sounds odd...

Acetronics2
- 14th November 2008, 19:38
In fact, you should use LATF.x instead of PORTF.x ...
Alain, OP says WHILE:WEND didn't work.. not sure why... sounds odd...

a good point for a " not so clean" signal ...

While PortA.5 : Wend just gives

BTFSC Porta,5
GOTO $-1

...

asm is really useful, sometimes !!! lol

Alain

Frozen001
- 14th November 2008, 19:44
Hi,

1) @20Mhz ... min Pauseus is ... 3µs !!!

2) UNTIL NOT PortA.5 is much quicker than UNTIL PortA.5 = 0

3) PortF.6 = 1 is much quicker than HIGH PortF.6

4) Instead of Repeat - Until NOT PortA.5, try While PortA.5 - Wend ...

Alain
Couple of things... My code as it is shown works for the most part as long as the loop does not get hung up.


1) Made the change, seems to work as before....

2) Made change code works as it did before

3) I will randomly miss characters, changed it back to what I originally had

4) Made change, I no not get any characters.

mister_e
- 14th November 2008, 19:45
BTFSC Porta,5
GOTO $-1
YEah but this will throw you an error for a 18F :D

GOTO $-2 would be better ;)

Maudit Francais!

Frozen001
- 14th November 2008, 19:49
How neat the signal on PORTA.5 is? Where this signal come from?

Looking at the signal in question on an o-scope, It looks pretty clean to me. It is connected to a 100K pull-up to 5V. The transition from high to low does have some ringing , that lasts about 90nS give or take, but the peaks are all < 0, so it should still be seen as a low.

mister_e
- 14th November 2008, 19:51
Reduce it!!! Let's say ~1-10K pull-up.

AND, wait a few Usec after you detect the falling edge...

Frozen001
- 14th November 2008, 20:09
Reduce it!!! Let's say ~1-10K pull-up.

AND, wait a few Usec after you detect the falling edge...

Wiat let me correct that... I just looked at the schematic, there is not a pull up on PortA.5. Sorry about that, I did not do the hardware, I am just doing the programming.


I have a 3uS pause after the falling edge (was 1uS, but Alain correct me on that already)

Thanks for all your help so far guys...

I am still learning this digital stuff, and have been slowly making my way up the hill.

Bruce
- 14th November 2008, 20:40
A floating input would for sure screw-the-pooch since it returns a random value when
the port pin is read...;o}

sayzer
- 15th November 2008, 09:09
Looking at the first post,

I think this could be the issue here.




X var PORTA.5
Y var PORTF.6


REPEAT
UNTIL x = 0 ' X = 1 ; wait until it is 0.

High y ' Here, X = 0.

while x = 0 : wend ' Here, X = 0, wait until it is 1.

REPEAT
UNTIL x = 0 ' X = 1 ; wait until it is 0.
Pauseus 1
Location1=PortJ

while x = 0 : wend ' Here, X = 0, wait until it is 1.


REPEAT
UNTIL x = 0 ' X = 1 ; wait until it is 0.
pauseus 1
CharLow=PortJ

while x = 0 : wend ' Here, X = 0, wait until it is 1.

REPEAT
UNTIL x = 0
pauseus 1
CharHigh=PortJ

while x = 0 : wend ' Here, X = 0, wait until it is 1.



------------

Frozen001
- 17th November 2008, 13:43
sayzer:

I'll give it a try and see if that helps...

Frozen001
- 18th November 2008, 21:01
sayzer:

I'll give it a try and see if that helps...
I made the change and it made no difference at all.

sayzer
- 19th November 2008, 08:10
If these changes made no difference, then you have an issue with your inputs.

_______________-

Frozen001
- 19th November 2008, 15:17
If these changes made no difference, then you have an issue with your inputs.

_______________-

I don't know... the signals on the ports are TTL level, so it is pretty definite if it is a high or low on the port.

I have been digging around the code, and actually looked at the Assemble that PBP creates. After you work through all the macros and stuff some of the commands are LONG. A while loop command can be well over 20 instructions depending on the logical operator used. This sort of explains why the my code does not work when I use while:wend combinations. 20 instructions on the 18F8722 at 20MHz takes like 4uS to excicute... seeing how the signal I am looking for is only there 1 uS I can see how it will miss it...

rmteo
- 19th November 2008, 15:46
As you have correctly surmised, trying to detect a 1uS pulse by polling a port pin is not going to be reliable.

Use an external (or pin change) interrupt instead and you will not miss any of these short pulses.