PDA

View Full Version : 16F688 problem



Tobias
- 9th May 2009, 06:07
This is my first shot using a 16F688 and the internal OSC. I am pretty sure I have the config's set right for the OSC because I did a DEBUG command and was able to see the correct output. I have the OSC setting at INTOSCIO, WatchDog , PowerUp, BrownOut, Internale External, and, Fail Safe disabled. I have the MCLR set as a reset and it is pulled high.

My problem is just turning on and off the PortC pins. When I try to turn on/off 0, 1, and 2, only 0 turns on/off. When I comment out Pin0(ClutchOut), pin 1 turns on and not 2. Of course then when I comment out 0 and 1, then 2 turns on. Below is the code.

I did notice that I do have the Pull-Ups enabled yet only A2 and A5 are at 5v. A4 is 1.4v. The rest are 0v


INCLUDE "modedefs.bas"
Throttle Var PortA.0
ClutchIn var PortA.1
LineLockIn var PortA.2
'MCLR var PortA.3
'DEBUG var PortA.4
Arming var PortA.5
ClutchOut var PortC.0
LineLockOut var PortC.1
Aux1Out var PortC.2
Aux2Out var PortC.3
Jumper1 var PortC.4
Jumper2 var PortC.5

Marker var bit
Counter var byte
Timer var byte

Option_Reg.7=0 'Pull-Ups Enabled
TRISA=%111111
TRISC=%110000
ANSEL=%00000000 'D/A turned off on all pins
ADCON0.0=0 'ADCON turned off
VRCON.7=0 'VRef Off
'INTCON.7=1

'IOCA.5 = 0
'IOCA.4 = 0
'IOCA.3 = 0
'IOCA.2 = 0
'IOCA.1 = 0
'IOCA.0 = 1 'Throttle Interrupt On

define OSC 4
DEFINE DEBUG_REG PortA
DEFINE DEBUG_BIT 4
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 1

loop:
high LineLockOut 'Yellow LED PortC.1
high ClutchOut 'Green LED PortC.0
high Aux1Out 'White LED PortC.2
pause 1000
low LineLockOut 'Yellow LED PortC.1
low ClutchOut 'Green LED PortC.0
low Aux1Out 'White LED PortC.2
pause 1000
goto loop

Archangel
- 9th May 2009, 07:17
You still have analog functions enabled, specifically the comparators.
CMCON0 = 0 ' turn off comparators.

Bruce
- 9th May 2009, 15:54
I think Joe nailed it, but check the datasheet for the value to disable comparators. I think
it should be CMCON0 = 7 on the 16F688.

Pins configured as analog inputs will be read as 0 when used for digital I/O.

The HIGH / LOW commands use BSF and BCF read-modify-write assembly language
instructions. This causes the whole port to be read, the port pin to be modified, then the
whole port is writen back to each time it lands on a HIGH LOW instruction.

Example:

high LineLockOut ' reads whole port, sets C.1, writes whole port back.
high ClutchOut ' reads whole port, (C.1 is read back as 0), sets C.0, writes it back.
high Aux1Out ' reads whole port, (C.0 is read back as 0), sets C.2, writes it back.

If pins are set to analog inputs, then it reads each pin value back as 0, then writes it back
as a 0 on the next BSF operation, so you end up with only Aux1Out being set once it runs
through all three lines of code above.

The same scenario can happen with read-modify-write. Even if the pins are not configured
as analog inputs.

If it blazes through these three lines of code at a high-speed, and there's a little bit of
external capacitance on these pins, the next read-modify-write operation after changing
the first output pin - may read the pin before it has had time to change, so it writes back
the wrong value to a previous pin when it changes the next pin.

When that happens, you can fix it by inserting a short pause between each instruction that
sets or clears pins, or you can just write to the whole port at once instead of setting or
clearing individual bits one at a time.

Archangel
- 9th May 2009, 18:51
I think Joe nailed it, but check the datasheet for the value to disable comparators. I think
it should be CMCON0 = 7 on the 16F688.

Pins configured as analog inputs will be read as 0 when used for digital I/O.

The HIGH / LOW commands use BSF and BCF read-modify-write assembly language
instructions. This causes the whole port to be read, the port pin to be modified, then the
whole port is written back to each time it lands on a HIGH LOW instruction.

Example:

high LineLockOut ' reads whole port, sets C.1, writes whole port back.
high ClutchOut ' reads whole port, (C.1 is read back as 0), sets C.0, writes it back.
high Aux1Out ' reads whole port, (C.0 is read back as 0), sets C.2, writes it back.

If pins are set to analog inputs, then it reads each pin value back as 0, then writes it back
as a 0 on the next BSF operation, so you end up with only Aux1Out being set once it runs
through all three lines of code above.

The same scenario can happen with read-modify-write. Even if the pins are not configured
as analog inputs.

If it blazes through these three lines of code at a high-speed, and there's a little bit of
external capacitance on these pins, the next read-modify-write operation after changing
the first output pin - may read the pin before it has had time to change, so it writes back
the wrong value to a previous pin when it changes the next pin.

When that happens, you can fix it by inserting a short pause between each instruction that
sets or clears pins, or you can just write to the whole port at once instead of setting or
clearing individual bits one at a time.

<h1>RATS !</h1> Misread the chart CMCON0=0 comparators off ANALOG, CMCON0 = 7 comparators off DIGITAL !
THANK YOU BRUCE !

Darrel Taylor
- 9th May 2009, 21:39
Misread the chart CMCON0=0 comparators off ANALOG, CMCON0 = 7 comparators off DIGITAL !

Which is where ALLDIGITAL.pbp comes in really handy. :)
http://www.picbasic.co.uk/forum/showthread.php?t=11100
<br>

Tobias
- 9th May 2009, 22:47
Thanks guys, I haven't had a chance to test yet but thanks.

Tobias
- 9th May 2009, 22:57
I got the following errors with the AllDigital.pbp, any ideas?

opcode expected instead of a variable
undefined symbol 'showdigitalresult'
undefined symbol 'showdigitalresult'

Darrel Taylor
- 9th May 2009, 23:09
Thank you Tobias.

I made some changes after testing with the PM assembler. Should have tested that assembler again. Sorry bout that.

Removing the variable opcode and the indent makes it work with PM again.
;----[Module defaults]------------------------------------------------------
#define SHOWDIGITALDEFAULT 0
ifdef SHOWDIGITAL
SHOWDIGITALRESULT = SHOWDIGITAL
else
SHOWDIGITALRESULT = SHOWDIGITALDEFAULT
endif
ifndef PM_USED
ifndef ADLISTALL
nolist
endif
endif

I'll update the main file.

Thanks again,