AVR programming introduction/Simplistic program

In this task we will consider the two basic stages in the AVR software development: building the code and uploading of the resulting binary to the MCU.

Before you begin
In this task, we will need the following hardware and software facilities:
 * either a simplistic device based on ATmega8 (or compatible) or one of the Arduino boards (Uno or Nano);
 * a development environment, including:
 * GCC and GNU Binutils built for the AVR target;
 * the GNU Make build automation tool;
 * AVR Libc;
 * the Avrdude image loading tool;
 * the usual system facilities, such as GNU Bash and a Text editor (GNU nano, Vim, GNU Emacs, or some other);
 * note that on Debian (and, presumably, its derivatives) it’s possible to install the AVR-specific tools listed above with a command like:

Reading the code
We will start reading the code above starting with its payload.   The  line toggles (changes to high if it was low and vice versa) the PB5 MCU output (D 13 on Arduino Uno.)   The  call results in an empty loop for the duration of about 2.718 s. That requires that the  C preprocessor macro matches the actual MCU frequency used in the circuit.   Both of the actions above are enclosed in the main loop coded as. Given that the condition in  is always true, the loop will continue indefinitely until the MCU is reset or the power is cut down.   Now, the  line above configures the PB5 MCU pin we use as an output. Otherwise, this pin will be left configured as input and the PORTB change above will result in the internal pull-up resistor being connected to and disconnected from the pin. The current through such a resistor, however, is likely to be insufficient to drive the LED connected to the pin.   The  lines begin the definition of the “main” function, defined here as returning a value of the   type (a signed integer) and accepting an indefinite number of arguments. The  line, which appears after the “endless” main loop, satisfies the formal requirement for a non-  function to return a value.  Finally, the  preprocessor directives at the top of the code request the following headers:
 * It’s the  function specifically that the run-time C environment passes control to after completing initializations.
 * Such a declaration of this function is one of the allowed by the standard.
 * The return value of 0 is defined by the standard for  as the code for successful completion.
 * The run-time environment actually implemented by GCC and AVR Libc for the AVR target does not pass any meaningful arguments to  and does not interpret the value returned in any way.
 * includes the definitions for the,  ,  ,   macros, as used in the code;
 * includes the definitions for the,  ,  ,   macros, as used in the code;


 * includes both the declaration and definition of the (inline)  function also used in this example.
 * includes both the declaration and definition of the (inline)  function also used in this example.

 

Building
  Create the  and   files as shown above. </li> <li> Build the example with : make <samp style="white-space: pre-wrap;" >avr-gcc -O2 -Wall -std=gnu11 -mmcu=atmega8 -DF_CPU=7372800  ../blink.c   -o blink avr-objcopy -O ihex blink blink.hex <dl> <dt>NB</dt> <dd> When using an MCU other than ATmega8, or the clock frequency other than 7.3728 MHz, the  and   build parameters are to be set accordingly. In particular, for the Arduino Uno board (as of revision 3), which uses an ATmega328P MCU and a 16 MHz crystal, the Make invocation could be like: make MCU=atmega328p F_CPU=16000000 </dd> </dl> </li> <li> Check for no errors in the output, and that the  file is created, containing the image to upload in the Intel hex format. </li> </ol>

Uploading and observing operation
<ol> <li> Connect the device to the development system’s USB port. Check that the respective device file is created – either  or similar. </li> <li> Check whether the Optiboot bootloader is reachable by downloading the current MCU’s flash memory image into an Intel hex format file, like: avrdude -P /dev/ttyUSB1 -c arduino -b 115200 -p atmega8 \ -U flash:r:"$(mktemp --suffix=.hex -- ./XXXX)":i <samp style="white-space: pre-wrap;" > avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.00s avrdude: Device signature = 0x1e9307 avrdude: reading flash memory: Reading | ################################################## | 100% 1.02s avrdude: writing output file "96TF.hex" avrdude: safemode: Fuses OK avrdude done. Thank you.
 * NB
 * In order to start Optiboot, Avrdude tries to reset the MCU by toggling the RTS and DTR lines of the interface. If these lines are not connected to the  MCU pin (on some USB-to-serial adapters these lines aren’t wired at all), the MCU has to be reset manually as follows:
 * type in the command above but do not start it with ⏎ Enter yet;
 * press the reset button on the device;
 * release the button and immediately press ⏎ Enter to start the command.

</li> <li> Upload the image we got to the MCU flash memory, like: avrdude -P /dev/ttyUSB1 -c arduino -b 115200 \ -p atmega8 -U flash:w:blink.hex:i <samp style="white-space: pre-wrap;" > avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.00s avrdude: Device signature = 0x1e9307 avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "blink.hex" avrdude: writing flash (90 bytes): Writing | ################################################## | 100% 0.02s avrdude: 90 bytes of flash written avrdude: verifying flash memory against blink.hex: avrdude: load data flash data from input file blink.hex: avrdude: input file blink.hex contains 90 bytes avrdude: reading on-chip flash data: Reading | ################################################## | 100% 0.01s avrdude: verifying ... avrdude: 90 bytes of flash verified avrdude: safemode: Fuses OK avrdude done. Thank you.
 * NB
 * The note on starting the bootloader above remains valid in this case just as well.

</li> <li> Check that the operation of the system is as expected by estimating the blinking period and comparing it to the one given in the code. </li> </ol>

Research
<ol> <li> Change the argument to  in the code and observe how the behavior of the system changes. Also, could you name where the orignial number possibly comes from? Note that you will need to repeat the building and uploading stages after each change. </li> </ol>