Hello World ATMega32M1¶
Now that you’ve installed the AVR toolchain, let’s compile and upload our first program.
Later on, this compilation and uploading process will be made much less painful using tools such as Make; for most subsystems, this entire process can be accomplished using a single command.
Step 1¶
Create a new directory called hello_32m1
as follows:
$ mkdir hello_32m1
This will be the root directory of the project. Now enter this directory by running cd hello_32m1
and run the following command:
$ git init
This will initialize Git for this root directory and all sub-directories. You’ll learn more about what this command is doing soon.
Step 2¶
Create a new file called hello_world.c
, and copy the following contents into
the new file:
#include <uart/log.h>
int main() {
init_uart();
print("Hello ATMega32M1!\n");
return 0;
}
The first line, init_uart();
, initializes the UART circuitry on the 32M1. UART
stands for Universal Asynchronous Receiver-Transmitter. This allows the 32M1 to
communicate with external peripherals using a serial protocol.
The second line, print("Hello ATMega32M1!\n");
, send the string “Hello
ATMega32M1” to the UART system to be written to serial output.
The third line returns from the main
function.
Run $ git status
and read the output carefully. Notice that Git has noticed
the new file you’ve created.
Step 3¶
Download the lib-common
library by running the following command in the root
directory:
$ git submodule add https://github.com/HeronMkII/lib-common
Run ls
in the root directory. Notice a new directory has been added, called
lib-common
. Explore the contents of this directory by running cd lib-common
(do not modify anything).
This is a library which contains many code components common to all subsystems, including SPI, UART and CAN functionality.
Before the library is used, it must be built. To do this, make sure you are in
the lib-common
directory and run
$ make
Inspect the lib
folder in the lib-common
directory. You should notice many
files ending in .a
. These are the library files we just generated.
Step 4¶
We’re now ready to compile our program. Make sure you’re in the root directory, and run
$ avr-gcc -std=gnu99 -Wall -mmcu=atmega32m1 -c hello_world.c -I ./lib-common/include
This will create a new hello_world.o
object file. We must now link this
object file to create an executable. To do this, run
$ avr-gcc -std=gnu99 -Wall -mmcu=atmega32m1 -o hello_world.elf hello_world.o -L ./lib-common/lib -l uart
This will create a new file called hello_world.elf
; this is a complete
executable file. To upload it onto the 32M1, however, we must format it
in the Intel Hex format. To do this, run
$ avr-objcopy -j .text -j .data -O ihex hello_world.elf hello_world.hex
This creates the final executable which we will upload to the 32M1, called
hello_world.hex
.
Step 5¶
We’re now ready to upload our hello world executable onto a board.
To do this, you need to connect a 32M1 on a board to your computer using a programmer. Find a Polulu programmer in the lab, and connect it to an open USB port on your computer.
We will use avrdude
to upload our hello_world.hex
onto the 32M1. To do this,
we need to tell avrdude
which USB port the programmer is connected to. To find
this out, run
$ ls /dev/tty.usb*
This lists all USB devices connected to your computer.
The USB device corresponding to the programmer is almost always the device with
the lowest id. For example, if the command above returns
/dev/tty.usbmodem00100561 /dev/tty.usbmodem00100563
, the USB port
corresponding to the programmer is /dev/tty.usbmodem00100561
. Make sure to
remember this port.
Connect power to the VCC pin on the board, and ground the GND pin. Set the voltage to 3.3 volts. Connect the programmer to the programmer port on the board. Check that the light on the programmer is green; this means the board is being powered correctly. If the board has insufficient power, the programmer will not upload to the board, because this has the potential to corrupt the MCU’s memory.
Now run the following command, where <port>
is replaced with the USB port you
found above.
$ avrdude -p 32m1 -c stk500 -P <port> -U flash:w:./hello_world.hex
This should upload your program onto the 32M1! If this command runs successfully, congratulations! You’ve just compiled and uploaded your first program onto the 32M1!
Step 6¶
To verify that the program is running correctly, first connect the female RX pin on the programmer via a male to male wire to the MOSI pin on the board. This is wire along which the serial communication between the 32M1 and your computer will occur.
Now, open CoolTerm. Click the Options icon on the top of the new window. The default options do not need to be changed. Click the Port dropdown menu and select the port you identified above. Click OK on the bottom right. Click the Connect icon. Now, any UART output from the 32M1 should appear on your screen.
Reset the board by pressing the reset button. If all goes well, you should see the string “Hello world!” appear on your screen!
This process was very time consuming and error prone. We’ll see how we can simplify this process in the future using tools such as Make.