-AVR-GCC Tutorial

Tip on storing initial values in EEPROM

AVR microcontroller have EEPROM memory built in which adds a lots of abilities storing constant values, calibration data, and other data that may be read and changed at any time during program flow. Ion couple projects I have used EEPROM for storing last device configuration, eg. in TDA7313 volume, BASS, TREBLE input and output channel information is updated each time when it has been changed. After device si turned ON it reads last saved settings from EEPROM memory and restores last device state. But what happens when you turn device for the first time. It has to read initial values that has to be stored or it wil read 'FF' what may lead to crash or something else. One way is to prepare separate *.eep file with initial EEPROM data and then burn it separately to microcontrollers EEPROM. But this may not be always handy.

Interrupt driven AVR USART communication

Simple USART routines arenot always practical because waiting transmitting buffer to be ready in a simple loop occupies processor. Especially if we don't know when data will be received. Another issue when multiple data bytes has to be sent/received. As microcontroller speciality is interrupts so it is better to use them and this way improve overall performance and energy saving.

In previous article we discussed simple USART implementation. Where microcontroller constantly has to check if there is data received in UDR register. Also for sending it has to check if send buffer is free. Such coding is ineffective as MCU have always to run at 100% performance checking the buffer. In such mode batteries are going down really fast. Why not to set up guardian which would wake the MCU if it have received a byte via USART. In other hand Interrupt mode allows to perform other tasks at full capacity while waiting for USART interrupt.

Lets modify our program to Interrupt driven USART mode

Programing AVR USART module


AVR USART module is is one of more complex modules in AVR microcontroller, but it gives ability to interface microcontroller to other hardware like PC or other devices with many flexible features. USART differs from other AVR communication modules by its communication protocol and because it doesn't use separate pin for synchronizing communication. Synchronisation is made within protocol itself. It has several benefits as there are less wires used but there can be communication errors due to incorrect clock settings or due to clock non-stability. In some AVRs there is ability to synchronize communication externally with separate clock pin and run USAR in synchronous mode.

USART interface specification

Most people knows USART as RS232 interface – which is basically in computers. We cannot AVR name USART module to RS232 as there are not RS232 conditions met. One of them are voltage levels. AVR microcontroller operates lets say at 5V level, while RS232 logic levels are different: “0” - from +3V to 25V while “1” - from -3V to -25V. To make USART interface as RS232 there is an adapter needed. It is not hard to build one. You can connect two AVR or other microcontrollers with same voltages without any adapter via USART, but if you are going to communicate to PC, then you must connect through TTL – RS232 converter.

AVR Comparator C programming example

Lets write simple example on using AVR comparator module. Program is written in C and compiled with AVR-GCC compiler(WinAVR). Program example illustrates the case when Positive Comparator input is connected to Internal voltage regulator 1.23V by setting ACGB bitin ACSR register. Also as negative comparator input is taken ADC3 input via Multiplexer. As indicator LED is connected to PORTD0 pin. If input voltage is lower than 0.23V then Diode is OFF and if voltage exceed 1.23V diode lights ON. Diode state is changed with ANA_COMP_vect interrupt service routine on ACO bit toggle in ACSR register.

Working program code:

Using standard Qsort function in AVR-GCC

Qsort function is a generic sorting function which allows to choose your own sorting criterion. Not often but sometimes you may need to have some sort of array of data. Dont go to much in to it what data type you will be storing in your embedded application but lets say it is a simple notebook based on AVR. Lets analyse simple program how data can be sorted by using function pointer.

Lets start with sample data. In my example I will use simple structure of four fields:

struct persons

	char First_Name[31];
	char Last_name[50];
	uint8_t Age;
	uint8_t Address[50];

How to combine C program with external ASM

Sometimes it is useful to program some parts in assembly language while whole program is written in C. There are two methods how to inject assembler parts in C program. One of them is to write in-line ASM and another is to link existing assembler program. For instance some parts of program may require critical timings and you are not sure if C compiler can be as optimal as you expect. Other reasons according to avr-libc

documentation may be as follows:

  • Code for AVR's that have no RAM;

  • Very timing critical applications;

  • Special tweaks that cannot be done in C.

As I mentioned all this can be also done using in-line assembler feature. For somebody in-line assembler may look too complicated because of special syntax requirements. Before starting to write assembler program first read (What Registers are used by the C compiler) to ensure you are using right registers in your assembler program and won't mess up the normal program flow by occupying registers that are storing values from other routines. In most cases push and pop may do the job.

Using sprintf function for float numbers in AVR-GCC

Usually it is not recommended to use float numbers in while writing AVR programs,because AVR core doesn't have floating point arithmetics built in so floating point arithmetics is emulated by software. Sometimes you don't need to declare variables as float if operations are pretty simple like division or multiplying by 2, 4, 8... this can be replaced by byte shift operation (byte<<1)=byte*2. Of course it depends on level of programming and not always you can run away from floats. And you don't have to. If you code will fit to Program memory and execution speed isn't crucial then use floats or double number formats.

Lets see what happens when building simple program with float numbers:

AVR USART explained

The Universal Synchronous and Asynchronous serial Receiver and Transmitter (USAR) is powerful and useful interface in many projects. It is usually used for code debugging and other user interaction while sending and receiving data form PC. Lets analyse how USART works on Atmega8. The main features of Atmega8 USART are:

  • Full Duplex Operation with Independent Serial Receive and Transmit Registers);

  • Asynchronous or Synchronous Operation;

  • Master or Slave Clocked Synchronous Operation;

  • High Resolution Baud Rate Generator;

  • Data OverRun Detection;

  • Framing Error Detection;

  • Supports Serial Frames with 5, 6, 7, 8, or 9 Databits and 1 or 2 Stop Bits;

  • Odd or Even Parity Generation and Parity Check Supported by Hardware;

  • Multi-processor Communication Mode;

  • Double Speed Asynchronous Communication Mode;

  • Noise Filtering Includes False Start Bit Detection and Digital Low Pass Filter;

  • Three Separate Interrupts on TX Complete, TX Data Register Empty and RX Complete;

As USART is pretty complex peripheral I will just go through it. Detailed information may be found on data-sheets!

USART is separated in three modules: Clock generator, Transmitter and Receiver.

Serial Peripheral interface-SPI of AVR microcontrollers

This is high speed synchronous data transfer between microcontrollers or other peripheral devices. AVR SPI interface:

  • uses three wires for synchronous data transfer;

  • can operate as Master or Slave;

  • allow LSB or MSB first bit transfer;

  • support multiple bit rates;

  • has end of transmission interrupt;

  • has write collision flag protection;

  • wakes up from idle mode;

  • supports double speed master SPI mode

More ways to use AVR Flash memory using WinAVR

We've been talking about controlling AVR Flash memory in previous post. We talked how ease we can write and read from flash memory using PROGMEM atribute. But lets see more ways of usage Flash memory in your applications.

Sometimes when you write a code and in some places you are just sending strings to LCD or USART using simple expression like:

SendSTR(“This is a string”);

This seems very simple but not good way to use strings, because any way this string is being hardcoded in to flash memory, but compiler is forced to load this string to SRAM during microcontroller initialization before main() routine starts. And this string stays in RAM. This is ok for one or two strings but when you use significant amounts of strings this way then you really waste your RAM by holding all static unchanging data.


Subscribe to RSS - -AVR-GCC Tutorial