[Help] 16F877a MPLAB x

Discussion in 'Embedded Systems and Microcontrollers' started by wimpylicious, Sep 19, 2013.

  1. wimpylicious

    Thread Starter New Member

    Sep 19, 2013
    Code ( (Unknown Language)):
    2. #define XTAL_FREQ 20MHZ
    3. #define _LEGACY_HEADERS
    4. #include <htc.h>
    6. __CONFIG(0X3F32);
    8. void main(void)
    9. {
    10.     ADCON1= 7;
    11.     TRISB = 0x00001111;
    13.     while(1){
    14.         RB0 = 1;
    15.         RB1 = 1;
    16.         RB2 = 1;
    17.         RB3 = 1;
    19.         if(RB4==1){
    20.             RB0=0;
    21.         }
    22.         if(RB5==1){
    23.             RB1=0;
    24.         }
    25.         if(RB6==1){
    26.             RB2==0;
    27.         }
    28.         if(RB7==1){
    29.             RB3==0;
    30.         }
    31.     }
    32. }
    Just a simple coding, i tried to light up LED at RB0 - RB3 (outputs).
    Then if i input wire 5V (from Vcc) to RB4 - RB7 (inputs), i want to turn off the LED. Why wouldn't it work?
    and somehow the LED at RB0 doesn't light up, but the other three does.
    Last edited by a moderator: Sep 19, 2013
  2. MaxHeadRoom


    Jul 18, 2013
    I don't program is C but if the TRISB is setting the four LSB to one, they will be set as inputs?
  3. t06afre

    AAC Fanatic!

    May 11, 2009
    What is that "magic" number used for the config bits. It may be correct. But I have no intention of looking that number up. Use this approach instead http://microchip.wikidot.com/mplab:how-to-view-and-set-configuration-bits
    Also replace #include <htc.h> with #include <xc.h> And remove the
    #define _LEGACY_HEADERS
    This program will also spinn around quite fast. So it will look like all LEDs are on constant
  4. JohnInTX


    Jun 26, 2012
    Yup. 1 makes it input, 0 makes it output. For this one TRISB=0b11110000; (not x).

    As t06afre says, your LEDs will spin quite fast. (I also agree with using the newer .h files)

    You could add some delay to slow things down but if you are trying to make the LEDs follow inputs there is another problem. Setting all of the LEDs ON then selectively turning them off means that your I/O has stray, non valid outputs e.g. if RB4==1, the RB0 will not be a steady 0 but will toggle at the rate determined by the loop delays. It might be OK for an LED but maybe not if you were trying to drive something else.. Its not a good programming practice.

    A better way would be:
    Code ( (Unknown Language)):
    1. if (RB4==1)
    2.   RB0 = 0;
    3. else
    4.   RB0 = 1;
    An even better way would be to declare a temp char variable, build the LED image into it then write the whole byte to the PORT. Advantages of this approach are:
    You actually now can clear the temp variable, build the (entire) LED image into it and write to the port by PORTB=temp; You also can just maintain a copy of what's on the port, flip individual bits then write to the whole port.
    You don't risk the r-m-w problem that can occur when bit flipping on ports in midrange parts. ( I NEVER bit flip midrange ports for that reason).

    As the others have said, set the config bits (ALL of them) to match your hardware.

    Good to go.
    Have fun.

    BTW: you haven't initialized PORTs A, C, D or E. Just because you are not using them doesn't mean that they are not there. They power up in a combination of analog and digital ports. Any good design will initialize the WHOLE system, not just the areas you are using.
    Last edited: Sep 19, 2013
  5. wimpylicious

    Thread Starter New Member

    Sep 19, 2013
    thanks for the tips peeps, i found out that my input pin was always high, therefore i connected a 1k resistor to ground, then when 5V gets in, it gets high input. (not sure why though, maybe because the internal resistance thingy?)
  6. tshuck

    Well-Known Member

    Oct 18, 2012
    It appears you are groping around for the solutions, without understanding the problem. Post your revised code (including configuration bits) and schematic so we can have a basis for helping you.

    You do have a crystal/external oscillator connected to the PIC, right?
  7. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    Took me years to notice one coincidence with each and every PIC TRIS register:

    To set as an 1nput, set the bit to one.

    To set as an 0utput, set the bit to zero.

    See it? 1 is 1nput, 0 is 0utput.
    absf likes this.
  8. Art

    AAC Fanatic!

    Sep 10, 2007
    What a mess..

    Code ( (Unknown Language)):
    2. var temp byte
    4. while(1) {
    5. temp = PORTB
    6. PORTB << 4
    7. PORTB = temp ^ 0xFF
    8. }
    Can you cycle port bits in a for/next loop in C?

    Code ( (Unknown Language)):
    2. for (int i=4;i<7;++i)
    3.     {
    4.     if portb.i-4 = 1 {portb.i = 0} else {port.i = 1}
    5.     }
    Last edited: Oct 1, 2013
  9. joeyd999

    AAC Fanatic!

    Jun 6, 2011
    Or, in only 3 instructions:

    Code ( (Unknown Language)):
    1.     comf    portb,w
    2.     swapf   wreg,f
    3.     movwf   latb
    But C is sooooo much better!
  10. Art

    AAC Fanatic!

    Sep 10, 2007
    Yes, but I don't know if the C supports inline asm to do the compliment in one instruction,
    or even if writing back to portB resets tris like it does in PicBASIC.
    I wouldn't start out by wasting an 8 bit wide port by splitting it.

    How is this anything other than a waste of time and memory?

    Only if they've done something to directly address bits, or it can do inline asm,
    Otherwise how to count the number of live bits in this byte:
    Code ( (Unknown Language)):
    2. 01010101.
    With a temp variable and a mask?
    How is that going to go when you want to compliment every value for a binary bitmap mask or some other real job?
    This was done in C, but bits replaced with byte values 0x00 or 0xFF,
    because a C routine would take forever to bit bang the real binary.
    Last edited: Oct 1, 2013