.include "2313def.inc"
.def temp0 = r16
.def temp1 = r17
.def temp2 = r18
.def temp3 = r19
.def COU_HI= r20
.def COU_LO= r21
.CSEG
.ORG 0
rjmp RESET
.org INT0addr
rjmp ECHO
RESET:
ldi temp0,RAMEND ;Locate stack
out SPL,temp0
ldi temp1, 0x00000001 ;Pin D0 = выход (сюда тестовый светодиод подключить, будет мигать. но не обязательно : ) )
out DDRD, temp1
ldi temp1, 0xFF ;Port B = выход
out DDRB, temp1
nop
nop
nop
nop
nop
nop
sbi PORTD,1
rcall DELAYSEK
cbi PORTD,1
rcall DELAYSEK
rcall lcd_init ;Display initialisieren
rcall lcd_clear ;Display стереть
ldi temp1, 'P' ;знак/букву вывести
rcall lcd_data
ldi temp1, 'r' ;знак/букву вывести
rcall lcd_data
ldi temp1, 'i' ;знак/букву вывест
rcall lcd_data
ldi temp1, 'v' ;знак/букву вывести
rcall lcd_data
ldi temp1, 'e' ;знак/букву вывести
rcall lcd_data
ldi temp1, 't' ;знак/букву вывести
rcall lcd_data
ldi temp1, ' ' ;знак/букву вывести
rcall lcd_data
ldi temp1, 0xA3 ;знак/букву вывести (можно и так в шестнадцатиричном коде. коды берутся из таблицы твоего ЖКИ модуля)
rcall lcd_data
loop: ; а тут просто мигаем светодиодом. надпись на экране уже стоит.
sbi PORTD,1
rcall DELAYSEK
cbi PORTD,1
rcall DELAYSEK
rjmp loop
DELAYSEK:
; -----------------------------
; delaying 1999998 cycles:
ldi R25, $12
WGLOOP0A: ldi R23, $BC
WGLOOP1A: ldi R24, $C4
WGLOOP2A: dec R24
brne WGLOOP2A
dec R23
brne WGLOOP1A
dec R25
brne WGLOOP0A
; -----------------------------
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; LCD-Routinen ;;
;; ============ ;;
;; (c)andreas-s@web.de ;;
;; ;;
;; 4bit-Interface ;;
;; DB4-DB7: PD0-PD3 ;;
;; RS: PD4 ;;
;; E: PD5 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;sendet ein Datenbyte an das LCD
lcd_data:
mov temp2, temp1 ;"Sicherungskopie" für
;die Übertragung des 2.Nibbles
swap temp1 ;Vertauschen
andi temp1, 0b00001111 ;oberes Nibble auf Null setzen
sbr temp1, 1<<4 ;entspricht 0b00010000
out PORTB, temp1 ;ausgeben
rcall lcd_enable ;Enable-Routine aufrufen
;2. Nibble, kein swap da es schon
;an der richtigen stelle ist
andi temp2, 0b00001111 ;obere Hälfte auf Null setzen
sbr temp2, 1<<4 ;entspricht 0b00010000
out PORTB, temp2 ;ausgeben
rcall lcd_enable ;Enable-Routine aufrufen
rcall delay50us ;Delay-Routine aufrufen
ret ;zurück zum Hauptprogramm
;sendet einen Befehl an das LCD
lcd_command: ;wie lcd_data, nur ohne RS zu setzen
mov temp2, temp1
swap temp1
andi temp1, 0b00001111
out PORTB, temp1
rcall lcd_enable
andi temp2, 0b00001111
out PORTB, temp2
rcall lcd_enable
rcall delay50us
ret
;erzeugt den Enable-Puls
lcd_enable:
sbi PORTB, 5 ;Enable high
rcall delay50us
cbi PORTB, 5 ;Enable wieder low
ret ;Und wieder zurück
;Pause nach jeder Übertragung
delay50us: ;50us Pause
; =============================
; delay loop generator
; -----------------------------
; delaying 48 cycles:
ldi temp1, $11
WGLOOP0: dec temp1
brne WGLOOP0
; -----------------------------
; =============================
ret ;wieder zurück
;Längere Pause für manche Befehle
delay5ms: ;5ms Pause
;ret ; !!!!!!!
; =============================
; delay loop generator
; -----------------------------
; delaying 49995 cycles:
ldi temp1, $65
WGLOOP0C: ldi temp2, $A4
WGLOOP1C: dec temp2
brne WGLOOP1C
dec temp1
brne WGLOOP0C
; -----------------------------
; delaying 6 cycles:
ldi temp1, $02
WGLOOP2C: dec temp1
brne WGLOOP2C
; =============================
ret ;wieder zurück
;Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
lcd_init:
ldi temp3,50
powerupwait:
rcall delay5ms
dec temp3
brne powerupwait
ldi temp1, 0b00000011 ;muss 3mal hintereinander gesendet
out PORTB, temp1 ;werden zur Initialisierung
rcall lcd_enable ;1
rcall delay5ms
rcall lcd_enable ;2
rcall delay5ms
rcall lcd_enable ;und 3!
rcall delay5ms
ldi temp1, 0b00000010 ;4bit-Modus einstellen
out PORTB, temp1
rcall lcd_enable
rcall delay5ms
ldi temp1, 0b00101000 ;noch was einstellen...
rcall lcd_command
ldi temp1, 0b00001100 ;...nochwas...
rcall lcd_command
ldi temp1, 0b00000100 ;endlich fertig
rcall lcd_command
ret
;Sendet den Befehl zur Löschung des Displays
lcd_clear:
ldi temp1, 0b00000001 ;Display löschen
rcall lcd_command
rcall delay5ms
ret
ECHO:
cli ; disable global interrupts
ldi temp0,0b00000000 ; Timer 1 -> STOP!
out TCCR1B,temp0 ; Timer 1 -> STOP!
nop
nop
nop
reti