MX018 - Simple Masking Technique

Forum to discuss articles which have been published in Matrix Multimedia's article zone. If you have any comments or questions regarding the articles please post them here.

Moderators: Benj, Mods

Post Reply
User avatar
DavidA
Matrix Staff
Posts: 1076
Joined: Fri Apr 23, 2010 2:18 pm
Location: Matrix Multimedia Ltd
Has thanked: 58 times
Been thanked: 258 times
Contact:

MX018 - Simple Masking Technique

Post by DavidA »

Article: http://www.matrixmultimedia.com/resourc ... php?id=382

If you have any questions for the author or comments on the article, please post them below.

medelec35
Matrix Staff
Posts: 9520
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2585 times
Been thanked: 3815 times
Contact:

Re: MX018 - Simple Masking Technique

Post by medelec35 »

Hi David.
Thanks for the great article!

Would it be possible (if people would find it useful?) to expand this article to cover other masking, Checking and toggling bits and bytes.
E.g to set bit 3 within a variable place in a calculation box:

Code: Select all

variable = Variable |(1<<3) 
which is same as

Code: Select all

variable = Variable |8 

You can replace | with OR

To toggle a bit 3 within a Variable place in a calculation box:

Code: Select all

Variable = Variable ^(1<<3) 
which is same as

Code: Select all

variable = Variable ^8 

You can replace ^ with XOR

To check for bit 2 within a Variable place in a decision branch:

Code: Select all

variable = &(1<<3)
which is same as

Code: Select all

 variable & 8 

You can replace & with AND

To Clear a register within a C code box
E.g If I want to clear bit 7 of option_reg to enable weak pull -ups

Code: Select all

clear_bit(option_reg , 7);
+ loads more useful bytes or bits manipulation I have seen scattered around.
Then it could be used as a reference sheet without searching the forum for each operation, all can be found in one place.
Martin

Spanish_dude
Posts: 594
Joined: Thu Sep 17, 2009 7:52 am
Location: Belgium
Has thanked: 63 times
Been thanked: 102 times
Contact:

Re: MX018 - Simple Masking Technique

Post by Spanish_dude »

Hi,

A bit more info for those who would like to know how the clear_bit works:

The clear_bit macro can be easily made by doing :

Code: Select all

#define clear_bit(var, bit) (var & ~(1 << bit))
If bit is set to (let's say) 4, the value of "1 << bit" will be 0001 0000 or 16(dec)
Using the ~ sign will invert the value so instead of having a value of 0001 0000 (or 16 dec) you'll have 1110 1111 (or 239 dec)
Next is AND'ing the value with var.

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

So if var = 1011 1010
The result would be
1011 1010
1110 1111 &
-------------
1010 1010

If you'd like to use this in a calculation box instead of a C code box you'll need to write:

Code: Select all

var = var & ~(1 << bit)
Like Martin wrote in his first code-box you can set bits by OR'ing it with a specific value.

BR,

Nicolas L. F.

brandonb
Posts: 438
Joined: Mon Aug 29, 2011 12:26 am
Location: arizona
Has thanked: 175 times
Been thanked: 173 times
Contact:

Re: MX018 - Simple Masking Technique

Post by brandonb »

i noticed using 8 bit variables direct calculation masking result can be used to get 24 and 32bit numbers, but on hardware it doesnt work that way, <<8 will work on hardware great....however <<16 will not, i had to take the byte variable and send it to a buffer 16 bit uint variable and calculate off that..... <<24 had the same result but had to create a 32bit ulong variable to use with the <<24 shift,.....am i overlooking something here? really i dont understand why its possible to <<8 with a byte variable?

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: MX018 - Simple Masking Technique

Post by Benj »

Hello Brandon,

I think the compiler may be doing some optimising here and assuming you do not want a 32-bit result when you actually do.

In C code you would tell the compiler to use a 32-bit memory by doing something like this.

unsigned long var32;
unsigned int var16;
var32 = (unsigned long) var16 << 16;

Note that there may be a good reason the compiler is forcing you not to do what you are trying to do. Maybe because the output assembler is bloated and inefficient.

The max file length issues in v4 with the FAT component were related to this very problem. We overcame the problem in v5 by using a structure to convert between 8, 16 and 32 bit values by accessing the correct location directly rather then using bit shifting.

Post Reply