2
\$\begingroup\$

This is a real odd thing I have here.

I picked up a PIC16F628 this morning to play with, and I am having a very strange issue with it.

I have written a very simple program which should light 2 LEDs in this sequence: (* = on, o = off)

RA0 RA1
 *   o
 *   *
 o   *
 o   o

But what actually happens is:

RA0 RA1
 *   o
 o   *
 o   o
 o   o

When RA1 turns on, RA0 turns off.

The exact same code run on an '84a works perfectly. Snippet:

loop
    BSF     PORTA,0
    CALL    delay
    BSF     PORTA,1
    CALL    delay
    BCF     PORTA,0
    CALL    delay
    BCF     PORTA,1
    CALL    delay
    GOTO    loop

My only thoughts are that it has something to do with the comparators that share the pins (should be disabled by default) which I have tried manually disabling but it has had no effect.

Now, one more thing to add confusion... If I send absolute values to PORTA (0x01, 0x03, 0x02, 0x00) it works correctly. Why should the bitwise operations work so strangely?

Oh, and I don't have any issue at all working with PORTB - only PORTA.

Any clues or ideas? Because I have run out.

\$\endgroup\$
2
  • \$\begingroup\$ How long is "delay"? 1 us? 1 ms? 1 s? \$\endgroup\$
    – ajs410
    May 20 '11 at 18:24
  • \$\begingroup\$ It's around 0.5 seconds - enough time to see the sequence unfold before me. \$\endgroup\$
    – Majenko
    May 22 '11 at 10:35
4
\$\begingroup\$

Your problem is probably caused by the Read-Modify-Write effect, see page 31 of the data sheet. You should use a shadow register, set and reset the bits in that, and write it to the port. Delays usually help, so I find it surprising that it caused you problems. The fact that you could write bytes to the port and it works as expected indicates that it probably is an R-M-W effect.

Here is a good description of the problem.

The 18F PICs have latch registers for the ports, and don't suffer from the R-M-W problem.

\$\endgroup\$
5
  • \$\begingroup\$ Hmm, are you sure it is RMW? Because OP mentions that it does not effect PORTB. \$\endgroup\$
    – Thomas O
    May 19 '11 at 21:08
  • \$\begingroup\$ The ports are different, because of the comparator inputs. That might have an effect. \$\endgroup\$ May 19 '11 at 21:31
  • \$\begingroup\$ Well, whatever the reason, abstracting the port via my own register seems to have solved it - seems a bit strange as the data sheet says it does a read-modify-write for all the ports. My guess is a bug in the system means the read of an output bit is not working right. \$\endgroup\$
    – Majenko
    May 19 '11 at 21:36
  • \$\begingroup\$ Is it possible that the PORTB has better current capability than PORTA? RA0 might not rise in time to look like a 1 by the time BSF PORTA,1 is executed. \$\endgroup\$
    – ajs410
    May 20 '11 at 18:24
  • \$\begingroup\$ Leon is correct. The bit manipulation instructions should never be used with the PORT registers on PICs (even the more modern ones). The bit manipulation instructions read the entire 8 bits, modify the desired bit and then write the entire 8 bits back again. If you have a 1 output on a pin, but there is a high load on it (relay, LED etc) the voltage on the pin may read back as a '0' although it is set to 1. Thus, it gets written back as a 0 as a result of the RMW process. It is recommended to prepare the value to output in RAM (using BCF/BSF) and then copy it whole to the PORT register. \$\endgroup\$ Feb 7 '12 at 21:21
1
\$\begingroup\$

Just saw this question. The 16F628 defaults on power-up to disabling the digital read circuitry for PORTA. You need to set the comparator configuration register (CMCON I think) to enable any pins you want to read via the PORTA register (bearing in mind that using bsf/bcf on a port without disturbing the other pins requires being able to read those other pins).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.