Jump to content
Sign in to follow this  
don_erickson

Bit I/o Difficulties

Recommended Posts

Using Sourceboost 5.6.1, BoostC 1.5, on a 16F87.

I am a beginner, and I have been struggling to learn how to handle bits on portb. I have posted other inquiries.

 

I am using bits 0 and 1 as outputs; bit 0 for a Sonalert, and bit 1 for a relay.

So, I have:

#define Relay 0 // Port B bit 0 relay

#define Sonalert 1 // Port B bit 1 sonalert

 

and I can use

 

set_bit(portb, Relay); // turn on relay

 

which generates

 

03D4 0614 BSF gbl_portb,0

 

and this works fine. Sonalert on bit 1 also works fine.

 

I also use bits 2 and 3 of the same port as inputs; two switches. (trisb = 0x0C).

So, it would seem reasonable to have:

#define CHG 2 // Port B bit 2 input - Change

#define S_R 3 // Port B bit 3 input - Set/Reset

 

since if the outputs work defined as the bit number, the inputs should also work defined as the bit number.

 

So when I do this, for the S_R switch on bit 3 for example, I have

 

if ((portb & S_R) == 0) { // reset

 

which generates

 

0112 0330 MOVLW 0x03

0113 0313 BCF STATUS, RP1

0114 0605 ANDWF gbl_portb, W

0115 031D BTFSS STATUS,Z

 

But note that this is looking bits 0 and 1 -- I wanted it to look at bit 3.

I have to define S_R as the VALUE of bit 3 and not the bit number.

Thus:

 

#define CHG 4 // Port B bit 2 input - Change

#define S_R 8 // Port B bit 3 input - Set/Reset button

 

Now, the same

 

if ((portb & S_R) == 0) { // reset

 

generates

 

0110 8619 BTFSC gbl_portb,3

 

which is not only simpler, but it also looks at bit 3 like I wanted.

 

It took me a couple of days to learn that if I am treating bits on a port as outputs, I define them with the bit number, but if I am using them as inputs, I must define them with the value of the bit, not the bit number.

Is this a lack of consistency, or am I making things difficult for myself?

 

Thanks

Don Erickson

Share this post


Link to post
Share on other sites

First off i hope im saying something usefull :)

 

but i think the problem is that, first you use a method

 set_bit(portb, Relay);

which is created so that you give the decimal number for the bit you want to set.

 

the second time it is a bit diffrent

if ((portb & S_R) == 0) { // reset

the value for S_R will not be decimal as before but it wil be binary.

Or i should say, Your macro in the first example is decimal and in the if example its binary. That makes sense cuz decimal 4 is binary 100 and is bit 2 and decimal 8 is 1000 and is bit 3.

 

you might want to use

 

#define Sonalert 0x1 // Port B bit 0 output

#define Relay 0x2 // Port B bit 1 output

 

portb=Relay+Sonalert; //set bit 0 and 1

 

I dont know if you can easily keep the consistency you want. im sure you can write methods te keep the consistency but i do not know if there are standard solutions for it. im no pro either but hoped it helped.

Share this post


Link to post
Share on other sites

Or, if you want to maintain consistency, you could 1) write your own isset_bit() type macro (as mentioned by Yodar), or 2) use the form:

 

if ( portb>>S_R & 0x01 )

 

Hope that's helpful.

 

--josef

Share this post


Link to post
Share on other sites
Or, if you want to maintain consistency, you could 1) write your own isset_bit() type macro (as mentioned by Yodar), or 2) use the form:

 

if ( portb>>S_R & 0x01 )

 

Hope that's helpful.

 

--josef

 

I find this to be a bit more readable:

 

if ( portb & (1 << S_R) == 0)

 

Don, take a look at the boostc.h file included with boostc (And you might want to grab the latest version of the compiler and ide while you're at it).

 

you can see how the set_bit and clear_bit macro's are defined.

Share this post


Link to post
Share on other sites
I find this to be a bit more readable:

 

if ( portb & (1 << S_R) == 0)

 

Don, take a look at the boostc.h file included with boostc (And you might want to grab the latest version of the compiler and ide while you're at it).

 

you can see how the set_bit and clear_bit macro's are defined.

 

Good call. That is more readable. So, you could define something like:

 

#define isset_bit( reg, bitNumb ) reg & (1 << bitNumb)

 

resulting in:

 

if (!isset_bit(portb,S_R))

 

--josef

Share this post


Link to post
Share on other sites

Hello All,

 

My prefered method is the neatest of all and generates very efficient code:

 

#define PORTB 0x06

volatile bit myInput @ PORTB.0; // RB0
volatile bit myOutput @ PORTB.1; // RB1

main()
{
   InitIo(); // sets up my port b - this routine needs to be coded
  
   if( myInput ) // is input on
       myOutput = 1; // turn output on
}

 

Hope this helps :)

 

Regards

Dave

Share this post


Link to post
Share on other sites
Hello All,

 

My prefered method is the neatest of all and generates very efficient code:

 

#define PORTB 0x06

volatile bit myInput @ PORTB.0; // RB0
volatile bit myOutput @ PORTB.1; // RB1

main()
{
   InitIo(); // sets up my port b - this routine needs to be coded
  
   if( myInput ) // is input on
       myOutput = 1; // turn output on
}

 

Hope this helps :)

 

Regards

Dave

 

 

Haha, Thanks Dave, that one IS the easiest to read.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...