0
\$\begingroup\$

I'm trying to understand how to operate an open-drain I/O port on an older PIC (PIC16F1718.) My goal is to use it for bit-banged bidirectional open-drain I2C communication.

I know how to enable and disable open drain mode, but from there I'm not sure how to control it. To control the output, do I change the output value (PORTx or LATx) or do I change the pin mode (TRISx)? How do I set the registers if I want to read in a value?

I figured these questions would be straightforward to answer from the datasheet, but it doesn't show the open-drain register (ODCONx) on its I/O port logic diagram, and all it says about open-drain control is how to enable the mode.

PIC16F1718 I/O Port Logic Diagram

Datasheet Page 123:

https://ww1.microchip.com/downloads/en/DeviceDoc/PIC16F-LF-1717-8-9-Data-Sheet-DS40001740D.pdf

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Not only is open-drain missing from that diagram, but weak pullup is missing as well. And input level (TTL/Schmitt) is missing too. I'd guess the diagram is simplified so as to not overwhelm. \$\endgroup\$ Commented Jul 8, 2021 at 0:58

2 Answers 2

3
\$\begingroup\$

Look at the description of the OPEN-DRAIN CONTROL register (on page 123 of the datasheet):

The ODCONA register (Register 11-6) controls the open-drain feature of the port. Open-drain operation is independently selected for each pin. When an ODCONA bit is set, the corresponding port output becomes an open-drain driver capable of sinking current only. When an ODCONA bit is cleared, the corresponding port output pin is the standard push-pull drive capable of sourcing and sinking current.

Since all this register does is change the output from push-pull to open-drain, you would use the PORTA register in both cases: writing a zero to PORTA sets the output pin low; writing a one sets the output high (for push-pull) or high-Z (for open-drain). This all assumes the direction control is set to output.

\$\endgroup\$
0
\$\begingroup\$

It’s been a long time since I’ve looked at a PIC16, so my memory might be a little hazy, nevertheless the ‘usual’ method of open drain is to set the port bit to 0 and manipulate the tris bit. So to output a logic 0, the port bit has already been set to 0 then tris = 0 to enable the output. For a logic 1 we rely on external pullup resistors and set the port to be an input by tris = 1.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ That's what you do when the pin doesn't have "official" open-drain capability. It's not necessary in this case. \$\endgroup\$ Commented Jul 8, 2021 at 2:52
  • 1
    \$\begingroup\$ Yes that's actually how we've done open drain in the past, and it works. But then I noticed there is actually an "open drain" feature and I'm hoping that somehow it will be better \$\endgroup\$ Commented Jul 8, 2021 at 4:57

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.