Programming in C – Tips for Embedded Development.

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=0×10; (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′.

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.

164 thoughts on “Programming in C – Tips for Embedded Development.”

Nice introduction to embedded programming and registers! Maybe for beginners a little more detailed introduction to binary system and logical operations would be needed, otherwise very simple and clear.

Yes,a little more detailed introduction to binary system and logical operations would be needed. But I don’t wanted to go deep in C programming as I assumed user know C, so I left them. But I think I would make a new page for it.
Thanks for your kind suggestion!

By ed
-
February 14, 2015 2:08 pm

I think it is great as it is. It is always tedious if one wants to go a bit deeper that many tutorials first hash up an introduction to the binary system again. I mean…. u are also not first teaching them English

Good introduction, however it would be nice to point to IDEs like Micro C Pro for AVR,Micro basic pro for avr and bascom too. I found esier to deal with libraries in Micro C pro for AVR, but you know that depends on the programmer.

Thats a great see through for beginners. This shows the strength of Embedded C programming.
And great work Mr. Avinash Gupta. Keep coming with such more stuffs in future.
Good Luck for your futuristic scope.

You are are Great Avinash.
I being from commerce line is able to understand everything. You have made it simple for me.
Thanks a lot and please keep this up.
People like we are dependent on people like you.

dude … tuts are awesome ..especially this one
evrything is simple and sweet …continue with the same work and forgot to mention …learning a lot from all this stuff
love your work
cheers,
your student in kind a way
wishing you a happy new year in advance

I’ve been trying to learn i2c, SMBus, 2-wire, whatever you want to call it and have confronted code that has little documentation. TWSR. TWDR, what were they? I thought it might a secret club

Now, Christmas Eve, you’ve just given a much cherished present to a stranger. THANK YOU! I look forward to diving back into i2c tomorrow with a fighting chance of getting it to work. I look forward to enjoying your site in the new year.

hi and hello avinash sir ,ur informations are very useful for me thank u very much for ur hard work ,i am a begginer for this embedded world ,i have pic, atmel proggramers but i dnt know how to start my embedded studies and proggram the microcontrollers but i know electronic hardware working pcb designing etc plz guide me to shine in this field from where i should be started ,

Its Really nice job since last 1yr I was looking for this stuff. It is having much more information for bit manipulation and it is required for every program. Even there are alternative to this bus mostly preferred and standard one is what you have explained.
Its our tradition to thanks, one who gives us knowledge.
so accept my nod(Pranaam)……….Guruji……
where could get stuff for function pointer?

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..

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 ……..

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.

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.:)

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..:)

sir pls could you provide me with the code of avr microcontrollers used for rotating the rod (via dc motors) in one direction for 30 seconds and then again rotating it in opposite direction for 30 seconds
thank you

i would love to do that but am a beginner having no idea about programming in past i had referred some books and asked many faculties about my problems regarding the same but everything seems fruitless now..

By Avinash
-
November 29, 2012 9:18 am

@Priya,

So if you are in this field then I better suggest you learn programming as it will come to your use in the future. So what is your experience level in C? How much do you know?

sir i have read your tutorials on avr they are really helpful though it took some time to understand each and everything but finally i was able to understand most of it and it would have been a more enriching experience if the pdf versions for all the tutorials are available anyways i enjoyed the parts i had read thank you for replying and all the wonderful tutorials

I tried to make PDFs in the beginning but the problem was that web article were constantly updated with new information and corrections made. And PDFs soon became obsolete. Thats why I dropped the idea.

How much experience you have working with AVRs? Do you have some setup to do the experiment?

By priya dixit
-
November 30, 2012 7:02 pm

thank you sir
these links were helpful…
i have all the basic knowledge of working with AVRs given in your tutorials..and had bought usb avr programmer, avr development board and atmega 16 microcontroller
i and one of my friend( pursuing mechanical engineering) are trying to develop a book scanner for which i needed
the programming code for rotating the rod (as mentioned earlier) the whole setup of the book scanner is as follows-
we have 2 rods at right angle to each other(say one along the x axis and another one along the y axis) the rod along the y axis rotates 60 degree clockwise(cw) and anticlockwise(acw) direction with time delay of 10 seconds as the rod rotates cw and acw the glass panel(which is moulded in the shape of an open book) attached to the rod along the x axis moves up and down….now moving the rod in 60 degree cw for 10 seconds then moving it acw is the 1st mechanism we need to build…nextly we need some automatic setup to turn the pages of the books which are to be scanned (since as the glass panel moves up there is a provision to turn the pages manually or through some automatic setup so that the further pages can be scanned)this automatic setup for turning the pages is the 2nd mechanism we need to build..third we need an speed regulator to make the rod move slow and fast as and when needed..
i request you if you could help us out in this..thank you once again and sorry for replying so late..

hii,
i am sadasiba, i am highly interested in embedded c but i am not so strong in coding
now i am learning embedded c, i have a question that no one is getting able to answer it or some of did not want to answer it, whom i asked yet
and i could not leave that question out of my mind and the question is”why there is no match between hex code generated after compiling and the previous original c code,if i am taking the ASCII equivalent of both charter used in c code and hex code generated” .is there any fact regarding compiler designing?.please kindly give a reply i am waiting for your reply.

Your tutorial turned out to be silver lining for me when I was in a confused state. I was browsing a lot to clear my doubts. I don’t know how I landed at your site but it cleared tons of my doubts and made me regain my lost interest in embedded systems. Thanks a ton for bringing up such wonderful tutorials.

Thanks a lot,Excellent tutorial for setting, clearing a bit in register,got cleared why left Shift is used for setting a bit and why we can’t directly copy the value to register.
you can write a Ebook on AVR Programming in C.