To write to a pin, we have to set that pin as an output pin. Then only we can write digital 1 or 0 to that pin. Suppose we need to set the value of Pin 5 in Port B to digital 1. This is how we do it.
We need to import this header to have all the necessary macros
#include <avr/io.h>
Now we have to set the correct pin as an output pin. Whether a pin of a port is set to input or output is decided by the values in "Data Direction Register" of the particular port. The data direction register for the PortB is DDRB. So, to set the pin 5 of PortB as output, we have to set the corresponding pin in DDRB register to logic high. We do that in the following way.
DDRB |= _BV(DDB5);
DDB5 is a macro which gives a byte where the bit that corresponds to PortB Pin5 is set to 1 while the other bits are 0. So, by making the above operation, we are setting the corresponding bit in DDRB register to 1 while making all the other bits to 0. It notify the system that PortB Pin5 is now an output pin.
Tt's time to set the desired output value to the PortB Pin5. If we want to set it to
1, here's how we do it.
PORTB |= _BV(PORTB5);
PORTB5 macro gives us a byte where the bit corresponds to Pin5 is set to 1 while all the other bits are 0. Therefore, the above operation sets the correct bit of the PORTB register to 1 making it's output value to 1.
Similarly, we can set the output value of the PortB Pin5 to 0 by doing the following operation.
PORTB &= ~_BV(PORTB5);
Using the above techniques, we write a LED blink application for Arduino as follows.
We can have a Makefile with the following content to compile and write the above C program into an Arduino Uno board.
References:
[1] https://balau82.wordpress.com/2011/03/29/programming-arduino-uno-in-pure-c/
[2] https://iamsuhasm.wordpress.com/tutsproj/avr-gcc-tutorial/
We need to import this header to have all the necessary macros
#include <avr/io.h>
Now we have to set the correct pin as an output pin. Whether a pin of a port is set to input or output is decided by the values in "Data Direction Register" of the particular port. The data direction register for the PortB is DDRB. So, to set the pin 5 of PortB as output, we have to set the corresponding pin in DDRB register to logic high. We do that in the following way.
DDRB |= _BV(DDB5);
DDB5 is a macro which gives a byte where the bit that corresponds to PortB Pin5 is set to 1 while the other bits are 0. So, by making the above operation, we are setting the corresponding bit in DDRB register to 1 while making all the other bits to 0. It notify the system that PortB Pin5 is now an output pin.
Tt's time to set the desired output value to the PortB Pin5. If we want to set it to
1, here's how we do it.
PORTB |= _BV(PORTB5);
PORTB5 macro gives us a byte where the bit corresponds to Pin5 is set to 1 while all the other bits are 0. Therefore, the above operation sets the correct bit of the PORTB register to 1 making it's output value to 1.
Similarly, we can set the output value of the PortB Pin5 to 0 by doing the following operation.
PORTB &= ~_BV(PORTB5);
Using the above techniques, we write a LED blink application for Arduino as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <avr/io.h> #include <util/delay.h> #define BLINK_DELAY_MS 1000 int main (void) { /* set pin 5 of PORTB for output*/ DDRB |= _BV(DDB5); while(1) { /* set pin 5 high to turn led on */ PORTB |= _BV(PORTB5); _delay_ms(BLINK_DELAY_MS); /* set pin 5 low to turn led off */ PORTB &= ~_BV(PORTB5); _delay_ms(BLINK_DELAY_MS); } } |
We can have a Makefile with the following content to compile and write the above C program into an Arduino Uno board.
1 2 3 4 5 | all: avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -c -o blink.o blink.c avr-gcc -mmcu=atmega328p blink.o -o blink avr-objcopy -O ihex -R .eeprom blink blink.hex avrdude -F -V -c arduino -p ATMEGA328P -P /dev/ttyACM0 -b 115200 -U flash:w:blink.hex |
References:
[1] https://balau82.wordpress.com/2011/03/29/programming-arduino-uno-in-pure-c/
[2] https://iamsuhasm.wordpress.com/tutsproj/avr-gcc-tutorial/