Code:
;----------------------------------------------------------
;Anschlussbelegung mein LCD
;----------------------------------------------------------
;DB4 = PB3 = PIN11
;DB5 = PB2 = PIN12
;DB6 = PB1 = PIN13
:DB7 = PB0 = Pin14
;E = PD4 = PIN6
;RS = PD5 = PIN4
;R/W = GND = Pin5
;----------------------------------------------------------
[_Init_LCD]
;----------------------------------------------------------
;
; RW liegt auf GND da nur geschrieben wird
; D3, D2, D1, D0 liegen auf GND da nur 4 Bit-Datenlänge
; RS Low für Befehlsübertragung, High für Datenübertragung
; E Low-High-Low für Übertragungsaktivierung
;
;Anschlussbelegung LCD
; PD4 | PD5 | PB0 PB1 PB2 PB3 | PB0 PB1 PB2 PB3
; E | RS | D7 D6 D5 D4 | D3 D2 D1 D0
; | 0 | 0 0 1 0 | 0 1 0 0 | 4 Bit-Datenlänge, extension Bit RE=1
; | 0 | 0 0 0 0 | 1 0 0 1 | 4 Zeilen Modus
; | 0 | 0 0 1 0 | 0 0 0 0 | 4 Bit-Datenlänge, extension Bit RE=0
; | 0 | 0 0 0 0 | 0 1 1 0 | Entry Mode Set Cursor Auto-Increment
; | 0 | 0 0 0 0 | 0 0 0 1 | LCD Inhalt löschen und Cursor auf Home
; | 0 | 0 0 0 0 | 1 1 0 0 | Display ein, Cursor aus, Blinken aus
_Init_LCD:
rcall LCD_Delay_5ms ; 5ms LCD-Verarbeitungspause einplanen
rcall LCD_Delay_5ms ; 5ms LCD-Verarbeitungspause einplanen
rcall LCD_Delay_5ms ; 5ms LCD-Verarbeitungspause einplanen
rcall LCD_Delay_5ms ; 5ms LCD-Verarbeitungspause einplanen
sbi DDRB, 0 ; PB3 (D3/D7) als Ausgang konfigurieren
sbi DDRB, 1 ; PB2 (D2/D6) als Ausgang konfigurieren
sbi DDRB, 2 ; PB1 (D1/D5) als Ausgang konfigurieren
sbi DDRB, 3 ; PB0 (D0/D4) als Ausgang konfigurieren
sbi DDRD, 4 ; PD4 (E) als Ausgang konfigurieren
sbi DDRD, 5 ; PD5 (RS) als Ausgang konfigurieren
ldi r24, &B00100100 ; 4 Bit-Datenlänge, extension Bit
rcall _Lcd_control
ldi r24, &B00001001 ; 4 Zeilen Modus
rcall _Lcd_control
ldi r24, &B00100000 ; 4 Bit-Datenlänge, extension Bit RE=0
rcall _Lcd_control
ldi r24, &B00000110 ; Entry Mode Set Cursor Auto-Increment
rcall _Lcd_control
ldi r24, &B00001100 ; Display ein, Cursor aus, Blinken aus
rcall _Lcd_control
[END]
;----------------------------------------------------------
[_Write_lcd]
;----------------------------------------------------------
_Write_lcd:
sbi PortD, 5 ; RS High für Datenübertragung
rjmp _Write_lcd_Byte ; weiter zur Datenübertragung
_Lcd_control:
cbi PortD, 5 ; RS Low für Befehlsübertragung
_Write_lcd_Byte:
ldi r17, 8 ;Für Schleife 8 x
loop: mov r26, R24 ;Zu übertragendes Byte wird in R24 bereitgestellt und in R26
;für Bitmanipulation
andi r26, &B00000001 ;nur LSB wird ausgewertet
ror r24 ;R24 wird nach rechts verschoben
rol r25 ;R25 wird nach links verschoben
or r25, r26 ;R25 und R26 in Register R25 vereinen
Dec r17 ;-1
Brne loop ;springe zu Schleife wenn R16 > 0
mov r24, r25 ;R25 wird in R24 bereitgestellt
swap r24 ;Nibble tauschen die Daten stehen jetzt gespiegelt an PB0 - PB3!!
mov r25, r24 ; Zu übertragendes Byte wird in R24 bereitgestellt und in R25
;für die Übertragung des 2. Nibble gesichert
; H i g h Nibble muss zuerst übertragen werden
swap R24 ; Nibble tauschen
andi R24, &B00001111 ; nur die unteren 4 Bit (unteres Nibble) berücksichtigen, obere 4 Bit
;(oberes Nibble) auf Null setzen
in R23, PinB ; PortB in Register R23 einlesen (wegen PC7, PC6, PC5, PC4) diese sollen ja
;nicht überschrieben werden
andi R23, &B11110000 ; nur die oberen 4 Bit (PC7, PC6, PC5, PC4) berücksichtigen, untere 4 Bit
;(PC3, PC2, PC1, PC0) auf Null setzen
or R24, R23 ; PortB (PC7, PC6, PC5, PC4) mit LCD (PC3, PC2, PC1, PC0) in Register R24
;vereinen
out PortB, R24 ; PortB aus Register R24 setzen
rcall LCD_Write_Enable ; Übertragungsaktivierung
; L o w Nibble muss noch übertragen werden
andi R25, &B00001111 ; nur die unteren 4 Bit (unteres Nibble) berücksichtigen, obere 4 Bit
;(oberes Nibble) auf Null setzen
or R25, R23 ; PortB (PC7, PC6, PC5, PC4) mit LCD
;(PC3, PC2, PC1, PC0) in Register R25
;vereinen
out PortB, R25 ; PortB aus Register R25 setzen
rcall LCD_Write_Enable ; Übertragungsaktivierung
rcall LCD_Delay_50us ; 50us LCD-Verarbeitungspause einplanen
ret
LCD_Write_Enable:
sbi PortD, 4 ; E High Übertragungsaktivierung gestartet
nop ; 3 Taktzyklen warten
nop
nop
cbi PortD, 4 ; E Low Übertragungsaktivierung beendet
ret ; Funktionsende
LCD_Delay_5ms:
ldi R24, 255 ; R24 Register mit Delaywert 100 * 50us vorbelegen
LCD_Delay_5ms2:
rcall LCD_Delay_50us ; 50us Pause
dec R24 ; R24 Registerinhalt um 1 runterzählen
brne LCD_Delay_5ms2 ; Springe bei ungleich zurück zu LCD_Delay_5ms2
ret ; Funktionsende
LCD_Delay_50us:
ldi R25, 165 ; R25 Register mit Delaywert vorbelegen
LCD_Delay_50us2:
dec R25 ; R25 Registerinhalt um 1 runterzählen
brne LCD_Delay_50us2 ; Springe bei ungleich zurück zu LCD_Delay_50us2
ret ; 1 Takt (Befehlszyklus) bei 3,6864Mhz dauert ca. 271ns
; 50us / 271ns * 3 Takte in der Schleife = 61,5
[END]
;----------------------------------------------------------
[_CLS]
;----------------------------------------------------------
_Cls:
ldi R24, &B00000001 ; LCD Inhalt löschen und Cursor auf Home
rcall _Lcd_control ; Befehl an LCD senden
rcall LCD_Delay_5ms ; 5ms LCD-Verarbeitungspause einplanen
ret
[END]
Das ganze sieht dann als Beispiel so aus:
Code:
$regfile = "2313def.dat" 'für ATMEL AT90S2313
$crystal = 4000000 'Quarz: 4 MHz
$lib "LCD.lib"
Ddrd = &B0110000 'Pin PD5 und PD4 auf Out
Ddrb = &B00001111 'Pin PB0-PB3 auf Out
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portd.4 , Rs = Portd.5
Config Lcd = 20 * 4a ' "a" für spezielles Display
Initlcd 'Initlcd
Cls
Locate 1 , 1
Lcd "erste Zeile"
Locate 2 , 1
Lcd "zweite Zeile"
End
Ich hoffe, damit geholfen zu haben...
Lesezeichen