Pages

Sunday, 22 September 2013

Arduino in pure C

Arduino is a great, simple development platform and it's simple enough that even less advanced users can start and be creative straight out of the box. I have nothing against the C++ Arduino Libraries but relying only on those separates you a little bit from the machine itself. Arduino is simple enough to use it with Pure C. Doing so, you will not only learn a lot more, but will have an ultimate control over your software and will better understand what really is going on. I dedicate this blog to everyone who is starting with Arduino as well as to those of you who already have a lot of experience with it but were never really brave enough to abandon the Arduino Libraries and IDE itself.

In order to start we need a couple of tools.
  • toolchain & cross compiler: avr-gcc, avr-binutils
  • C library: avr-libc
  • Programmer: avrdude
Some other useful stuff which can be installed:
  • debugger: avr-gdb
  • simulator: simavr/simulavr
On most of the modern system those packages can be installed automatically (through a package manager). If that's not the case, you will have to download them compile and install manually. On ARCH linux you can install arduino package using yaourt, which will automatically install avr-gcc + avrdude, unfortunately those are not placed in the PATH directories so one needs to specify the paths explicitly. I'm not going to focus on those matters as in my understanding they're a little out of scope.

To start the work first of all, we need to prepare a Makefile which will ease up the development and compilation process. The avrdude configuration paths, serial port or the target mcu should be adjusted accordingly to the configuration of your board and system. TARGET denotes the name of the ELF file which will be generated by the compiler and SOURCES variable should contain a list of all source files which must be compiled. For the purpose of this simple example there is only one blink.c which we'll create later on. The basic Makefile which I will use and extend further on looks the following way:



Using C with AVR MCU requires some knowledge of the avr-libc library. So this site:

http://www.nongnu.org/avr-libc/

will be your best friend for now on. Not mentioning the detailed datasheet of the MCU itself. For Atmega's installed on Arduino UNO this one is located here:

http://atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet.pdf

The Arduino Schematics also comes very handy:

(Rev 3): http://arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf

For the moment we need to know three things.
  1. In order to configure a pin as output we need to configure it in the DDR(B,C,D) register.
  2. In order to raise the pin high or low we need to set an appropriate bin in the PORT(B,C,D) register.
  3. The avr-libc implements the simplest, so called, busy delay (which in general is a bunch of loops) which can be used for our purposes.

Let's put this together:


A short walk through this example. Line 6, writing 0x01 will configure pin 0 of port B as output, on the next line I'm setting port B to zeros. On Line 10 I'm XOR'ing current value of PORTB with 0x01, this will cause a value of the first bit to toggle since

0 xor 0 = 0;
0 xor 1 = 1;
1 xor 1 = 0;
1 xor 0 = 1;

On the next line I'm calling a avr-libc delay function, so our LED won't blink with full clock speed. If we have a look at the schematics, then we can see that PORTB0 is connected to pin 8 on the arduino. This is where the LED should be attached.

All that needs to be done is as simple as:
make
make install

... and our blinking led C "project" should run now on Arduino. Complete code can be found here:

https://googledrive.com/host/0ByE_WFvvg-guTzE4TmFwMDhaZTA/blink.tar.gz

1 comment:

  1. Thanks it was very much useful!! works neat in Arch linux.

    ReplyDelete