PDA

View Full Version : problem with toggle command



INVTLG
- 2nd September 2016, 22:45
having problem with the toggle command; (using PIC18f13k22)
this works;


LOOP1:
PORTA.1 = 1
pause 100
PORTA.1 = 0
pause 100
goto LOOP1


now, using the toggle command, this does not work;


LOOP1:
PORTA.1 = 1
pause 100
TOGGLE PORTA.1
pause 100
goto LOOP1

what am I missing?

SUNFLOWER
- 3rd September 2016, 00:41
Something I ran into also. Has something to do with reading state of pin for toggle, a problem if pin is set to analog, I think. Anyway, a simple reliable method to toggle a pin is to add 1 to the pin value -- portA.1=portA.1 + 1

HenrikOlsson
- 3rd September 2016, 07:59
There must be hundreds of posts about this across the forum by now.
Turn off any analog functions (comparator, ADC) that's on the pin(s) you're going to use as digital.

When an analog pin is read, as in myBit=PortA.1 it will always return the same value no matter what the logic state actually is. Toggle then flips the bit and writes it back to the pin. What happens next time TOGGLE executes?

On devices whit LAT registers you're better off using them instead of PORT but I don't Think Toggle works with them.

/Henrik.

INVTLG
- 3rd September 2016, 17:58
Thanks for the answers, that was it. The problem was that the ANSEL register was set to disable the digital input buffer, which caused all reads of that pin to return '0'. What threw me off was that I was thinking of the toggle command is an output function, & since the state of the ANSEL register has no affect on digital output functions, I thought I was OK with that setting. But toggle is really both an output & an input function in that it has to read the state of the pin to be able to change it to the opposite state.

Actually, after considering what SUNFLOWER said, it's not obvious that the toggle command necessarily has to have an input (read) function to it, but evidently it does work that way.

HenrikOlsson
- 3rd September 2016, 18:53
How else could it work? If it's supposed to toggle a bit it needs to know what state that bit is currently in, right?

INVTLG
- 4th September 2016, 01:21
Henrik,
Well, I guess I don't have to know If I just add 1 to whatever is there, so why should it have to know? - just kidding
From your original answer, I see that you obviously understand the inner workings of these microcontrollers & what the compiler is doing behind the scenes. I do not, & my last comment about the 2nd part of SUNFLOWER's answer is just this very thing; before I read your answer, I might think that somehow it could just add 1 to whatever is there.

HenrikOlsson
- 4th September 2016, 07:45
Exactly, when you think about it for a bit you'll realise that even PortA.1 = PortA.1 + 1 won't work because of the exact same reason and in this case it's even more "obvious" than with the TOGGLE command because here you have it spelled out. You're telling the compiler to read the state of PortA.1, add 1 to it and write it back. If, when Reading PortA.1 it always reads high because it's got its digital buffer disabled then it will work just as bad as TOGGLE will.

On top of that you should know that ALL bit operations are executed as Read-Modify-Write by the internal PIC hardware, has nothing to do with the compiler. So, if you're using some pins on PortA as digital outputs but you don't bother to enable the digital buffers and then you do something simple like PortA.0 = 1 what will happen is that the PIC (ie the actual processor) will read all 8 bits from PortA, set bit 0 and write all 8 bits back to the Port register and the state of "the other" pins might change "unexpectedly".

So, whenever you get "weird" results on any I/O pins, even if you're not actually writing to that specific pin you should always think about the analog peripherals.

And again, on the device with LAT register you should use those instead of port since they're pretty much unaffected by RMW issues, no matter the actual cause.

/Henrik.