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

Arduino MIDI Music Box

It's time to do something useful with our small 8-bit computer. Music box is a fun and easy project. It's not demanding from the hardware point of view but it can be a little bit tricky from the software point of view itself - ideal project to learn a lot and not to spend the whole day soldering. What we will need:  an Arduino (of course)  Piezo buzzer  ... and that's all. Now a couple of words of what we want to achieve.  Requirements  Let's point them out: play monophonic melodies by generating tones (1 channel MIDI instrument) the notes will be send by the PC through the serial port  our musicbox should be visible to the PC as a MIDI port  be able to use MIDI player of choice on PC to play MIDI files on our musicbox  The requirements are specified. Unlike most of the simple projects around which play the same melody everytime, which most of the times is hardcoded in the program memory and in order to change it...

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...

Generating Tones with Timers

Previously I presented a basic way of using timers in order to generate delays. At this time, we'll learn how to use timers and piezo buzzer to generate tones (beeps). The code for that won't be very different from what we were doing previously. Let's start with defining the requirements of our implementation. Our "beeper" function should allow us to generate a beep of given frequency and duration. Simple as that. Just to quickly summarize, when using timer for delay purposes we configured it in CTC mode and configured the prescaler and OCRXA register value so the timer "overflowed" with a 1 kHz frequency (1 ms period), the delay duration was specified by the number of "overflows". Previously, as long as counting the 1 ms cycles was good enough to determine the duration, now the duration depends on both parameters, the actual duration specified as an input parameter as well as the frequency itself.  Let's list steps that our "be...