[Help] 16F877a MPLAB x

Thread Starter

wimpylicious

Joined Sep 19, 2013
2
Rich (BB code):
#define XTAL_FREQ 20MHZ
#define _LEGACY_HEADERS
#include <htc.h>

__CONFIG(0X3F32);

void main(void)
{
    ADCON1= 7;
    TRISB = 0x00001111;
    
    while(1){
        RB0 = 1;
        RB1 = 1;
        RB2 = 1;
        RB3 = 1;

        if(RB4==1){
            RB0=0;
        }
        if(RB5==1){
            RB1=0;
        }
        if(RB6==1){
            RB2==0;
        }
        if(RB7==1){
            RB3==0;
        }
    }
}
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:

JohnInTX

Joined Jun 26, 2012
4,787
I don't program is C but if the TRISB is setting the four LSB to one, they will be set as inputs?
Max.
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:
Rich (BB code):
if (RB4==1)
  RB0 = 0;
else
  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:

Thread Starter

wimpylicious

Joined Sep 19, 2013
2
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?)
 

tshuck

Joined Oct 18, 2012
3,534
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?)
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?
 

ErnieM

Joined Apr 24, 2011
8,377
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.
 

Art

Joined Sep 10, 2007
806
What a mess..

Rich (BB code):
var temp byte

while(1) {
temp = PORTB
PORTB << 4
PORTB = temp ^ 0xFF
}
Can you cycle port bits in a for/next loop in C?

Rich (BB code):
for (int i=4;i<7;++i)
    {
    if portb.i-4 = 1 {portb.i = 0} else {port.i = 1}
    }
 
Last edited:

joeyd999

Joined Jun 6, 2011
5,283
What a mess..

Rich (BB code):
var temp byte

while(1) {
temp = PORTB
PORTB << 4
PORTB = temp ^ 0xFF
}
Can you cycle port bits in a for/next loop in C?

Rich (BB code):
for (int i=4;i<7;++i)
    {
    if portb.i-4 = 1 {portb.i = 0} else {port.i = 1}
    }
Or, in only 3 instructions:

Rich (BB code):
	comf	portb,w
	swapf	wreg,f
	movwf	latb
But C is sooooo much better!
 

Art

Joined Sep 10, 2007
806
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.

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.
How is this anything other than a waste of time and memory?

But C is sooooo much better!
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:
Rich (BB code):
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?
http://www.youtube.com/watch?v=FIYnFaCxbiQ
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:
Top