please dont rip this site

PIC Microcontoller C Bit Math Methods

Bob Blick says:

The basis for all bit tests is AND, so if you are trying to test bit 3 of a variable, the compiler is doing this:
if(variable & 0b00001000)

or to see if it's clear:

if !(variable & 0b00001000)

All the special bits in a PIC are already defined, so if you want to test or modify a port pin you can refer to it directly, as in:

if(RB3 == 0)

setting bits works the same way and you must still remember the caveats about modifying individual pins on a port(they are single cycle read-modify-write and if the port is forced externally or there is capacitance slowing the port down you can get bits set differently than you thought) or say you want to start the A/D converter:

ADGO = 1;

For general variable bit access you either need to use AND tests as most C texts would suggest or do a union as described in another email answer, or something like one of these two methods as described by Clyde.

from the hitech FAQ here are some approved ways to test, set and clear bits:

Q: I want to be able to access single bits in a byte, but if I try to define a bit variable using the absolute variable construct, e.g.
static bit bitvar @ ((unsigned)&bytevar)*8+0;

I get a compiler error. How can I do this?

A: The short answer is "you can't do this". The absolute variable construct using @ requires an address known at compile time. The long (and more useful) answer will depend on what you're actually trying to do. You may find all you need is some simple macros like:

#define  testbit(var, bit)   ((var) & (1 <<(bit)))
#define  setbit(var, bit)    ((var) |= (1 << (bit)))
#define  clrbit(var, bit)    ((var) &= ~(1 << (bit)))

If you have source code that's already in dot-format, the FAQ at htsoft.com goes like this:

Q: I want to convert some Bytecraft MPC source code to the HI-TECH C PIC compiler. The bit access notation has confused me. In MPC, the Convention is FILE.BIT, where the file and bit are separated by a period. Will HI-TECH C accept this notation, or is there a "slick" way to convert the source code to compile with the HI-TECH C Compiler ?

A: This notation is not accepted by our compiler - it's non-ANSI. What I'd suggest is this: do a global change (or several thereof) to convert everything that looks like FILE.BIT into FILE_BIT and then add to the program (or a header file) declarations like:

/* this line once only, of course */
#define PB(port,bit)    ((unsigned)&(port)*8+(bit))
/* as many like this as required */
static bit      FILE_BIT        @ PB(FILE,BIT);

I'm not sure if you are using symbols for the bit number, or an actual number, either way it doesn't really matter.

How easy the global changes are depends on whether you are using the dot character anywhere else, and how powerful your editor is.

The absolute variable notation (@ address) is non-ANSI too, but this is only used in declarations, not in the code itself, so it's a lot easier to port than the Bytecraft dot notation, where you have to go and change all your code instead of just your declarations.

All of these translate directly into the bit test and set instructions in the PIC and are very efficient.

Unions are another way of constructing combination Byte / Bit variables.

union status
 {
  unsigned char byte;
    struct
     {
      unsigned motor_status :1; //bit0
      unsigned error_status : 1;        //bit1
      unsigned force_sensor : 1;        //bit2
      unsigned current_sensor : 1;      //bit3
      unsigned motor_voltage : 1;       //bit4
      unsigned encoder_voltage : 1;     //bit5
      unsigned motor_on_time : 1;       //bit6
      unsigned unused : 1;              //bit7
     }bits;
 }update_status;

to load a value at byte level you can write:
 update_status.byte =  0xC0;
to access individual bits:
 update_status.bits.unused = 1;


Don B. Roadman says:

I went through this stuff a while back. The simple fact is that the compiler just doesnt have the facility to handle data as both a byte variable and as individual bits. It just lacks that capability. There are ways to do this by writing a whole lot of confusing code, but I found the following method the simplest way. Just define a global variable at an absolute address, then the bits can be defined as normal without all the hassles. Here is an example. Note that foo is the 8bit variable, and bar0, bar1...bar8 are the bits in foo.
unsigned char foo @ 0x4e;
        // Bit definitions for foo
        bit     bar7            @ (unsigned)&foo*8+7;
        bit     bar6            @ (unsigned)&foo*8+6;
        bit     bar5            @ (unsigned)&foo*8+5;
        bit     bar4            @ (unsigned)&foo*8+4;
        bit     bar3            @ (unsigned)&foo*8+3;
        bit     bar2            @ (unsigned)&foo*8+2;
        bit     bar1            @ (unsigned)&foo*8+1;
        bit     bar0            @ (unsigned)&foo*8+0;

The disadvantage of this is that the variable MUST be defined at an absolute address (in this case, I used location 4E hex). The compiler blythely does everything, but is oblivious to the fact that it has assigned a variable to a location, so Its not smart enought to check before it uses it for some other variable. Just look at the variable map and be sure to assign your variable to someplace that isnt used.

I cant find any documentation on how they assign space to variables, but so far, best I can tell, If you use the upper space you'll be ok. They seem to start at the end of the special registers and work up, but this may not be true in general...I just don't know.

I was pretty dissappointed that this limitation exists. I am aware that it isnt in the ansi standard, but neither is the above stuff that exists mainly for accessing the SFRs. I guess it would be a very difficult thing to modify the compiler to respect variables assigned to fixed locations or it would probably have been done before now. All in all, it is a good compiler, and since the light version is free, its worth taking the time to look through all the workarounds and choose the one you like the best.

Code:


file: /Techref/microchip/language/C/math/bits.htm, 6KB, , updated: 2002/11/1 18:03, local time: 2024/11/17 15:15,
TOP NEW HELP FIND: 
18.227.111.126:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://sxlist.com/techref/microchip/language/C/math/bits.htm"> PIC Microcontoller C Bit Math Method s</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

 

Welcome to sxlist.com!


Site supported by
sales, advertizing,
& kind contributors
just like you!

Please don't rip/copy
(here's why

Copies of the site on CD
are available at minimal cost.
 
Quick, Easy and CHEAP! RCL-1 RS232 Level Converter in a DB9 backshell
Ashley Roll has put together a really nice little unit here. Leave off the MAX232 and keep these handy for the few times you need true RS232!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .