.set lcd_port=PortD .set lcd_pin=PinD .set lcd_ddr=DDRD .equ lcd_rs=4 .equ lcd_en=5 .equ lcd_rw=6 .equ lcd_waitmax=AVRTakt*1600/23 ;Kann auch höher gesetzt werden. lcd_busy: push r24 ;Wenn die Register r24 und r25 nicht vom Call benutzt werden push r25 ;können die beiden Push-Befehle raus. ldi r24,0xf0 ;LCD_Datenrichtung 7:4 = Ausgang, 3:0 = Eingang. out lcd_ddr,r24 cbi lcd_port,lcd_rs ;RS low (4) zum lesen des Busy-Flag. sbi lcd_port,lcd_rw ;R/W high zum lesen vom LCD. ldi r24,low(lcd_waitmax) ;Maximale Zeit (1,5ms) als Notausgang falls Busy nicht low wird. ldi r25,high(lcd_waitmax) lcd_busy1: sbi lcd_port,lcd_en ;Enable high für erstes Nibble. rcall lcd_busy_Wait ;7 Takte Blödsinn zum warten bis das LCD die Daten anlegt. set ;Internes Busy-(T)Flag setzen. sbis lcd_pin,3 ;Ist Busy gesetzt dann T-Bit gesetzt lassen. clt ;T-Bit löschen wenn Busy gelöscht ist. cbi lcd_port,lcd_en ;Enable wieder low für erstes Nibble. sbi lcd_port,lcd_en ;Enable high für zweites Nibble. cbi lcd_port,lcd_en ;Enable wieder low für zweites Nibble. sbiw r24,1 breq lcd_busy2 brts lcd_busy1 ;Wenn Busy gesetzt, dann die Abfrage wiederholen lcd_busy2: ldi r24,0xff ;Port D zurückstellen auf Ausgang out lcd_ddr,r24 pop r25 ;Wenn die Register r24 und r25 nicht vom Call benutzt werden pop r24 ;können die beiden Pop-Befehle raus. lcd_busy_Wait: ret