Here I will highlight some features of C language commonly used in 8 bit embedded platforms like 8051, AVR and PICs. While programming microcontrollers in C most of the time we have to deal with registers. Most common tasks are setting and clearing bits in a register and check whether a bit is 0 or 1 in a given register. So here I will give detail on those topics, it will help you if you are new to embedded programming in C and if you get confused when you see some codes.
A Register
A register is simply a collection of some bits (mostly 8 bits in case of 8bit MCUs). Either each different bit in a register has some purpose or the register as a whole holds a value. Registers serves as connection between a CPU and a Peripheral device (like ADC or TIMER). By modifying the register the CPU is actually instructing the PERIPHERAL to do something or it is configuring it in some way. And by reading a register, the CPU can know the state of peripheral or read associated data.
![]() |
Fig.: CPU writing to Peripheral Register |
![]() |
Fig.: CPU Reading from Peripheral Register |
Binary Numbers in C
When you write a=110; in C it means you are setting the value of variable"a" to "one hundred and ten" (in decimal). Many time in embedded programming we are not interested in the value of a variable but the state of each bits in the variable. Like when you want to set the bits of a register (MYREG) to a bit pattern like 10010111 (binary). Then you cannot write MYREG=10010111. Because compiler will interpret 10010111 as decimal. To specify a binary number in C program you have to prefix it with 0b (zero followed by b). So if you write
MYREG=0b10010111;
it assigns the bit pattern 10010111 to the bits of Register MYREG.
HEX Numbers in C
In same way if you prefix a number by 0x (a zero followed by x) then compiler interpret it like a HEX number. So
MYREG=0x10; (10 in HEX is 16 in decimal)
MYREG=0xFF;(Set all bits to 11111111 or decimal 255)
Setting a BIT in Register
Here our aim is to set (set to logical 1) any given bit (say bit 5) of a given register (say MYREG). The syntax is
MYREG=MYREG | 0b00100000;
The above code will SET bit 5 to 1 leaving all other bits unchanged. What the above code does is that it ORs each Bit of MYREG with each bit of 0b00100000 and store the value back in MYREG. If you know how logical OR works then you will get it.
In short you can write the same code as
MYREG|=0b00100000;
Now lets come to practical usage. In practice each bit has got a name according to its work/function. Say our BIT (the 5th bit) has got name ENABLE, and what it does is clear by its name,when we set it to 1 it enables the peripheral and when cleared (0) it disables it. So the right way to set it is.
MYREG|=(1<<ENABLE);
The << is called left shift operator. It shifts the bits of LHS variable left by the amount on its RHS variable. If you write
b=1<<3;
then, 1 whose binary value is 00000001 is shifted 3 places to left which results in 00001000
So if ENABLE is defined as 5 (as enable is 5th bit) then
MYREG|=(1<<ENABLE);
will result in
MYREG|=(1<<5);
which again result in
MYREG|=(0b00100000);
Now a beginner would ask "What's the Advantage ?". And once you know it you would realize that advantage is immense!
- Readability of code: MYREG|=(1<<ENABLE); gives a clue that we are enabling the peripheral while MYREG|=0b00100000; does not give any clue what it is doing, we have to go to data sheet and find out which bit actually ENABLEs the peripheral. While ENABLE=5 is already defined in header files by the developer of compiler by carefully studying the datasheets of device.
- Easier Portability: Suppose you use this code many times in your program (and your program is reasonably large and uses other register also) and you now want the same code to run on some other MCU model. The new MCU is of similar family but has slightly different bit scheme, say ENABLE is bit 2 instead of bit 5. Then you have to find all occurrence of MYREG|=(0b00100000); and change that to MYREG|=(0b00000100); But if you have used the other method then you simply need to inform the compiler (by its setting options) that you are going to use the other MCU and compiler will automatically get the definitions for the new device. And in this definition ENABLE=2 will already be defined by the compiler developer. So it will be lot easier.
Clearing a BIT in Register
For clearing a bit logical AND(symbol &) operator is used in place of logical OR (symbol |). The syntax is as follows
MYREG&=~(1<<ENABLE);
![]() |
Fig.: How to clear (0) a bit in C language. |
This will clear (i.e. set to value 0) a given bit (identified by name ENABLE) in a register called MYREG. This operation will not affect any other bits of register except ENABLE.
Let us see how it works with the help of following diagram.
Fig.: "Clearing a BIT" how it works? |
So now you know how you can selectively clear any bit in any given register. If you want to clear more than one bit at a time you can write like this
//This will clear bits ENABLE,FAST_MODE and BUSY, leaving all other bits untouched MYREG&=(~((1<<ENABLE)|(1<<FAST_MODE)|(1<<BUSY)));
Similarly the syntax for setting(set to 1) multiple bits at a time is as follows
//This will set bits ENABLE,FAST_MODE and BUSY, leaving all other bits untouched MYREG|=((1<<ENABLE)|(1<<FAST_MODE)|(1<<BUSY));
Testing The Status of a Bit.
Till now we were modifying the registers either setting or clearing bits. Now we will learn how can be know that a specific bit is 0 or 1. To Know if a bit is 0 or 1 we AND it with a AND MASK. Suppose if we want to check bit 5 of a register MYREG then the AND MASK would be 0b00100000. If we AND this value with the current value of MYREG then result will be non-zero only if the 5th bit in MYREG is '1' else the result will be '0'.
The syntax would be like this.
if(MYREG & (1<<ENABLE))
{
//ENABLE is '1' in MYREG
...
}
else
{
//ENABLE is '0' in MYREG
}
So now you know the basic operation on bits, they are widely used in firmware programming and will help you understand other codes on my web site. And Please don't forget to post your comment regarding any doubts, or reporting errors in the above article, or simply to tell how you liked the stuff.
By
Avinash Gupta
me@avinashgupta.com





GREAT WORK!!! THAT WAS SO SIMPLE AND CLEAR! REALLY HELPFUL!
THANK YOU AVINASH.
Thanks Avinash.
I very like about your article that make beginner like me understand the basic.
Excellent stuff from you. Great work!!!! Concepts are crystal clear
Excellent for a beginner…cant’ be better.
Excellent!!! Just thanks! =)
Very helpful tutorial. Concept is clear to clear and set a specific bit. How can toggle a specific bit?
@Shoeb You can use xor operation to toggle a bit.
GREAT GREAT GREAT!!!!
Awesome tutorials…Hats off to you Gupta Ji…
Awesome Tutorials….!!
we were looking for this for so long and we finally get a detailed sensible level explanation..!
Please introduce some keywords so that people find it easily on the google…!!
we had much trouble..
It’s really simple and good and very useful for beginners
Lucid explanation especially regarding setting and resetting of bits. Such explanation cannot be found in books and the reason given was very good
hi..,
Avinash sir,
ur tutorial increases curiosity to learn mcu programming.
NICE WORK..:D
SIR..
In b/w your tutorial you said DATA SHEET of a mcu…from data sheet what all the information that we need to gather for better programming mcu..??
Thank you sir… it’s very help me…
Really thanks for your good explanation of this part. i need some more information after this can you do?
great stuff…very clear and straight explanation….i really loved the last part of blog( testing status of bit)…..keep going..
hi Avinash..
i have no words to say about this article..no one can be explain like this..hats of to you..am very proud to be say this..keep it up
good…. akhirnya aku tahu setelah rasa penasaran yang panjang…. thanks
great work…
z really helpful for a begginer..
oh yea indeed… Dis site is helpful
:p
ya i agree wid Amrit ……its cool n gud…
btw amrit i didnt know dat u wer a geek n dats supercool
it matches wid ur image
ya i agree wid amrit too … its cool n good…
btw amrit i didnt know dat u are a geek n dats supercool
superb dude
THE DATA IS TOO GOOD BUT
@SUBHRA AMRIT IS A BEGINNER BUT I AM COOL N A PRO IN ELECTRONICS..
THANKS TO EXTREME ELECTRONICS ITS SUPERCOOL…
wow…
nice i learnt good from it.thanks buddy
It is very good and helpful for beginners like me. Thanks a lot!!
very very good tutorial—thx lot–
Thank u sir,
Way u have given it’s very interactive and making interest to learn..
Sir its a request kindly suggest how to read the datasheet while coding for microcontroller as software engineer what are the things we need to take care because sir if we go through the entire datasheet it is very very confusing sir please suggest …..wating for ur reply sir ……..
With regards
rakesh Kumar
Just download the full datasheet from the manufacturer. Keep it for future reference. Whenever you feel stuck, just search for what you are trying to do in the datasheet. Most of the times it would be given clearly in steps.
very nice
dat was really nice of u 2 hav explained d basic stuff so perfectly, u get it fixed in ur heads in d second reading itself.
Excellent stuff.
awesome…………
Great, this stuff help me in my project .
Thank lots
great for a beginner…….
keep it up…..
printf(“really helpful ,like it “);
THANKS…..
Thanks for your good explanation.
REally nice….thanks a lot
pure awesomeness !
awesome…
Super – your skills of explaining things are excellent. Maybe you will try to write a book. It’s really amazingly simple and easy-to-understand explanation. Thank you very much.
Andrzej,
Thanks,_it’s_easy_to_understand.
Can_you_give_me_tips_on_atmega64_register
(c_programming)
Thanks for your simple and lucid explaination about the C programming.Very easy for the beginner like me to understand.but one request from my side.can u please give some more guidelines about the C language which will enable person like me to write codes independently for any project made by me.I mean some more basic things that you would like to add regarding hardware coding.please sir.
Thanks.:)
Helped me a lot in understanding the basics of avr c programming.
fentastic work….
grt wrk…
Nicely explained the basics of registers…..!!
kudos ..
Thank you Avinash for the great intro article…i am a BEGINNER,i really need anyone who knows what a good pratical tutorila for Embedded C beginner??or any resources where you can learn industrial Embedded C??Thank you Friends..:)
thank you very much, it’s very clear and understable,.
Very much helped and cleared doubts…
a real awesome work done.
thanks a lot.
A very well-illustrated article.
It was easy for me, a novice to understand.
Maybe if you would provide references for your statements and further readings, that could make the tutorial more effective.
Realy, it was a very helpful tutorial.
Thanks a lot