You are on page 1of 3

Basics of AVR 'C'

Let us look at the basics of 'C' for programming AVR Micrcontrollers in this tutorial. Simple stuff like
setting and clearing bits is important to any project you do.
It is often required to set, clear, toggle and check bit status of a Register without affecting any other
bits. Also it is important to do in a way that is compiler independent and code can be ported without
modifications.

Consider the Data Direction Register (DDRD) shown below. As you know we need to set or clear bits
in order to make the corresponding pin output or input respectively.

7 6 5 4 3 2 1 0
DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0
Let us also say that there is a switch connected to PORTD2 and LED connected to PORTD4 as
shown.

Now what we need to accomplish is this:

7 6 5 4 3 2 1 0
DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0
0 0 0 1 0 0 0 0
Contents
• 1 Setting a bit
• 2 Clearing a bit
• 3 Checking a bit
• 4 Toggling a bit
• 5 Macros

Setting a bit
Let's set the bit 4 to make the port pin as output. There is no direct bit set or clear instruction in 'C'
that we can call to do this. Hence lets start with the simple binary number: $$0b00000001$$ Now lets
left shift it 4 times to get $$0b00010000$$ Now if we OR this result with DDRD register which has
default value of 0b00000000 we get:
\begin{array}{r} &0b00000000\\ &0b00010000\\ \hline &0b00010000 \end{array}

It is important to note that even if the value of DDRD was different, only bit 4 would have been set
with the operation above without affecting other bits. Now let us write that in the hex notation in a C
Statement.
DDRD = DDRD | (1 << 4);

we can also concatenate the OR operation and write as:


DDRD | = (1 << 4);

Taking this a little further, you might want to define the number 4 as a constant, so that if LED is
connected to some other pin, you may not want to change in all the places you've used it. Like so,
#define LED 4
DDRD | = (1 << LED);

Clearing a bit
Now let us go ahead and clear the bit-2 and also assume this time that the DDRD value is
0b01010101 we need to obtain 0b01010001

Again Lets start with $$0b00000001$$ Left shift 2 times to get $$0b00000100$$ Let's invert the
result to get $$0b11111011$$

Now let's take this result and & it with the DDRD value \begin{array}{r} &0b01010101\\
&0b11111011\\ \hline &0b01010001 \end{array}

Let's write a this in 'C' statements:


#define mySwitch 2
DDRD &= ~(1<<mySwitch);

Checking a bit
Lots of times during programming, you will want check if a bit is set or clear. For example to check if
the timer flag is set or let's say in our example if the switch is pressed or released. Often this is
accomplished by checking status of particular bit in a given register.

Lets say we want to check the status of 4th bit of PIND register. Then the status can be obtained by
status = (PIND & (1<<mySwitch) ! = 0);

Toggling a bit
If we need to toggle the LED connected to PORTD, bit-4 as with our example it can be accomplished
by XOR operation as shown. Assuming the intial value of PORTD register is 0b00000000

As before let's start with $$0b00000001$$

Let's left shift by 4 times to get $$0b00010000$$

Now lets XOR the value obtained with the PORTD value. \begin{array}{r} &0b00000000\\
&0b00010000\\ \hline &0b00010000 \end{array}

It can be summed up as
#define LED 4
PORTD ^= (1 << LED);
So every time the statement is executed the LED changes it state.

Macros
We have defined all of these operations in stdutils.h file. Which you can include and use these and
other similar functions.

I have included a snippet below, you may download the complete file.
#define util_GetBitMask(bit) (1<<(bit))
#define util_BitSet(x,bit) ((x) |= util_GetBitMask(bit))
#define util_BitClear(x,bit) ((x) &= ~util_GetBitMask(bit))
#define util_BitToggle(x,bit) ((x) ^= util_GetBitMask(bit))
#define util_UpdateBit(x,bit,val) ((val)? util_BitSet(x,bit): util_BitClear(x,bit))

#define util_GetBitStatus(x,bit) (((x)&(util_GetBitMask(bit)))!=0u)


#define util_IsBitSet(x,bit) (((x)&(util_GetBitMask(bit)))!=0u)
#define util_IsBitCleared(x,bit) (((x)&(util_GetBitMask(bit)))==0u)

#define util_AreAllBitsSet(x,BitMask) (((x)&(BitMask))==BitMask)


#define util_AreAnyBitsSet(x,BitMask) (((x)&(BitMask))!=0x00u)

Please enable JavaScript to view the comments powered by Disqus.

You might also like