; *********************************************************************** ; * * ; * LCD_8bit.asm - Routinen zur Ansteuerung eines LCD im 8bit-Modus * ; * ============ * ; * * ; * ©2004 Christoph Wagner (christophwwagner@lycos.de) * ; * * ; * Chip : ATMEGA16 / 1MHz * ; * LCD : 4x27 LCD * ; * * ; * Ports : D0..7 -> PORTA.0..7 * ; * EN1,2 -> PORTC.2,3 * ; * RS -> PORTD.7 * ; * RW -> GND * ; * * ; *********************************************************************** .def SETUP = r16 .def VALUE = r17 .def LOOP = r18 .def TEMP1 = r22 .def TEMP2 = r23 .def TEMP3 = r24 WAIT_MS: ; Wartet LOOP*1000 Zyklen ldi TEMP1,249 WAIT_MS_LOOP: nop subi TEMP1,1 brne WAIT_MS_LOOP nop subi LOOP,1 brne WAIT_MS ret WAIT_MS_WHILE: ; Wartet (LOOP-1)*1000+2 Zyklen subi LOOP,1 ; 1 Zyklus breq WAIT_MS_END ; 1 Zyklus ldi TEMP1,249 ; --- LOOP_WAIT_MS: ; | nop ; | subi TEMP1,1 ; | brne LOOP_WAIT_MS ; 996 Zyklen rjmp WAIT_MS_WHILE ; 2 Zyklen WAIT_MS_END: ret WAIT_50US: ; LOOP * 50 Zyklen ldi TEMP1,15 W50US_LOOP: subi TEMP1,1 brne W50US_LOOP nop subi LOOP,1 brne WAIT_50US ret LCD_COMMAND: cbi PORTD,7 ldi LOOP,100 ; 5ms rjmp LCD_OUT ; RS <- GND LCD_DATA: ldi LOOP,1 ; 50µs sbi PORTD,7 ; RS <- Vcc LCD_OUT: andi SETUP,0b00001111 in TEMP1,PORTC andi TEMP1,0b11111100 mov TEMP2,TEMP1 ; TEMP1,2 <- obere 6bits von PORTC or TEMP1,SETUP in TEMP3,PORTA ; LED Inhalt sichern out PORTA,VALUE ; Datenleitungen beschreiben out PORTC,TEMP1 ; Enable-Leitungen setzen nop nop nop out PORTC,TEMP2 ; Enable-Impuls out PORTA,TEMP3 ; LED Inhalt wiederherstellen call WAIT_50US ; Befehlsvollendung abwarten ret LCD_INIT_POWERUP: ;************************ Direkt nach Anschalten ldi LOOP,250 call WAIT_MS ; 250 ms Powerup LCD_INIT: ;************************ Irgendwann ldi LOOP,15 call WAIT_MS ; 15 ms warten ldi SETUP,0b00001111 ; beide Displayhälften ldi VALUE,0x30 call LCD_COMMAND call LCD_COMMAND call LCD_COMMAND ldi VALUE,0x38 ; zweizeilig Initialisieren call LCD_COMMAND ldi VALUE,0x01 ; Display löschen call LCD_COMMAND ldi VALUE,0x0E ; Display an, Cursor an call LCD_COMMAND ldi VALUE,0x80 ; Cursor auf 0 setzen call LCD_COMMAND ret ; Display initialisiert LCD_SET_CURSOR: ori VALUE,0x80 ; Cursor set Value call LCD_COMMAND ; Setup muss vom Programm eingestellt werden ret