Developing in C for the ATmega328: Using the Standard C Framework
Where I illustrate developing code for the ATmega328P using the new Standard C framework.
Sources
- Github: Programming the Arduino Uno in C
- Microchip AVR ATmega328 Go to this page for the datasheet, you will need it.
- Definitive UNO pinout
- avr-libc Standard AVR C Library
Introduction
The Github repository referenced above is a new Standard C framework which mimics a subset of the Arduino framework. [Note: Standard C refers to using a standardized version of C, in this case, avr-gcc (ANSI C) as compared to Arduino C++, which is a combination of C, C++ and Arduino classes and templates. Many universities have an expectation of their students to understand C in the context of ANSI C.] The intent of the repository is to provide the capability for someone to use Standard C in programming an Arduino Uno (or similar type of microcontroller.)
The differences between using the Arduino Framework and this (AVR_C) framework are:
- The AVR_C framework is standard C compliant. It doesn’t use C++ or unique Arduino code, which means you are learning C and not a variant of C/C++.
- The code is much smaller which allows you to do more in the small memory configurations of the ATtiny microcontrollers.
- In some situations such as serial printing, AVR_C is far more simple. The AVR_C approach uses the Standard C functions of puts(), getchar() and printf() as compared to the laborious Serial.print() classes.
Install git
The best way to use this repository (or any Github repository) is to install git and add the repository by cloning. This allows you to update it easily when the repository is updated.
Linux (and Windows Subsystem for Linux)
For Linux systems, git is probably already installed. To test that:
git --version
If you don’t get a message showing git and its version, it isn’t installed. To install use:
sudo apt install git
Once installed, perform the git –version command in the command line.
macOS
For macOS systems, git probably won’t be installed. To test that:
git --version
If you don’t get a message showing git and its version, it isn’t installed. To install use: (*Note: If you don’t have homebrew already installed, see this )
brew install git
Once installed, perform the git –version command in the command line.
Windows
Windows doesn’t have a standardized Unix/Linux environment, unless you’ve installed WSL. In this case, we’ll install Git for Windows. Click on Download and save the file to your Downloads directory. Install Git for Windows by double-clicking on the downloaded file. It will ask a series of questions and for now go with the defaults.
Once installed, go to the Windows search bar and enter git , which will start git in the command line. Enter:
git --version
to confirm git was installed.
Use git
# go to folder where you want your github repositories to be, i.e; Documents/github.
# I'll start by making a repository folder
mkdir github
cd github
# go to the repository site as in github.com/lkoepsel/AVR_C
# click on the green Code button and copy either the HTTPS link or SSH link
git clone git@github.com:lkoepsel/AVR_C.git
cd AVR_C
The alternative is to download the ZIP file and extract it to where you want to use it. This will require you to periodically replace it with a new version.
Once you have the folder local to your computer. I recommend you read the README file to get an overview of the repository.
Testing Code
Once you are in the repository, you will want to begin testing your setup. In this case, it is ensuring tool chain, serial connection and your board all work together to enable C code creation.
Tool Chain
Note: My assumption on this page, is that you have already completed Setup for your respective platform. And by completed, you have been successful using your favorite code editor, make and an Arduino/compatible board. You are able to make changes to the led program and load it on the UNO. If you haven’t done this, please go the Setup page and complete the steps for your platform, otherwise, the rest of this page will be impossible.
Repository Configuration
The repository has two main folders, Library and examples. Each folder in examples is a simple example as to how to use an aspect of the Library. In each one of these examples there are two files, a c file, main.c and a make file, Makefile.
The first step is to ensure the Makefile is setup properly for your serial connection and your board.
Serial connection
The easiest method to determine your serial connection to your board is to use the Arduino IDE (yes, this is ironic). In the IDE, use Tools -> Port -> (list of ports) to identify the port connected to your board. Typically, the Arduino will call out the name of the board next to the port name.
Ultimately, you will want to have the system specific name of the serial port. For Linux/macOS, it will be similar to /dev/ttyACM0 or /dev/cu.usbmodem4301, respectively. For Windows, it will be something like COM3. Once you have identified the serial port, make the change on the 5th line of the Makefile:
5 SERIAL = /dev/cu.usbmodem3101
Board Changes
If your board is an Arduino UNO or one that is quite similar, then you don’t need to make any adjustments to line 10 “MCU = atmega328p”. If you have a different processor, for example if you are using an ATtiny84 board, use “attiny84”, for the MCU parameter.
First Test
Let’s try delayTest as the first test. It is the Arduino “blink” example, however it uses the C Library code, instead of the Arduino framework. It will help ensure the Library is being used for your code.
To run the code:
# switch to the example folder
cd delayTest
# compile code and upload to
make flash
# the above command will compile, link and load the Uno
# just as the Upload command would do in the Arduino IDE
If there are errors in compiling the code, you will need to confirm a change in the Makefile. We are adding the Library to the compilation, so we need to confirm the location of the Library to the Makefile.
# Make sure line 18 is uncommented
18 LIBDIR = ../../Library
# and line 65 has -I$(LIBDIR) at the end
65 CPPFLAGS = -DF_CPU=$(F_CPU) -DBAUD=$(BAUD) -I. -I$(LIBDIR)
Serial Test
The avr-gcc tool chain brings a much better serial communications capability to the Library. Once the uart code has been added to support the ATmega328P processor, you are able to use the standard C input/output commands such as getchar(), puts() and printf().
To begin testing the serial port, open the examples/serialio folder. Run make flash as you normally do. To see the output and provide input to the program you will need a serial monitor. Consider using the following based on your platform: (You can also use the Arduino Serial Monitor on all three platforms.)
A couple of notes on serial I/O using Standard C. The current simple approach for serial I/O uses polling, where the input/output routines wait for a char to be received/sent, respectively. This makes the I/O very slow (9600 baud), is blocking (no I/O, nothing happens) and requires some upfront initialization. This is fine for now, as we’re more interested in developing Standard C programs then production code.
For the last point regarding I/O (initialization), this does mean one needs to do the following: (Use the serialio example for guidance.)
At the top of the file, add
#include <stdio.h>
#include "uart.h"
# Inside of main(), add prior to your I/O
init_serial(); // this is a macro, so no () are required
Note: As noted in the README file in the repository, I have found a serial application, which seem to have an issue with this serial I/O approach. On Linux, using minicom, the serialio program wouldn’t respond with input. I tested the serialio using the Arduino serial monitor and it worked well. I haven’t seen the issue on any other combinations.
Make Commands
The Makefile in each folder has a variety of options which can be quite useful. Here are a few of them:
# Same as Verify in Arduino IDE, simply compiles the main.c program
make
# Same as Upload in Arduino IDE, compiles, links and uploads the code to the UNO
make flash
# Create a an assembly listing of the code complete with C source code
make disassembly
# Show the size of the code created in great detail
make size
# Remove all files except source files (main.c and Makefile)
make all_clean
# Remove all the current object files in the Library
make LIB_clean
Comments powered by Talkyard.