Embedded Systems Design

Low Power and Embedded Systems - Workbook 3


In this workbook we will make a precise timer, and we will attach a Liquid Crystal Display (LCD) to the microcontroller via an interface board.

Supporting material



Data sheet for the Atmel ATMEGA168P used in these exercises. You will need to refer to this frequently. Within these workbooks this will be referred to as 'the datasheet' The section numbers referred to in these workbooks refer to revision 8161C of the datasheet dated 05/09.



Schematic for LCD interface PCB.



Printed Circuit Board layout for LCD interface PCB, for reference only.



Microcontroller implementation for the LCD interface PCB, for reference only.

Interrupt Vector Table


Table of interrupt vector names for ATMEL AVR series microcontrollers.

An on-line version of this guide is available at:


Exercise 1 - Precise timing

The _delay_ms() function used in workbook 1 is useful, especially during testing, but it does not take account of time spent servicing interrupts. To get precise timing, it is necessary to use a timer.

The ATMEGA168 has three. Timer0 and Timer2 are 8 bit, and Timer1 is 16 bit. Have a look at section 14 in the datasheet to get an overview of what the timers can do. The requirement of this exercise is to take our ADC samples at exactly 1 second intervals.

One mode which can be selected for a timer is to count from zero up to a value held in an 8 bit register: OCR0A for Timer0, OCR2A for Timer2, or a 16-bit register, OCR1A for the 16 bit timer, Timer1. When the timer reaches the value held in the compare register it immediately resets the counter to zero, issues an interrupt, and continues counting from zero. This mode is referred to as CTC mode, and is the one we will use in this exercise.

One second is rather a long period with a master clock of 14.746MHz, so the 16 bit timer will be the appropriate one to use.

Even so, at full clock rate this would only give a maximum period of 2^16/(14.746 x 10^6), or approx 4.4 milliseconds. A divider prescaler can be introduced between the 14.746MHz master clock and the timer input, which makes it possible to greatly increase the maximum time period achievable by the 16 bit counter. The prescaler divider value P, is selectable in a number of powers of 2, up to a maximum value of 2^16.

As we have seen, with a 16 bit timer, the maximum period we can create is about 4.44ms. We need to choose a prescaler so the maximum count (2^16) gives a period greater than 1 second. The best match from the prescaler values available (see section 15.11.3) is 256. Dividing by a higher number would reduce the resolution of the timer.

- The period of the 16 bit timer input clock is now (1/14.746MHz) * 256 = 17.36us

- To get a 16 bit timer period of 1s, the 16 bit timer register has to be set to 1/17.36us = 57601, or in hexadecimal 0xE101

These can be written as a 16 bit value OCR1A = 0xE101 or if written as two 8 bit values they must be written high byte OCR1AH first then Low byte OCR1AL.

The main loop will reduce to something like:

    while (1) {
        if (gotadcvalue == 1) {
            USART_TransmitUint8(adch) ;		
            USART_Transmit(0x0A) ;		
            USART_Transmit(0x0D) ;		
            gotadcvalue = 0 ;

Exercise 2 connecting an LCD

So far the only output from the microcontroller has been via a serial data connection, or by flashing an LED. In this exercise you will add an interface to an LCD controller and display. There are a wide range of these alphanumeric displays on the market, with different size and backlight options, but nearly all use either a Hitachi or Seiko controller. These controllers are almost identical in operation, but the initialisation is fiddly, requiring a set of commands with minimum periods between them. The LCDs themselves run from a 5V power supply.

To speed up development for you and to reduce the number of IO pins required, a small PCB is provided which takes a clock and data signal and does the interfacing to the LCD for you together with a supporting library. This PCB also uses an ATMEGA168 microcontroller.

For your interest, links to the schematic diagram, specification, and associated C code for the library are available in the supporting material section at the start of the worksheet.

Hardware connections.

To use the LCD, it is necessary to incorporate a library of low level drivers which take care of communicating via the LCD interface board. For flexibility, this library allows you to connect the LCD via any two lines on the same port of your microcontroller. For this exercise we will use PD6 and PD7 on PORTD.

For code portability the library uses generic names for controlling these pins, and these need to be defined and the definitions made visible to both the library function and the main C program. This is done as follows:

The following section will prove very useful in the future, but can be skipped if you are behind schedule.

Copyright Ian Wassell and Brian Jones 2009