Pinouts go low after PORTC AND operation

Discussion in 'Embedded Systems and Microcontrollers' started by DR4DR4, Aug 5, 2012.

  1. DR4DR4

    Thread Starter New Member

    Aug 5, 2012
    Hi, this is my first post. I'm new to programming and micro controllers but have started using a few PIC's with MPLAB X and the HITEC C version9..? something compiler.

    This is only a query as I would like to know why I'm getting this particular behaviour which I will try to explain. I'm using a 16F690 PIC on a low pin count board and a pickit 2 programmer.
    I also made myself a hardware tfla-01 logic analyzer, the design with it's own power and resistors and an isolating chip. I made it a little while ago so can't remember details but it's not relevant to my question.

    I read an article about left shifting a binary and OR' ing it with the port register to turn pins high and AND'ing a two's complimented version for low. I have walked the below code through using MPLAB's simulator. Viewing the PORTC register contents goes like I would have thought it should.

    starts – 000000 ...→ 000001 → 000011 → 000111 → 001111 → 001110...[the final &=~]

    Also when I use the software logic analyzer in the simulator to trace RC0-RC3 they go up as I would expect consistent with the above. What should happen then is rc0 goes up, then rc1..rc2..rc3.
    Then rc0 should go low.. this loops so rc0 toggles of and on but the other pins stay high.

    Now I program my PIC and get each led light in sequence from rc0 to rc3 turn on individually.
    When I trace using the hardware tfla-01 analyzer this confirms after each shift operation only the shifted bit brings that pin high, the other 1's that remain in the PORTC register don't keep their respective pins high. The time delay between shifts is set to 500ms. Code snippet below.

    Portc set for ouput and initialized all pins low...+ #define delay 500
    PORTC|=(1<<0);//enable rc0 - zero shift 1 then OR with portc register
    PORTC|=(1<<1);//rc1 up
    PORTC|=(1<<2);//rc2 up
    PORTC|=(1<<3);//rc3 up

    PORTC&=~(1<<0);//disable rc0

    So my query is why when bit's are set to 1 in the PORTC register do they not hold the pin high. They only hold the individually shifted bit place pin high, the rest go low. The 16F690 does not support in circuit debugging without a header so I can't know that on the chip this is also the case and it may differ from the simulated register.

    I'm aware that the software simulation is just that already after trying to trace clkout signal, this signal does not exist on the simulator but does when using the chip.

    This may be very obvious to someone with more experience but at this time of writing I would have thought all 1's in the register would keep the pinouts high.
    Any explanations welcomed.

  2. BMorse

    Senior Member

    Sep 26, 2009
    Might have something to do with the uC's "write then read" on the ports (dont really have time to go through datasheet), try assigning the values to a variable then transfer data to port pins. . .
    DR4DR4 likes this.
  3. MrChips


    Oct 2, 2009
    You are assuming that the instruction (1<<3) etc. shifts a 1 in from the right.
    This is not so.
    DR4DR4 likes this.
  4. JohnInTX


    Jun 26, 2012
    Have you cleared the ANSELH and ANSEL registers to make the port pins digital? They are analog when the PIC is reset. You can output a 1 but when you do a r-m-w on the port for the next pattern the 1 you just wrote will be read back as 0 and clear the LED pin when the new pattern is written to the port.

    A secondary point here perhaps but yeah, in my world, that's the ONLY way I do midrange I/O.. for lots of good reasons.
    Last edited: Aug 5, 2012
    DR4DR4 likes this.
  5. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    Your code is doing what you told it to do. Here's the terms broken out to show what values are really being used:
    Code ( (Unknown Language)):
    1. PORTC = 0
    3. PORTC   |= (1<<0);
    4.         |= 000001
    5.          = 000001
    7. PORTC   |= (1<<1)
    8.         |= 000010
    9.          = 000011
    11. PORTC   |= (1<<2)
    12.         |= 000100
    13.          = 000111
    16. PORTC   |=(1<<3)
    17.         |= 001000
    18.          = 001111
    20. PORTC   &= ~(1<<0)
    21.         &= ~000001
    22.          =  111110 & 001111
    23.          =  001110
    Note this is not C code, just the actual data being used.
    DR4DR4 likes this.
  6. DR4DR4

    Thread Starter New Member

    Aug 5, 2012
    Thanks to everybody for the replies.

    The ANSEL & ANSELH analogue select registers were at their default enabled.
    I cleared these registers and the lights stayed on as I had first thought they would.
    So this was in fact the thing stopping my lights from staying on and my port pins from staying high.

    I see lots of references to use another register when setting the port registers for reliable behaviour and to avoid any read-modify-write issues so I will use this method in the future.

    My issue is solved so thanks for that

    Not really an issue but…

    The RC4 port is not an analogue port and was the one port that went high and stayed high. This makes sense because it’s digital i/o and behaved like the other ports when they were analogue disabled.

    When I disabled analogue via ANSEL this port behaved differently, which I did not expect. With the same program it blipped high for half a millisecond or so and stayed low ‘maybe’ pulling the rest of the pins low as well until the next instruction to clear RC0. At this time it went high along with the rest of the port pins that were supposed to be staying high.

    Maybe it’s down to my circuit, rc4 is not connected to anything, the leds are on ports rc0-rc3. Or maybe it’s some other fuse setting, should ANSEL&ANSELH only affect the analogue pins.

    Again to summarize by setting ANSEL & ANSELH to zero the shift to enable RC4 pulls all up pins low until the next shift to clear RC0 when RC1-RC4 all go high again.

    Code snippet:-

    Analyzer output with RC4 enable commented out [ch3-ch7=RC0-RC4]:-

    Output with RC4 statement uncommented:-

    Just curious if anybody knows why that happens?

    Thanks again Doug.
    Last edited: Aug 8, 2012