Skip to main content

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

Comments

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

    ReplyDelete

Post a Comment

Popular posts from this blog

RTC without RTC ? How good is my crystal ?

Clock - I think that it's the most popular idea for a project with the MCU . It's not that hard from both software and hardware side to realize but not that trivial as well, not mentioning the fact that once realized it sits somewhere in the house, constantly reminding about itself and brings a kind of satisfaction :). There are a lot of options really to implement, a buzzer alarm, perhaps a thermometer, display and buttons servicing, perhaps maybe even serial port usage for NTP synchronization. But ... The most challenging thing - like in every clock is the time reference source. There are a couple of options: well calibrated frequency source acting as an interrupt source Real Time Clock module with external crystal ( < 20 ppm ) internal clock These days RTC chips are so cheap and widely available that they are really the only reasonable choice, but if we're only planning to play around a bit with the software without paying much attention to accura...

Arduino R-2R ladder Audio DAC

There is a lot of projects out there which use  R-2R ladder and an Arduino to recreate sounds from either SD card or short audio clips programmed directly to MCU's flash memory. Although using SD card is fairly reasonable and provides a lot of flexibility it's not very challenging (from the software point of view) and it requires some additional hardware. Believe it or not we already have all the needed hardware in the Arduino itself. Assumptions In this project I'll play mp3 or any other multimedia files from the PC using Arduino. Bellow are the details: Play PCM 8kHz 8bit Audio with Arduino Audio samples will be transfered via USART from the PC in binary format using SLIP Audio files will be decoded on the PC side and only the RAW data will be send to Arduino Timing Arduino is a powerful machine, powerful enough that it's possible to play audio with even higher sampling rates and bit-resolutions than assumed above, the bottleneck in this...

Simple Serial Port Command Line Interface (CLI)

It's often very useful to have some sort of interface through which a basic management can be done of our application. Whether you're designing a giant Marquee with a LED display or a plotter or you simply need to get some diagnostics from your device occasionally, a simple CLI system can come very handy.  Of course, designing something similar to "bash" or any other unix shell is completely out of scope since those applications are huge and are simply an overkill for our needs. It's pretty simple though to create some basic, yet flexible & easilly extensible CLI system. First thing needed is a command type definition. This will bind a keyword with an actual underlying routine executed for that keyword typed in the CLI . typedef struct _t_cmd { const char *cmd; void (*fh)(void*); } t_cmd; The command type is pretty simple. There's the CLI command/keyword pointer, it holds a pointer to the execution function and that's it. OK, so...