.include "m2560def.inc"
.macro do_lcd_command
ldi r16, @0
rcall lcd_command
rcall lcd_wait
.endmacro
.macro do_lcd_data
ldi r16, @0
rcall lcd_data
rcall lcd_wait
.endmacro
.org 0
jmp RESET
RESET:
ldi r16, low(RAMEND)
out SPL, r16
ldi r16, high(RAMEND)
out SPH, r16
ser r16
out DDRF, r16
out DDRA, r16
clr r16
out PORTF, r16
out PORTA, r16
do_lcd_command 0b00111000 ; 2x5x7
rcall sleep_5ms
do_lcd_command 0b00111000 ; 2x5x7
rcall sleep_1ms
do_lcd_command 0b00111000 ; 2x5x7
do_lcd_command 0b00111000 ; 2x5x7
do_lcd_command 0b00001000 ; display off?
do_lcd_command 0b00000001 ; clear display
do_lcd_command 0b00000110 ; increment, no display shift
do_lcd_command 0b00001110 ; Cursor on, bar, no blink
do_lcd_data 'H'
do_lcd_data 'e'
do_lcd_data 'l'
do_lcd_data 'l'
do_lcd_data 'o'
halt:
rjmp halt
.equ LCD_RS = 7
.equ LCD_E = 6
.equ LCD_RW = 5
.equ LCD_BE = 4
.macro lcd_set
sbi PORTA, @0
.endmacro
.macro lcd_clr
cbi PORTA, @0
.endmacro
;
; Send a command to the LCD (r16)
;
lcd_command:
out PORTF, r16
rcall sleep_1ms
lcd_set LCD_E
rcall sleep_1ms
lcd_clr LCD_E
rcall sleep_1ms
ret
lcd_data:
out PORTF, r16
lcd_set LCD_RS
rcall sleep_1ms
lcd_set LCD_E
rcall sleep_1ms
lcd_clr LCD_E
rcall sleep_1ms
lcd_clr LCD_RS
ret
lcd_wait:
push r16
clr r16
out DDRF, r16
out PORTF, r16
lcd_set LCD_RW
lcd_wait_loop:
rcall sleep_1ms
lcd_set LCD_E
rcall sleep_1ms
in r16, PINF
lcd_clr LCD_E
sbrc r16, 7
rjmp lcd_wait_loop
lcd_clr LCD_RW
ser r16
out DDRF, r16
pop r16
ret
.equ F_CPU = 16000000
.equ DELAY_1MS = F_CPU / 4 / 1000 - 4
; 4 cycles per iteration - setup/call-return overhead
sleep_1ms:
push r24
push r25
ldi r25, high(DELAY_1MS)
ldi r24, low(DELAY_1MS)
delayloop_1ms:
sbiw r25:r24, 1
brne delayloop_1ms
pop r25
pop r24
ret
sleep_5ms:
rcall sleep_1ms
rcall sleep_1ms
rcall sleep_1ms
rcall sleep_1ms
rcall sleep_1ms
ret
Resource created Wednesday 11 March 2020, 10:18:22 AM, last modified Thursday 02 April 2020, 10:59:01 PM.
file: lcd_example.asm