PDA

View Full Version : TOGGLE will not go LOW



SUNFLOWER
- 16th January 2013, 23:55
I have been writing complicated code for years without any troubles. Now something simple will not compile correctly. TOGGLE will not toggle low but does toggle high. Everything else seems to work ok but I am worried about this instability -- Rebooting computer did not clear this issue. Ideas on what's going on here?

DEFINE LOADER_USED 1 ' Bootloader space
OSCCON = %01100000 ' Internal oscillator speed 4 MHz 18F4620

MAINLOOP:

' LOW PORTA.0
PAUSE 50
TOGGLE PORTA.0
PAUSE 50

GOTO MAINLOOP

Normnet
- 17th January 2013, 02:17
I have been writing complicated code for years without any troubles. Now something simple will not compile correctly. TOGGLE will not toggle low but does toggle high. Everything else seems to work ok but I am worried about this instability -- Rebooting computer did not clear this issue. Ideas on what's going on here?

DEFINE LOADER_USED 1 ' Bootloader space
OSCCON = %01100000 ' Internal oscillator speed 4 MHz 18F4620

MAINLOOP:

' LOW PORTA.0
PAUSE 50
TOGGLE PORTA.0
PAUSE 50

GOTO MAINLOOP
Does the alternate "Low PORTA.0" work?
Perhaps the pin cannot be driven low?

Norm

mackrackit
- 17th January 2013, 02:29
http://www.picbasic.co.uk/forum/showthread.php?t=561

SUNFLOWER
- 17th January 2013, 03:09
Thanks, I was not aware TOGGLE needs to read digital, so can not toggle while doing some ADC on higher ports of A.

ADCON1 = %00001111 ' Make AN0-AN12 digital

AvionicsMaster1
- 17th January 2013, 14:29
I'm betting if you had a resistor pulling the pin low, say a 10k, you'd see it going low. I'm not familiar with the 18f4620 but on a 12f683 it needs some kind of load to pull the pin low. Don't have to be alot but something.

spcw1234
- 17th January 2013, 16:03
Adding these 2 lines should allow you to drive the pin.

ADCON1=15 'Set all A/D pins digital
CMCON=7 'Turn off comparators

HenrikOlsson
- 17th January 2013, 17:55
If you look at section 19.5 of the datasheet (http://ww1.microchip.com/downloads/en/devicedoc/39626b.pdf) for the 18F4620 you'll find this:

When reading the Port register, all pins configured as analog input channels will read as cleared (a low level). Pins configured as digital inputs will convert as analog inputs. Analog levels on a digitally configured input will be accurately converted.
So if you do a TOGGLE on a pin which has NOT be set to digital it will read '0', the bit will then flipped to '1' and written back to the port. Next time you do that TOGGLE it will again read the bit as '0' (even though it was previously set to '1'), flip that bit to '1' and write it to the port. Ie. it will never toggle it low because every time its told to toggle the bit it's read as low and gets toggled to high.

Page 224 in the same datasheet shows how to set ADCON1 up in order to configure the various pins as either analog or digital. And then there's the compartor as have been pointed out, see page 234. However for the 18F4620 the comparators are OFF by default so you strictly speaking you don't need to turn them off again. ALWAYS make a habit of checking IF you need to turn comparators off and/or enable digital mode on the pins you're using and HOW to do that - not all chips are the same.

/Henrik.

SUNFLOWER
- 17th January 2013, 23:08
Yes, thanks all, Henrik is correct.


I can drive the pin low. I was losing confidence when TOGGLE did not blink. I just did not think about the need of TOGGLE to read the state of an analog pin to blink an LED.


The Olimex board came with LED hardwired to PORTA.0 I am doing ADC on 6 other A/E ports (replacing cadmium sulfide photoresistors with more durable phototransistors in eyes of solar dish trackers) (also replacing expensive pulse/I2C tilt accelerometers with cheaper analogs).


I can make the LED blink by adding 1 to a tracking bit and not use TOGGLE in this instance. I doubt the need for an LED on solar dish PC boards. PORTA.0 will be liberated. Thanks again -- Doug.


P.S. You can see progress -- Google -- matrix solar dish

boroko
- 8th August 2014, 07:39
Just ran into this on a 18F4431 trying to get a heartbeat to work inside a ISR using DT-INTS:


'**** TMR0 Int Handler ******
ToggleLED:
HIGH PORTA.0
PAUSEUS 100
LOW PORTA.0
@INT_RETURN
...Worked, while:

'**** TMR0 Int Handler ******
ToggleLED:
TOGGLE PORTA.0
@INT_RETURN
Did not.
Thanks for posting this. I don't know if I would have figured it out on my own.
Bo

mark_s
- 9th August 2014, 00:27
Did you happen to try LATA.0 vs PORTA.0 ?

Like this


'**** TMR0 Int Handler ******
ToggleLED:
TOGGLE LATA.0
@INT_RETURN

boroko
- 9th August 2014, 00:48
Just tried it. Works wonderfully.
One benefit of "HIGH, PAUSEUS, LOW" way is that I can only get brief flash, which is nicer to look at for a heartbeat, but the other side of that, is that with the "TOGGLE LATx", you can save some time in the ISR by eliminating the pause.

Thanks for the heads up.
Mark

richard
- 9th August 2014, 02:53
before you go too far down the wrong road read this thread about pbp and latx

http://support.melabs.com/threads/998-i2cwrite-using-lat-regs

boroko
- 9th August 2014, 03:34
Thanks. of course Darrel would be the one to find something that obscure. Bet there's a story and some lost hours on that one.
Mark

Archangel
- 9th August 2014, 03:53
I have experienced this probably 50% of the time I have attempted to use toggle, High & Low commands and as such do not even attempt to use them.
Is there a definite cause / effect or relationship to their failure to work and setting TRIS registers? Can anyone point to a paragraph in the manual?

richard
- 9th August 2014, 05:13
from the pbp3 manual for HIGH
HIGH Pin
Make the specified Pin high. Pin is automatically made an output. Pin may be a constant, 0-15, or a variable that contains a number 0-15 (e.g. B0) or a pin name (e.g. PORTA.0).
HIGH 0 ' Make Pin0 an output and set it high (~5 volts)
HIGH PORTA.0 ' Make PORTA, pin 0 an output and set it high (~5 volts)
led Var PORTB.0 ' Define LED pin
HIGH led ' Make LED pin an output and set it high (~5 volts)
Alternatively, if the pin is already an output, a much quicker and shorter way (from a generated code standpoint) to set it high would be:
PORTB.0 = 1 ' Set PORTB pin 0 high
Since this command automatically sets the data-direction of the pin it acts on, the Pin parameter should only be a PORT or GPIO register (or an alias to a PORT or GPIO register). If the command is directed to act upon a LAT output or a bit within a variable or SFR, it will attempt to set a data-direction register that doesn't exist. The result may be unexpected behavior since a bit is changed in a seemingly random memory location. This can be very difficult to debug.

its also mentioned for other commands

Archangel
- 9th August 2014, 07:29
Ok I did some testing and I found:
1. High & Low worked without Tris or Ports set or analog settings set to digital
2. Setting port to 1 and zero worked with Tris & Ports set without analog settings set to digital
3. Toggle would not work without setting the analog stuff to digital, but when properly set it did.
it otherwise would go high and stay high.

Test chip 16F690 on Microchip demo board
Interesting, Since Both posters are using portA in their examples I think some analog register is blocking it working.
Which is what Mackrackit alluded to in post #3, I found it interesting it did not affect #2 in my test.
HTH
JS

richard
- 9th August 2014, 10:40
looks like I went off on the wrong path again, but I'd say archangel is 100% correct . if only people would post their complete code (or complete compilable example demonstrating the problem) speculation would be unnecessary,
dream on

SUNFLOWER
- 10th August 2014, 16:53
According to data sheet 18F4620 making one port analog makes all smaller number ports analog which interferes with TOGGLE. IF AN5 is analog then AN0 thru AN4 are also analog, like a pyramid. TOGGLE is not needed. Adding a bit to an output pin toggles that pin, analog or not.