PIC Programming Doubts

Discussion in 'Embedded Systems and Microcontrollers' started by nelsonys, Apr 18, 2011.

  1. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    Hi, I'm a newbie in PIC programming, hopefully I can learn something from all of the masters here...

    I'm really confused with different compilers come with different statement for some simple operation like blinking a LED.

    I would like to stick to MPLAB C18 compiler as I'm trying my first PIC programming using the PICkit 3 debug express.

    There's some statement that I would like to seek for clarification.
    What is the difference between:

    1. LATDbits.LATD0 = 0
    2. TRISDbits.TRISD0 = 0
    3. PORTDbits.RD0 = 0

    For 2, is it when I declared TRISD = 0, then the statement of 2. become unnecessary?

    By the way, is there any documents or guides that I can find these kind of statements?

    Thanks!
     
  2. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    and also people do write something like this:
    4. PORTD = 0

    Confused -___-
     
  3. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    TRISDbits.TRISD0 = 0; sets bit 0 of the register TRISD to 0 and leaves bits 1 to 7 untouched whereas the command TRISD = 0 sets all the bits (0 to 7) of register TRISD to 0.

    Same with the PORTDbits.PORTD = 0; command acts on bit 0 and PORTD = 0; act on the whole register.

    Any command in the form REGISTERNAMEbits.BITNAME acts on one specific bit of the register whereas a command just stating the REGISTERNAME act on the whole register (all the bits).

    Look in the header file for the chip you are using to find the valid names of registers and register bits.
    For example if you were coding for a PIC18F2525 chip the header file C:\MCC18\h\p18f2525.h would contain the definitions of all register and bit names for that chip.
     
    Last edited: Apr 18, 2011
  4. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    Thanks Alex...

    There's a book written that if u TRIS a port to become input, then it's better to use PORTX = 1 instead of LATXbits.LATX = 1 in order to make the port read in external signal.

    Is it a hard and fast rule?
     
  5. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    When reading a port you should read from the PORT that way you read the current state of the port pins rather than the state of the port latch, eg my_variable = PORTD;.

    When writing to a port you should write to the port latch, eg LATD = 0x7F;

    If a port is set as an input you can't write to it so a statement such as PORTD = 1; will have no effect.
     
  6. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    Thanks Alex,

    I thought PORTD = 0 has no effect rather than 1?

    Please check if my concept is wrong:
    1. If I TRISD = 0, then LATD = 0 means that RD7:0 output as 1
    2. If I TRISD = 1, then PORTB = 0 means that RD7:0 read for input, whereas PORTB = 1 is meaningless.
    3. If I need to read a switch input from RB0, I have to call and enable the internal pullup of RB0 first before it is able to read anything. There's a doubt here, external pullup does not play a sufficient role in this case? Besides, it is really important to declare ANSELH = 0x00 to define that it is a digital input? Could it be skipped?
     
  7. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    1. If TRISD = 0 then all pins of port D are set as outputs and anything you write to LATD will be output on the port pins so if you were to write 0x7F to LATD then RD7 would output 0 and RD6-RD0 would output 1. To set all portD pins as outputs you would have to write TRISD = 0xFF.

    2. If TRISD =1 then pin RD1 is set as a input, all other pins (RD0, RD2-RD7) will be outputs.
    PORTD = 0 will write 0 to all PORTD pins that are set as outputs and have no effect on pins set as inputs.
    PORTD = 1 will write 1 to pin RD0 and 0 to RD1-RD7, it will have no effect on any pin set as an input.
    To be correct you should write to the LATD but most of the time (not always) writing to PORTD will have the same effect. You should however get into the habit of always writing to the LAT rather than the port.

    3. It all depends on how the switch is wired. If the switch has its own external pull-up then you obviously don't need the internal pull-ups enabled, otherwise you do.
    All ports that are capable of being configured with analog functions always default to the analog state so if you use want to use one of these ports or pins for digital input then you must first disable all analog features on that port or pin. Obviously if all you are using is PORTB which has not analog functions then you don't need to worry about any ANSEL command.
     
  8. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    Thanks Alex,

    Here's a code:

    void main (void)
    {
    TRISD = 0b01111111; // PORTD bit 7 to output (0); bits 6:0 are inputs (1)
    // LATDbits.LATD7 = 1; // Set LAT register bit 7 to turn on LED
    // while (1)
    ;

    }

    even if I masked LATDbits.LATD7 = 1 and while(1)
    the LED7 is still ON and endlessly. This is kind of confusing...

    I thought TRIS is to set the port status, LAT is to toggle port in or out?
     
  9. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    LAT sets port pins high or low, TRIS set the pins as either output or input.

    Your program is doing what it should, it is turning on RD7 (lighting the LED) and then going into an endless loop. Try changing the LAT command to LATDbits.LATD7 = 0; and see if that makes the LED stay off.
     
  10. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    Sorry Alex, I'm quite stupid understanding this...

    What I don't understand is TRIS is to set the direction of the port, but now even if I don't latch the RD7 to high, it also output a current by tristating RD7 to output only.

    Of course by latching RD7 to 0, the LED would be off. So I am confused that just by tristating RD7 to output, would it be meaningless to latch RD7 to high anymore?
     
  11. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    I feel that the default logic signal on the port is high...
     
  12. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    Hi Alex, I found the main problem here.
    This time I'm lucky that when I tristate the RD7 for the first time:
    TRISD = 0b01111111;
    without declaring LATDbits.LATD7 = 1, it did not light the LED7
    But right after I successfully lighted up the LED7, and clear the flash memory for reprogramming, this time I deleted the latchup statement and it gives me light up LED7 by simply tristating the RD7 only.

    Is it the previous logic level will be left on the port as long as the PIC is power-up?
     
  13. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    The TRIS does not tristate the port, it simply sets the direction of the port pins (input or output). Output ports are either at logic 0 or 1, input ports are high impedance unless its PORTB and weak pull-ups are enabled.

    When the PIC boots up its ports pins don't come up any predefined state, whether a pin that is set as an output comes up logic 0 or logic 1 is a matter of pure chance so in any program you write should initialise the port to a know state before you start to use it.
     
  14. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    21
    0
    OIC... that's why I saw some examples that some authors usually clear the port first by latching it to logic 0.

    Thanks a lot for clarifying my doubts!
     
Loading...