On my project, I plan to have a user configurable setting set using a switch. Unfortunately, it looks like I don't know how to read from a port.

I'm using PIC18F4680 and C18 compiler.

Here's the picture of the circuit:



Circuit description:

The pin 19 is set as high and resistor R3 is set between pin 19 of the PIC and pin 3 of the switch. Pin 20 of the PIC is connected to the pin pin 2 of the switch. Pin one of the switch is connected via R37 to the circuit ground. Using a multimeter, I can see that when the switch is set so that the switch's pins 2 and 3 are connected on the PIC pin 20, there is at logical high voltage (around 4.96 V). When the switch is set so that switch's pins 1 and 2 are connected, I can see that the PIC's pin 20 is at logical low voltage (around 40 mV). The pin settings are exactly as shown below. As far as I know, on this PIC there are no internal pull-up resistors on port D.

Pin 19 is RD0 on this PIC and pin 20 is RD1 on this PIC.

I've set the RD0 like this:

TRISDbits.RD0=0;//Set as output 

and RD1 like this:

 TRISDbits.RD1=1;//set as input

When the switch is set so that the RD0 is connected to RD1, I can read 4.96 V on the RD1 pin, so after reading, I should get high value. Unfortunately, when I read it using this code:


where PortD1 is a char.

I always get PortD1 value of zero, no matter in which position the switch is.

I'm not using any of the devices which are multiplexed to pins RD0 and RD1.

So what am I doing wrong here?


I added

CMCON = 0;

to the start of my program, so comparator and parallel slave port should be disabled and shouldn't interfere with port D. Also I'm not using hardware PWM, so it shouldn't be causing problems.


On this chip, I'm using port E to drive an 8 bit multiplexer, which is working correctly. The strange thing is that when I try to read status of port E, using


I get zeroes both times although I know that the value isn't zero. So it looks like the problem isn't specific to port D.


After some more testing, I was unable to repeat the problems with reading LAT registers. It seems that they are read fine now.


After doing some more testing, it appears that ports A, B and C provide results same as LAT A, B and C registers. Ports D and E always read zero, no matter what is written into their LAT registers. It turns out that port E was zero because it was set as analog input. After setting ADCON1bits.PCFG=255;, port E works now.


I've also disabled the ECCP module using ECCP1CONbits.ECCP1M=0; and it didn't make any difference. I've accounted for all multiplexed modules on port D and they are all disabled.

  • 3
    \$\begingroup\$ No, that's a picture of your PC board. It doesn't tell us much about the circuit. \$\endgroup\$ – Olin Lathrop Jul 1 '12 at 16:29
  • \$\begingroup\$ @Olin Lathrop I didn't know pictures talk. \$\endgroup\$ – AndrejaKo Jul 1 '12 at 16:31
  • 2
    \$\begingroup\$ I might be missing something here, but if all you need is an on/off value corresponding to the setting of the switch, why not just make it with a single pull-up/down resistor? en.wikipedia.org/wiki/Pull-up_resistor \$\endgroup\$ – sonicwave Jul 1 '12 at 17:09
  • \$\begingroup\$ @sonicwave Mostly because this setup was the first that I thought of. Also since this is going to be a single device, the price of such components doesn't matter much. \$\endgroup\$ – AndrejaKo Jul 1 '12 at 17:12
  • \$\begingroup\$ Not so much because of the cost, more due to a pull-up/down being the standard way of doing it. With your current setup though, I'd probably just remove the resistors and connect the input directly to ground/your "high" voltage (although I'll admit I haven't worked with PICs before, so there might be reasons not to do this). \$\endgroup\$ – sonicwave Jul 1 '12 at 20:47

I think Wouter had the right idea, but you need to put CMCON = 0x07; to turn the comparators off (see p.258 of datasheet, top right)

| improve this answer | |
  • \$\begingroup\$ I have no idea how many times I read that page and I've always understood the diagram to say that comparators are disabled when CMCON = 0. Thanks a lot! \$\endgroup\$ – AndrejaKo Jul 2 '12 at 4:36
  • \$\begingroup\$ It's things like this that drive me crazy about the PIC. \$\endgroup\$ – Rocketmagnet Jul 2 '12 at 11:27

Since Wouter's guess wasn't it (it was a reasonable guess given the information you provided), it may be something electrical. How exactly is the switch connected to the port pin? Normally the switch would be between the port pin and ground, which means there needs to be a pullup to Vdd. Some pins on some PICs have these internal. If so, you can turn it on. If not, you have to add your own pullup resistor externally.

If the switch is connected between the pin and Vdd, then you need a pulldown. That has to be external because I know this PIC does not have internal pulldown resistors.

Your switch shows 3 pads. Are you using all of them? Show a schematic of exactly how everything is connected.


Your circuit (which wasn't described before) doesn't make much sense. I don't see the point to the two resistors nor why a second I/O line is envolved in such a strange way. The normal way to connect a switch is:

This is the simplest case where you only have a SPST switch. Note that this method works fine with momentary pushbuttons too. As I said earlier, some PIC pins have optional internal pullups. In that case you can just connect the switch between the PIC pin and ground without anything else. R1 is then essentially inside the PIC.

You have a SPDT switch, so you can do this without any extra parts than just the switch:

| improve this answer | |
  • \$\begingroup\$ Yes, I'm using a switch that connects two of the three pads together at one time (I can't remember how that type is called in English at the moment). \$\endgroup\$ – AndrejaKo Jul 1 '12 at 16:53
  • \$\begingroup\$ @AndrejaKo - a change-over switch, or C-O, or SPDT, for single pole, double throw. \$\endgroup\$ – stevenvh Jul 1 '12 at 16:54
  • \$\begingroup\$ Actually for the second diagram, the problem is that I don't trust myself enough not to set the input pin as output low and create a short this way. With resistors, if I do that, nothing terribly bad should happen. \$\endgroup\$ – AndrejaKo Jul 2 '12 at 4:37
  • \$\begingroup\$ @AndrejaKo: Then you still only need a single resistor in series with the PIC pin. 10 kOhm would is a good knee-jerk value. \$\endgroup\$ – Olin Lathrop Jul 2 '12 at 14:09

Disable the comparator module:

CMCON = 0;

| improve this answer | |
  • \$\begingroup\$ It didn't help. Also from the datasheet about port D:On a Power-on Reset, these pins are configured as digital inputs., so the extra devices shouldn't interfere. \$\endgroup\$ – AndrejaKo Jul 1 '12 at 16:24

I had the same problem with a PIC18F46K20, I found that it was because i set LATE = 0b11111111; in my initialisation. Looking at the datasheet PORTE only has 3 physical pins on LATE and the others have other functions. As soon as I changed my code to be LATE = 0b00000111; it worked and I could read PORTD again

| improve this answer | |

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.