To demonstrate how to blink LCD Segment on an AVR Butterfly using Native AVR Machine Language.
PREAMBLE:
A picture's worth a thousand words, and example code is worth twice that to a new-comer. Here is a simple program that flashes an LCD segment on the Butterfly display.
NOTE:
A detailed desciption of the program follows the listing in another post.
THE PROGRAM IN AVR ASSEMBLER:
CODE
;----------------------------------------------------------; ; B L I N K E N D A S H .; ; ===================== .; ; .; ; A SMALL PROGRAM THAT WILL FLASH ONE OF THE LCD SEGMENTS .; ; THE BUTTERFLY EQUIVALENT OF BLINKING A LED (BLINKENLITE).; ;----------------------------------------------------------;
;---------------------------------: ; RENAME/DEFINE WORKING REGISTERS.; ;---------------------------------; .DEF A = R16 ;WORKING REGISTER
.ORG $0000 RJMP ON_RESET;SETUP RESET VECTOR
ON_RESET: LDI A,HIGH(RAMEND);SETUP STACK OUT SPH,A ;TOP MEMORY LDI A,LOW(RAMEND);GROWS DOWN OUT SPL,A
RCALL LCD_INIT;INIT LCD
LOOP: INC A STS LCDDR0,A;ON RCALL DELAY CLR A STS LCDDR0,A;OFF RCALL DELAY RJMP LOOP
;-------------------------------------; ; INITIALIZE THE LCD SCREEN REGISTERS.; ;-------------------------------------; LCD_INIT: LDI A,(1<<LCDCS)|(3<<LCDMUX0)|(7<<LCDPM0) STS LCDCRB, A LDI A,(0<<LCDPS0)|(7<<LCDCD0);32kHz STS LCDFRR, A LDI A,(1<<LCDCC3)|(1<<LCDCC2)|(1<<LCDCC1) STS LCDCCR, A LDI A,(1<<LCDEN)|(1<<LCDAB) STS LCDCRA, A RET
;-----------------------; ; CASCADE DELAY ROUTINE.; ;-----------------------; DELAY: LDI A,4 DLUPE: DEC R0 BRNE DLUPE DEC R1 BRNE DLUPE DEC A BRNE DLUPE RET
AVR_Admin- 04-12-2006
TITLE: HOW TO BLINK A BUTTERFLY'S LCD SEGMENT
PROGRAM NAME: BLINKENDASH.ASM
PROGRAM PURPOSE:
To blink LCD Segment on Butterfly using Native AVR Machine Code.
This command tells the assembler/compiler to read in the file "m169def.inc" which contains definitions for various constants and registers for the Atmega169 chip that is used at the core of the Butterfly Board.
CODE
.DEF A = R16 ;WORKING REGISTER
We give the register we want to use a name.
CODE
.ORG $0000 RJMP ON_RESET;SETUP RESET VECTOR
ON_RESET:
We want our program to start at the beginning of Flash Memory, that's what the .ORG statment does.
On Power-Up (or Reset) the Atmega169 will jump to location $0000 so we jump from there into the first line of our program called ON-RESET.
CODE
LDI A,HIGH(RAMEND);SETUP STACK OUT SPH,A ;TOP MEMORY LDI A,LOW(RAMEND) ;GROWS DOWN OUT SPL,A
Before we can call any subroutines we need to setup a Stack to hold our return address.
RAMEND is defined in the m169def.in file we read in earlier and is a constant set to the amount of SRAM the Atmega169 chip has less one, or in other words, it indicates that last available RAM spot in our SRAM. We use this to set the 2-byte Stack Pointer SPH(high-byte) and SPL(low-byte) out of the way at the top of memory and let the stack grow "down" in memory.
CODE
RCALL LCD_INIT ;INIT LCD
This calls the subroutine LCD_INIT that initializes the LCD for writes. A suboutine is called by pushing current address on the stack that we just set-up and then jumps to the location of the routine LCD_INIT.
When the program encounters the RET at the end of the subroutine LCD_INIT it will pop this address off the stack and return to where it came from. (Actually it returns to the statement immediately after the initial call)
CODE
LOOP: INC A STS LCDDR0,A;ON RCALL DELAY CLR A STS LCDDR0,A;OFF RCALL DELAY RJMP LOOP
This is an infinite loop that writes ONE to an LCD segment, waits, then writes a ZERO, shutting it off, then waits and starts all over again.
CODE
;-------------------------------------; ; INITIALIZE THE LCD SCREEN REGISTERS; ;-------------------------------------; LCD_INIT: LDI A,(1<<LCDCS)|(3<<LCDMUX0)|(7<<LCDPM0) STS LCDCRB, A LDI A,(0<<LCDPS0)|(7<<LCDCD0);32kHz STS LCDFRR, A LDI A,(1<<LCDCC3)|(1<<LCDCC2)|(1<<LCDCC1) STS LCDCCR, A LDI A,(1<<LCDEN)|(1<<LCDAB) STS LCDCRA, A RET
This is a subroutine that initializes the LCD for use. If you want to know the details of LCD initialization, please refer to the commented version of LCD_INIT in my program "HELLO WORLD" thread in this section.
CODE
;-----------------------; ; CASCADE DELAY ROUTINE; ;-----------------------; DELAY: LDI A,4 DLUPE: DEC R0 BRNE DLUPE DEC R1 BRNE DLUPE DEC A BRNE DLUPE RET
This is my simple cascading delay routine. It does nothing but run in circles wasting time. You can adjust the amount of delay by changing the initial value of the A register: I am using 4.
AVR_Admin- 04-13-2006
TITLE: HOW TO BLINK AND LCD SEGMENT ON AVR BUTTEFLY
CONTINUING EDUCATION:
If you would like to lean more about the LCD I refer you to the 18 page PDF document AVR065 below:
Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.