copyright = Kent Andersson www = none email = kent@smmab.se comment = I2C LCD driver libversion = 1.02 date = 31 march 2002 statement = You are free to use this code any way you like, if you are able to optimize statement = it better, please send me an update on my e-mail. history = No known bugs. ;define a constant named PCF8574_LCD pointing to the i2c address ;dimension _lcd_e as byte to control the E-lines (4 lines LCD:s) ;_lcd_e should have one of the following values ;128 to enable E1, 64 to enable E2, 192 to enable both E1 and E2 (cls, deflcdchar) ;Connect the following pins from PCF8574 to LCD ; ;P0 - D4 ;P1 - D5 ;P2 - D6 ;P3 - D7 ;P4 - RS ;P5 - RW (not used, set to 0 to ground for write) ;P6 - E2 (on 1 or 2 line display nc) ;P7 - E1 [_Init_LCD] _Init_LCD: *BASIC: waitms 50 ldi r16,&hc0 ; this is to make the initialization on both halfs of a 4-line LCD Ldi _temp1, &h03 ; at init-time I call all routines before _lcd_e is loaded into r16 Rcall _Send_to_LCD *BASIC: waitms 4 Rcall _Send_to_LCD Rcall _Send_to_LCD Ldi _temp1, &h02 Rcall _Send_to_LCD Ldi _temp1, &h28 Rcall _Write_lcd_byte ;RS flag should to be 0, so jump directly to write byte Ldi _temp1, &h08 Rcall _Write_lcd_byte Ldi _temp1, &h0c Rcall _Write_lcd_byte Ldi _temp1, &h01 Rjmp _Write_lcd_byte [END] [_Write_lcd] _Write_lcd: * lds r16,{_lcd_e} sbr r16,&h10 ;set RS flag (4 high bits is used as control) rjmp _write_lcd_byte _Lcd_Control: * lds r16,{_lcd_e} _write_lcd_byte: push r24 Swap _temp1 Rcall _Write_lcd_Nibble pop r24 _Write_lcd_nibble: Cbr _temp1,&HF0 ; E1, E2, RW, RS low _Send_to_LCD: push r26 push r27 ldi r25,3 _send_3_times: PUSH _temp2 BST _temp1, 0 * BLD _temp2, PCF_D4 BST _temp1, 1 * BLD _temp2, PCF_D5 BST _temp1, 2 * BLD _temp2, PCF_D6 BST _temp1, 3 * BLD _temp2, PCF_D7 BST _temp1, 4 * BLD _temp2, PCF_RS BST _temp1, 5 * BLD _temp2, PCF_RW BST _temp1, 6 * BLD _temp2, PCF_E2 BST _temp1, 7 * BLD _temp2, PCF_E1 *BASIC: i2csend pcf8574_LCD, _temp2 POP _temp2 eor _temp1,R16 ; Xor E1 and/or E2 to set them ; @genus(250) ldi r26,0 _LCD_delay: dec R26 brne _LCD_delay Dec R25 Brne _send_3_times eor _temp1,R16 ; Xor to restore to initial state (even number of times) pop r27 pop r26 ret [END]