AVR: Reading Inputs in AVR

Filed in AVR , MCU 1 comments

Article by: Kumail Ahmed – PAF-KIET

Hello again, last time we discussed how to install the basic software which are needed for AVR programming. We also learned how to turn an LED on-off through the controller.

The next most important step in micro-controller, in my opinion, is to learn how to take input. What’s the use of a controller if we cannot connect it to the physical world? Data inputs can be of many types including analog, timing sequence, external interrupts or digital. We would focus on taking digital inputs. This means to send either a high or a low to a specific pin and perform the required job.

Connect the circuit as shown above. If you are doing this on a breadboard connect PIN7 to VCC and PIN8 to Ground. ATMEGA8 works on 5V. The circuit would turn on the LED when the button is pressed and vice versa. The resistors R1,R2 are called ‘current-limiting’ resistors. They limit the sink and source current inside the controller. If you are interested in the maximum sink and source current see the datasheet! Now the code:

#include<avr/io.h>

#include<util/delay.h>

int main(void)

{

DDRC=(1<<PC2);  //Make PC2 an output

PORTC=(1<<PC0); //Make PC0 an input

While(1)

{

_delay_us(10);  //optional

if(bit_is_set(PINC,PINC0))    //If pin value is high

PORTC|=0×04;     //Turn on the LED

else                  //else

PORTC&=(~0×04); //turn it off

}

return 1;

}

If we want to make a PORT as an input, we write 1 to the specific PORT:

PORTC=(1<<PC0);

Just remember that we write 1 to a specific PORT if we want to make it input. This is the short story! Why we wrote 1 to the PC0 might be of interest for an engineer. See the following chart:

AVR PORTS are very much advanced compared to 8051. In 8051 we had an open-collector configuration for PORTA only and other PORTS didn’t had this. In AVR we have the option to change any PORT to a    Hi-Z state or a ‘close-collector’ (This is my term, I think you won’t find this on the internet!)

When we write 1 to PORTC we are simply making it ‘close-collector’. What we mean by this is that now a specific amount of current can be sourced thus making it an INPUT.

AVR also support Hi-Z state. Z stands for impedance. This is extremely useful when we connect many controllers along the same data bus.

I think we have many new symbols here in this program. If you have read all bitwise operators you easily understand the program. Just for information:

& ……. AND

|………OR

~……. INVERT

^………XOR(not used in this program)

The reason to use all these operators is to make you feel these operators! We will start with

if(bit_is_set(PINC,PINC0))

This line means that if PINC0 is high, perform the respective function under the ‘if condition’. Bit_is_set is a built-in function which takes in two values. The first is the port name and second is the respective port. This function also has its counterpart, bit_is_clear(PIN NAME, PIN NO). Always remember one thing, “We read from a PIN and write to a PORT”. Therefore, we always give in PIN NAME rather than PORT NAME.

Next line: PORTC|=0×04;

This line could also be written as

PORTC=PORTC|0×04; but in C we have a short-hand which I have used.

‘|’ represent a logical OR. We mostly use ‘OR’ to make something high. The Boolean algebra for OR is

A|0=A and A|1=1.  If PORTC= XXXX XXXX, ORing it with 0000 0100(0×04) would result in XXXX X1XX. This will always make the third bit high.

You might be wondering why I wrote PORTC|=0×04;

rather than simply writing PORTC=0×04;

Please understand the difference! PORTC|=0×04 would force all other bits to zero except the third bit. Remember that in the second line of the program we made the first bit of PORTC high. Writing PORTC=0×04;line would simply force the first bit to be zero and we would be able to use it as an INPUT.  ANDing and ORing are used when we want to control individual bits. I hope you understand the difference.

Coming to the last line:

PORTC&=(~0×04);

Again, you can write this as

PORTC=PORTC&(~0×04);

The Boolean Algebra for AND is A&0=0 , A&1=A.

The ‘~’ operator would cause a bit inversion. i.e. ~0×04 (0000 0100) will cause it to change to             1111 1011(0xFB). ANDing this value with PORTC will force only the third bit to be become a zero and will not affect the remaining bits. i.e. let us suppose PINC= XXXX XXXX, ANDing this with 0xFB with result in    XXXX  X0XX. No other bit is changed except the third bit.

The end result of this program is to that it will perform the following function. When we press the button it will turn on the LED. When we release it will turn the LED off.

I know this might have caused a headache for a non-C programmer! Please don’t feel irritated. Once you understand these bit-wise operators everything else is a piece of cake! Thank you for reading.

Posted by hamzaazeem   @   16 September 2009 1 comments
Tags : , , , , , ,

Share This Post

RSS Digg Twitter StumbleUpon Delicious Technorati

1 Comments

blog comments powered by Disqus
Previous Post
«
Next Post
»
EXULT designed by ZENVERSE  |  In conjunction with Reseller Hosting from the #1 Web Hosting Provider - HostNexus.