You are on page 1of 19

USING AVR MICROCONTROLLERS FOR PROJECTS K.Padmanabhan, P.Swaminathan & S.

Ananth The Atmel AVR family of Embedded microcontrollers Having done through a number of microcontrollers for several application projects, it is now found that the chip AVR 8535 (and its new version ATMega8535) are superior quality devices both in performance, versatility and price. This two part article is intended to introduce this processor with typical applications illustrating how we have a very powerful and cost effective embedded system in this device. Yes, at the first instance, the AVR 8535 is yet another microcontroller. Having seen the industry standard Intels 8051 and its derivatives over two decades, with versions having better memory, speed as well, such as the Philips 8951, the Atmels own 89c51 and so on, it may be thought that there is not any need to venture into a different family of devices, such as the AVR. But such a thought must be set aside for a while; soon, the power and flexibility of this AVR will prove it to be false. The AVR family itself is very large and expanding; however, for a cost of about 250 Rs., if one can build a microcontroller based project with the following features, why delay? 1. Four ports, one with 8 Analog Digital Converter channels 2. A.D.C. having a time of conversion of as low as 60 microseconds! This itself, if one wants to add an external ADC to the 8051 or any other controller chip, the cost will fly to over four digits! And that is a 10 bit A.D.C. not just 8 bits. 3. Now for speed. If an 8 MHz crystal is connected, each instruction executes in 1/8th of a microsecond. The 89c51 at 12 MHz clock had its internal divide by twelve; so, it ran at just 1 microsecond. Thus, this chip is 8 times faster with this crystal, but we can use a still higher frequency crystal also. The processor is called RISC processor. So most instructions execute in one clock cycle itself. 4. The chip has RS232 transmit and receive much like the 8051 family, but it can support even higher baud rates. 5. There are quite many internal registers, internal RAM, internal EPROM and internal CODE memory (flash memory).(4K bytes). 6. And the instruction set is fully versatile and complete, with several arithmetic, logic and transfer instructions, several relative jump instructions and so on. 7. There is an analog comparator pin also, which can compare an external analog voltage and take control action. 8. Reset is possible through software; and a WATCH DOG is provided. Also power down, sleep modes. 9. There is an additional Serial Interface known as the SPI bus, with three wires Data (2) and Clock (1). These pins are used for PROGRAMMING

OR LOADING THE CODE from a PC interface through printer port or serial port. So, we can enter the code for our program, after development, into its internal 4K flash memory, through these 3 pins from a Computer. And there is no need for 12 volts and so for programming these internal flash memory locations. Just 5 V supply is alright. 10. TwoPWM output pins, useful for power control applications is also available. 11. Of course, there are the several timers like in the 8051, but with much much more time resolution. Additional features like input capture and output compare are also available. Thus, the 8535 microcontroller executes 8 times faster, cheap with ADC in it and has a simple instruction set for every application. Though there are several chips in the AVR family, all with the same instruction set almost, the ones that are freely and cheaply available and which have the complete set of port pins, are the following: 1. 90S8515 2. 90S8535 3. ATMega8535 Small or tiny versions of the AVR family (much like the 89C2051 with 10 pins in the 89C51 family) are also available, such as the ATTiny26. Of these, the devices 1 and 2 of the (90S) family were the only ones available in our local market at about 250Rs last year (2004), but now, during this year, (2005), these are becoming obsolete and only the more powerful device the ATMEGA 8535 - is freely available in local shops, at about 250 Rs. Thus, this article, which was first prepared and sent to EFY during the middle of 2004, has now been revised to fix its purview only on the presently available and more versatile ATMEGA8535. We shall delve into the chips inside with typical programs and circuits in this two part article.

Fig.1. Pin out of the AT Mega 8535, the 90S8535. The pin out for 90S8515 is different.

CIRCUIT DESCRIPTION OF AVR 8535 PROGRAM DEVELOPMENT BOARD. The development work on the 8535 does not require expensive software to be purchased. All are available for free from the net. And also the method of programming the device! Such is the support that Atmel provides for its device that even a C compiler is available free. First, the chip is interfaced to an LCD single line alphanumeric display with the pins of the LCD module connected to the port bits of the 8535. A crystal is connected to the pins12, 13. It can be a 8 MHz crystal or any other, up to 16MHz.. For eg., a temperature display and controller is required to be devised. We can use a program given in the CD and that would show the temperature on the LCD display. Port Cs bit 0 can control the heater to be off or on through a miniature relay, whose contacts are in series with the heater.

+5 +5
2

7 +5V 1 5V R C + analog voltage input (LM35) 10 32 9 RST 40 12

LCD 1 x 16 or 2 x 16 14 4 5 6 1

10K Contrast 3

24 25 26 29 8535 Port C for control. 22 + relay 9 1 16 8 ULN2003

13 8MHz

GND AGND 11 31

22pF each

fig.2 An 8535 circuit for showing an analog voltage from an LM35 temperature transistor to indicate Temp. and control a heater through port Cs bit 0 (pin22) via a ULN2003 and a miniature 5 V relay .

The program is just reading the ADC value of channel 0 from pin40 and showing the same on the LCD as a four digit number. A few lines of code to compare the number with a set or required temperature value and to toggle the bit Port B.0 will do the work. And this is but a very simple example of the applications that one could put the AVR to. The ATMEGA 8535 is featured with some advanced features both in its instruction set and in its internal embedded hardware that any kind of embedded control application even a digital filter built in can be implemented on the device, provided one gets quite conversant with its hardware and software particulars. And the 8535 Mega handbook which can be downloaded from the ATMEL.com site is a 300 and more pages book, which needs painstaking study to fully exploit its features, nay, even work out simple applications like the one above. It is with this purpose that this serial is aimed to provide a lucid introduction to most of the features and by providing meaningful application programs. These application program units can be combined in any application to yield a powerful controller, filter or motor controller or whatever. DEVELOPING THE PROGRAM AND PROGRAMMING THE CHIP Unlike the 8051 or any other microcontroller, the above process of program assembly and actual programming are rendered extremely simple in this aVR chip. Any A V R program has the extension .asm. It is first written in either the EDIT or Wordpad program. As with all microprocessor or microcontroller programs, we enter the program by mnemonics and then find out the code list for the program. The code is found by using the cross assembler software, which is AVRASM.EXE. This software is given along with this article. To know the modus of writing an assembly program, a simple program written for the AVR processors is given in the table TEST1.ASM below. If a line begins with a ;, that line is meant only for entry of comments. The crossassembler will not use it for code formation.
; Test 1.asm : Learn to know simple port output to the LEDs. ; What to learn here: ; - to access a output-port (Port B and the LEDs) ; - the different parts of a typical assembler program ; General conventions used here: ; - Words in uppercase letters are command words of the assembler language ; or predefined ports of the processor. ; - We define Words in lowercaseletters. ; Assembler directive: to define the target chip type ; ; Usually one does not have to include the def.inc-file. But it is ; good to do I, manually by adding these lines. Failure to include ; these definitions would result in a number of error messages. Simply

; copy the def.inc-file to the same directory where your source code resides ; or add your whole path to the include-statement below. .NOLIST .INCLUDE "m8535def.inc" .LIST ; The directives NOLIST and LIST switch off the listing of the INCLUDEfile ; (the listing will be found in the file TEST1.LST). ; Define register ; ; This register is defined for the purpose of interim storage of values. ; The .DEF statement renames one of the 32 8-bit registers to a easier ; to remember name (here: mp). R16 to R31 are more verstatile ;registers to use than R0- to R15. Hence, we take R16 for a general ;purpose register.; R16. Renaming these register also has the advantage ;that whenever we ; want to change such a location we will just have to change the .DEF ; statement. Otherwise one would have to go through all commands re; ferencing the register R16 and change all these lines. .DEF mp = R16 ; Reset address: .org $0000 ; Up till now not one byte of code was created. Here we start with the ; first code, we define the program start address. Later we will see, that ; this jump command at address 0 is useful. Here the first byte of code ; is created. ; Whenever the AVR is restarted it starts its program execution at address ; 0000. Such a restart may be activated by a power-on, by a hardware ; reset on the respective pin or by a watchdog-timer reaching its zero ; count. (The watchdog timer is not used here.) ; In all these cases a jump to a program called "main" will be executed. ; RJMP means "Relative Jump". In a relative jump a relative distance ; is added to the current execution address and the program is executed ; at this new address. We don't have to care about this distance by now ; because the assembler calculates this relative distance from the information ; in our source code and adds it automatically - as long as the maximum ; permissible distance of 2 kB for- or backwards is not exceeded, otherwise ; the assembler stops with an error message. rjmp main ; Here we start with our main program code. First we have to define a ; label, because the assembler has to know that this is the target of a ; jump. A label is a freely defined name, followed by ":". For a better ; overview labels start in column 1 of a line, all commands start with a ; blank or a tab character. Behind the label there could be a command, ; but this is not used here. main: ;First we must set up the stack pointer. Then only subroutines can be ;called and they can return back to the return address saved on the ;stack.

ldi R16,low(RAMEND) ; Load low byte address of end of RAM ;into register R16 out SPL,R16 ;Initialize stack pointer to end of internal RAM ldi R16,high(RAMEND) ; Load high byte address of end of RAM ;into register R16 out SPH, R16 ; Initialize high byte of stack pointer ;to end of internal RAM ; then we need to define port B as output, because the LEDs are connected ; to these port pins. This is done by writing eight ones to the data direction ; register of port B. The data direction register of port B is named DDRB, ; we don't have to care about its real address, as the .def-file holds this ; information already. We do that in two steps. First we load binary 1111.1111 ; to a register: ldi mp,0b11111111 ; The command LDI (LoaD Immediate) loads an 8-bit value into the register ; mp. This command is only valid for the registers R16 to R31. That is why we ; defined mp that way at the beginning of this source code file. Commands ; with two parameters are generally defined such that the first parameter ; is the target (here: register mp), where the result of the operation goes to. ; The second parameter is the value or location where the result comes from. ; After execution of this command the register mp has the value 1111.1111 ; binary, FF hex or 255 decimal. ; The 0b... of the beginning of the number is always a binary, 0x... is a hex ; notation. The leading zero is the signal for the assembler to expect a number, ; not a register or something else. Numbers without 0b... or 0x.. are decimal ; by default. (LDI mp,255 would have the same result.) ; This value has to be brought to the data direction register of port B now ; to make all port pins to outputs. A 1 in the data direction register brings ; the pin to switch on its output drivers, a zero makes it an input. out DDRB,mp ; The command OUT writes register values (here: mp or R16) to a port ; (here DDRB). DDRB is defined in the file "8515def.inc", which is already ; read by the assembler when the .DEVICE-command or the .INCLUDE; command above has been processed. So we don't need to care here ; for the real adress of this port. ; The following part of the program now writes zeros and ones to the port. ; The LEDs are switched on and off with a high frequency. Because this

; part of the program is repeated over and over again, and this is called a loop. ; The label loop is jumped to whenever the processing of writing ones and ; zeros is ended. loop: ldi mp,0x00 out PORTB,mp ; LDI loadd eight zero bits to the universial register mp. OUT copies these ; zeros to the port B. This time they are written to the port's output register ; named PORTB. Rcall delay ; The zeros set the LEDs on, because they are connected to the supply ; voltage over resistors of 1 k (0=on, 1=off). ldi mp,0xFF out PORTB,mp ; After that eight ones are loaded into the register mp and copied to ; the same data port. That switches the LEDs off. rjmp loop delay: clr r19 ldi r17,$ff loop1: inc r17 brne loop1 inc r19 brne r19,loop1 ret ; With this relative jump we jump back to the start of the loop and the ; loop is repeated as long as power is supplied. ; At 1 MHz frequency, the default frequency of the Mega 8535, every LDI- and OUT-command execution requires ; 1000 ns, the RJMP need 2 cycles and 2000 ns. Every 4000 ns the loop is ; executed once, so with these values the LEDs are switched at 250 kHz. ; if a delay is introduced in between, then the LEDs blink slower. The ; rcall delay does this, by decrementing a register r19,r17 from 255 to zero ;and thus elapsing time, making it 256x256 times slower, about 0.5Hz. ; After assembling this sourcefile the program will have eight words. ; The file TEST1.LST holds the result of the assembling process in form ; of a listing.

Then, it is assembled using the AVR assembler. That is avrasm.exe, which is included in the CD, and which can of course be downloaded free of cost. There is another more versatile AVRSTUDIO 4.0 software which is over 2MB and that is a user friendly program for development. However, we shall use the simpler direct assembler, the avrasm.

5V +5 +5V 8 nos LED

1 5V R C 10 32 9 RST

8 8535 .

12

13 `

GND AGND 11 31 22pF each

Fig. 3 A simple test circuit forATMEga 8535 on a breadboard and LEDs. (for mega8535, the crystal and 22pF are not even necessary; pins 12,13open). Simply type avrasm -i adc.asm adc.lst adc.hex under DOS prompt. This means that we want the cross assembler to prepare the code generation for our mnemonics in a file test1.hex, and also to provide a text file giving both code and our program together in test1.lst. Then, we get the listing file adc.lst and the hex or code file adc.hex. Otherwise, one can prepare a batch file. This is done as follows: On Dos prompt, enter copy con avr.bat Then type in the next line: Avrasm -i %1.asm %1.lst %1.hex Then in the next line press the F6 key which displays Control-Z. Then, press enter key again. The display comes as 1 file copied. Now the avr.bat file has been prepared. We invoke this simple batch file to assemble this (or any) program as under: Upon Dos prompt, type : Avr test1 This assembles the program, and forms both the list file (that contains the code cum assembly listing) and the hex file that is the actual intel-format hex file for use by the programmer. Like this, any other assembly program xxx.asm can be coded into the hex.-file by simply typing avr xxx, on DOS prompt. xxx denotes the name of the program. The .asm is not be typed. It must be noted that in our test1.program, there is a line called .INCLUDE "C:m8535def.inc. This means that the program uses the statement file for the ICs parameters, which is called m8535def.inc. This file is also required along with the avrasm.exe cross assembler. When we want touse the mega8535, this is the name of the include file. For other Avr processors, such as 90s8515,90s8535, at-Tiny 26 etc., the respective include files are:

8515def.inc, 8535def.inc,tn26def.inc These files are required for generating the codes for them. The second thing is to program this code into the chip. A chip previously programmed or erased is automatically erased when a new program is put into it by our device - programmer. The AVR Device programmer The programmer called ICPROG was sent along with the earlier prepared version of this serial. However, with the availability of the mega 8535 chip, since this programmer is not capable of programming it, it is now deleted from this article. It is useful only for the earlier 90S series of 8515 and 8535. Now another programmer software called AT-PROG is given along with this part. This is also a simple to use, invoked from command-prompt, software, which is menu driven and user friendly. The programming software uses a circuit board connected to the printer port of a computer. The circuit is very simple. It just connects the IC to the pins of the PC printer port. The following gives the figure, showing the connections. Mega8535,90S8535 5 Printer port D-male D25 connector 2 3 10 18 9 6 8 7 11 10 11,31 +5V

22pF crystal (optional)

22pf Fig.4 The circuit diagram of the AT-PROG multi-i.c. Avr programmer. This circuit is assembled on a small PC with a D25 male-female plug at one end, as shown in the photograph of our prototype below. The IC base is a 40 pin Zero-insertionforce socket, known as ZIF socket in the market. This enables easy insertion and removal of the IC to be programmed. The AT_PROG.exe is a simple software which can be run under DOS prompt, by typing AT-PROG. The program along with its associated help files: At-prog-hlp.htm At-prog.exe At-prog.cfg At-prog.ini are to be available. These are given along with this article. The menu driven window of the at-prog programmer has the following menu headings. 1. FILE menu This is to select or open the file test1.hex., or whatever, which is to be programmed into the device.

Pull down by clicking this menu and when OPEN is seen, enter the file name in the window provided for file entry, as test1.hex and press Enter. 2. The choice of IC to be programmed is selected by another window Select by pressing on the edge of this small rectangular window with the mouse click and choose the IC accordingly. The figure shows how ATMEGA8535 has been chosen. 3. Next connect the Printer port connector connection to the programmer board, whose circuit is shown above. 4. WRITE menu Use the WRITE menu by clicking on it. Then, that window shows a border and the bottommost right side small window whitens and shows Connecting. Then, the data is transferred through to the IC and verified after programming, showing OK in that same window. 5. Check menu This small window menu is used to find out if the IC is inserted in the socket and if connector connections are OK. This will say an error if the IC is not there or is not responding. In this mode of programming, the Serial-peripheral Interface (SPI) of the AVR chip is brought to use. This interface is having three important wire connections, called MOSI - Master output and slave input MISO - Master input and slave output SCLK - serial clock In this way, the SPI interface does the transfer of data (ie., our program codes) into the chip, which is now a slave. The clock and data are given to the two pins MOSI and SCLK of the chip. Then, upon each byte received, the chip has to acknowledge it by a byte, which is 53hex in this format for the SPI. In the check mode, the IC is enquired about its name by the computer, which it replies with its signature code. Each IC has its specific signature code. Thus, by noting the code itself, what IC is being programmed will be known to the computer. So, the small little window under the device select rectangular window can be clicked to show autodetect the IC mode.

6. Options menu In this menu, the speed of the clock used for data sending from the Computer can be selected as slow, normal and fast. With present high speed PCs, choose normal or slow. 7. In the same menu, there is an option read signature bytes. This is to be enabled and is so by default. 8. The Port menu which is next to the File menu is useful if a different printer port is available. The program automatically selects the available printer port.

After pressing the WRITE window, the activity shows OK. Then the chip is removed from the programmer circuit board and fixed on to the target board, which was mentioned, for the case of the test1.asm program, as that of Fig.3. Remove the programmed chip and place in the circuit given in fig.3, which is just a breadboard circuit, and apply 5V, press the switch connected to Reset, if need be (it works on power ON itself). You will find the LEDs blink (fast) and the waveform can be observed on the CRO for any of the pins at the output to the LEDs. It is at about 600 Hz.
2. Message display on the LCD module ; ************************************************************** ; * This program writes a message on to the LCD * ; *************************************************************** .NOLIST .INCLUDE "m8535def.inc" ;device =ATmega8535 .LIST ; ; Constants ; ; Used registers ; .DEF rmpr = R16 .DEF temp = R14 .DEF result=R12 .DEF mpr =R16 ; Code starts here ; .CSEG .ORG $0000 ; ; Reset-vector rjmp Start ; Reset-vector ;************** various subroutines for LCD display***************** ;cmd is the LCD modules command entry subroutine.Command Value in R16 cmd: cbi portc,2 cbi portc,3 cbi portc,4 out portb,r16 sbi portc,4 nop nop nop nop nop cbi portc,4 rcall delay1 ret ;lcdwr is the LCD modules data entry subroutine. Asci codeValue in R16 lcdwr: cbi portc,2 cbi portc,3 cbi portc,4 *

sbi portc,2 out portb,r16 sbi portc,4 nop nop nop nop nop cbi portc,4 rcall delay1 ret ;init_lcd is the LCD modules initialize LCD routine for cursor etc. init_lcd: ldi R16,$38 ;function_set command for 8 bit data drive rcall cmd ;write this in the command register for LCD rcall delay1 ; wait since this takes some milliseconds for LCD rcall delay1 ldi R16,$0e ; command for entry mode set rcall cmd ; cursor active, display on, no blink. rcall delay1 ldi R16,6 ; command for cursor shift right after each write rcall cmd ldi r16,1 ;command for clear display rcall cmd rcall delay1 ret delay1: clr result ldi R16,$a0 loop2:

; a suitable number for the required delay

inc R16 ; increments from 160 ($a0) to 256 brne loop2 inc result ; increments result register from 0 to 255 brne loop2 ret ;got 256 times 95 for loop

; **************** End of the subroutine section *************** ; ; ******************** Main program **************************** ; ; Main program routine starts here ; Start: ldi R16,low(RAMEND) ; Load low byte address of end of RAM into register R16 out SPL,R16 ; Initialize stack pointer to end of internal RAM ldi R16,high(RAMEND) ; Load high byte address of end of RAM into register R16 out SPH, R16 ; Initialize high byte of stack pointer to end of internal RAM LCD: ldi out out out r16,$ff ddrb,r16 ddrc,r16 ddrd,r16

;ff makes all bits as output on the port B ;PORT C BITS USED FOR LCD WIRING

ldi r16,$55 out portb,r16;then alternate bits are low and high ($01010101) ;the above is a test which one can find if the program works! rcall init_lcd ldi R16,$80 rcall cmd ; simply observe the pins 1-8 for alternate high and low outputs! ldi R16,$45 ;"E" rcall lcdwr ldi R16,$6c rcall lcdwr ldi R16,$65 rcall lcdwr ldi R16,$63 rcall lcdwr ldi R16,$74 rcall lcdwr ldi R16,$72 rcall lcdwr ;"l" ;"e" ;"c" ;"t" ;"r"

ldi R16,$6f ;"o" rcall lcdwr ldi R16,$6e ;n" rcall lcdwr ldi R16,$c0 ; this command is to set to the next half of LCD rcall cmd ;because 8 characters have filled the first half ;omit these above 2 lines if a two row LCD display or a Hitachi 1-row ; display is used. ldi R16,$69 ;i rcall lcdwr ldi R16,$63 ;"c" rcall lcdwr ldi R16,$73 rcall lcdwr ldi R16,$20 rcall lcdwr ldi R16,$46 rcall lcdwr ldi R16,$6f rcall lcdwr ldi R16,$72 rcall lcdwr ;"s" ;" " ;"F" ;"o" ;"r"

here:

ldi R16,$55 ;"U" rcall lcdwr RJMP HERE; Test of the serial interface

The above program displays the message Electronics ForU on the LCD module. (Fig2). The LCDs have 2 row or 1 rows. In some one row types, the first part of 8 characters are written consecutively; the next part needs to restart the cursors address at

$c0. But Hitachi make single row types do not need to restart the cursors address after the eighth entry; the characters can be written consecutively up to 16, i.e., entire row. The program is given the name :LCD_CHAR.asm and is assembled into the .hex file by typing and invoking the cross assembler AVR. avr lcd_char Then, the file lcd_char.hex is generated. This is used in the at-prog programmer to write this to the flash memory of the Mega8535. While assembling this using the above command, please note that the definition file for the IC mega8535 is in the same directory (m8535def.inc). Another program for table look up The above message display program was written by writing the instruction Call lcdwr for each character. Instead, if we enter all the bytes for Electronics forU in a table address, they can be picked up one by one until the end and shown on the LCD. For this purpose, there is an instruction called LPM, load program memory. The table is in program memory only and so the name.
;-------------------------------------------------------; File: main.asm ; .INCLUDE "m8535def.inc" ;device =ATmega8535 .LIST ; ; Constants ; ; Used registers ; .DEF rmpr = R16 .DEF temp = R14 .DEF result=R12 .DEF mpr =R16 ; Code starts here ; .CSEG .ORG $0000 ; ; Reset-vector rjmp Start ; Reset-vector ;************** various subroutines for LCD display***************** ;cmd is the LCD modules command entry subroutine.Command Value in R16 cmd: cbi portc,2 cbi portc,3 cbi portc,4 out portb,r16 sbi portc,4

nop nop nop nop nop cbi portc,4 rcall delay1 ret ;lcdwr is the LCD modules data entry subroutine. Asci codeValue in R16 lcdwr: cbi portc,2 cbi portc,3 cbi portc,4 sbi portc,2 out portb,r16 sbi portc,4 nop nop nop nop nop cbi portc,4 rcall delay1 ret ;init_lcd is the LCD modules initialize LCD routine for cursor etc. init_lcd: ldi R16,$38 ;function_set command for 8 bit data drive rcall cmd ;write this in the command register for LCD rcall delay1 ; wait since this takes some milliseconds for LCD rcall delay1 ldi R16,$0e ; command for entry mode set rcall cmd ; cursor active, display on, no blink. rcall delay1 ldi R16,6 ; command for cursor shift right after each write rcall cmd ldi r16,1 ;command for clear display rcall cmd rcall delay1 ret delay1: clr result ldi R16,$a0 loop2:

; a suitable number for the required delay

inc R16 ; increments from 160 ($a0) to 256 brne loop2 inc result ; increments result register from 0 to 255 brne loop2 ret ;got 256 times 95 for loop

; **************** End of the subroutine section *************** ; ; ******************** Main program **************************** ; ; Main program routine starts here ; Start: ldi R16,low(RAMEND) ; Load low byte address of end of RAM into register R16

out SPL,R16 ; Initialize stack pointer to end of internal RAM ldi R16,high(RAMEND) ; Load high byte address of end of RAM into register R16 out SPH, R16 ; Initialize high byte of stack pointer to end of internal RAM LDI R16,$FF OUT DDRB,R16 OUT DDRC,R16 ; MAKE PORTS B AND C AS OUTPUT PORTS (WIRED TO lcd) rcall init_lcd clr r17 clr r18 ; required in the table fetch routine LCD: ;-------------------------------------------------------ldi ZH, high(table*2) ; Set up Z to point to the beginning of table ldi ZL, low(table*2) add ZL, r17 ; Offset Z by r18:r17 adc ZH, r18 lpm ; Load mov r16,r0 ;get loaded value into r16 cpi r16,$ff ;table end? breq idle rcall lcdwr ;write on lcd display inc r17 rjmp LCD ; use Hitachi LCD display module if 1 row type is used; or else use ; ;any two-row type LCD. Otherwise, this above program sequence will ;work only for 8 characters. The rest will not be seen: Electron ;only will be visible. idle:

table: .db $45,$6c,$65,$63,$74,$72,$6F,$6e,$69,$63,$73,$72,$6f,$72,$55,$FF

ldi r16, (1<<SE) out MCUCR, r16 sleep rjmp idle

; Enable sleep