1
\$\begingroup\$

I'm learning how to program a PIC10F220. I'm using a PICkit 3 programmer and running physical experiments, as well as running the simulator in MPLABX.

One thing I want to do is set the proper level for a port output latch before the tristate (TRIS) switches to output mode. This diagram suggests that it should be possible, and that the input and output paths are separable:

pic port

I've written this chunk of assembly:

    ; !GPWU=0: enable wakeup on pin change 
    ; !GPPU=0: enable weak pullup on GP0,1,3
    ; T0CS=0: timer 0 internally clocked
    ; T0SE=0: ignored
    ; PSA=0: prescaler assigned to timer 0
    ; PS=111: 1:256 prescaler
    movlw b'111'
    option

    ; ANS1=0: GP1 digital
    ; ANS0=1: GP0 analog in
    ; CHS=00: channel GP0/AN0
    ; GO=0: not converting yet
    ; ADON=1: ADC is enabled
    movlw b'01000001'
    movwf ADCON0

    ; We can write to the GP2 latch even if it's still in input mode;
    ; this ensures no glitch between clearing TRIS and sending the GP2 output.
    ; (but this doesn't work in the simulator)
    btfsc GPIO, GP1  ; Check GP1 status (negative logic)
    goto gp1_off
gp1_on:            ; if it's clear, port 1 is on
    bsf GPIO, GP2  ; turn GP2 on
    goto gp2_done
gp1_off:           ; if it's set, port 1 is off
    bcf GPIO, GP2  ; turn GP2 off
gp2_done:

    movlw b'1011'  ; only GP2 output, others input
    tris GPIO

As in the comments - in real life this works, but in the MPLABX simulator attempted modifications to GP2 have no effect. Why would this be? Have they failed to model the write latch as being functional even when the corresponding TRIS bit is still high (input)?

This seems pertinent:

BIDIRECTIONAL I/O PORTS

Some instructions operate internally as read followed by write operations. The BCF and BSF instructions, for example, read the entire port into the CPU, execute the bit operation and re-write the result. Caution must be used when these instructions are applied to a port where one or more pins are used as input/outputs. For example, a BSF operation on bit 2 of GPIO will cause all eight bits of GPIO to be read into the CPU, bit 2 to be set and the GPIO value to be written to the output latches. If another bit of GPIO is used as a bidirectional I/O pin (say bit 0) and it is defined as an input at this time, the input signal present on the pin itself would be read into the CPU and rewritten to the data latch of this particular pin, overwriting the previous content. As long as the pin stays in the Input mode, no problem occurs. However, if bit 0 is switched into Output mode later on, the content of the data latch may now be unknown.

\$\endgroup\$
  • \$\begingroup\$ Just to be clear, are you saying that you've stepped through the code line-by-line in the simulator, and the bsf GPIO, GP2 and bcf GPIO, GP2 instructions have no effect on the GPIO register while TRISGPIO2 is a 1? \$\endgroup\$ – brhans Oct 6 '18 at 21:27
  • \$\begingroup\$ @brhans That's correct. \$\endgroup\$ – Reinderien Oct 6 '18 at 21:28
  • \$\begingroup\$ Then it looks like a bug in the simulator to me. \$\endgroup\$ – brhans Oct 6 '18 at 21:41
  • \$\begingroup\$ @brhans I don't have much choice but to conclude that you're correct. Submit an answer, if you want. \$\endgroup\$ – Reinderien Oct 7 '18 at 14:57
2
\$\begingroup\$

Figure 5-1 is a bit misleading. In fact none of the PIC10F220's I/O pin circuits look exactly like that. Here's the circuit for pin 2:-

enter image description here

Note that GP2's output driver is disabled when T0CS is high. T0CS is bit 5 of the OPTION register, and guess what? Yes, it's high at power on!

To enable digital output on pin 2 you need to clear the T0CS bit in the option register, like this:-

movlw b'11011111' ; T0CS low, other option bits high
option

If you want to use GP0 or GP1 as outputs then you have a similar problem. These pins are shared with analog inputs AN0 and AN1, which are enabled at power on. To enable their digital outputs you need to clear the ANS1 and ANS0 bits in ADCON0.

EDIT:

Your updated code simulated correctly for me in MPLab 8.92 but not in MPLabX 3.65, which suggests a bug in the MPLabX simulator.

\$\endgroup\$
  • 1
    \$\begingroup\$ I had already taken into account OPTION; I just hadn't shown it in the assembly excerpt. Also, incorrect setup of the option register wouldn't explain why it works in-circuit but not in the simulator. \$\endgroup\$ – Reinderien Oct 7 '18 at 4:54
  • \$\begingroup\$ "incorrect setup of the option register wouldn't explain why it works in-circuit but not in the simulator. " - it might if some other code (that you didn't show us) changed the configuration. However I have now tested your updated code in MPLabX and it fails, which suggests a bug in the simulator. I suggest using the simulator in MPLab 8.92, which works correctly. \$\endgroup\$ – Bruce Abbott Oct 7 '18 at 15:35

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.