Depuis des jours, j’essaye de mettre en oeuvre un afficheur LCD 2x16 + module I2C (PCF9474) avec :
_ compilateur MikroBasic Pro V7.1.0
_ EasyPic5
_ PIC 18F2420 8Mhz:
_ Libstock : htps://libstock.mikroe.com/projects/dow ... .0.0.0.zip dont code ci-dessous
J’ai adapté l’adresse du module I2C à $27
La compilation ne génère pas d’erreur et pourtant je n’arrive pas à faire fonctionner.
Qui peux m’aider à trouver une solution à mon problème ou m’indiquer un autre code en Mikrobasic qui fonctionne.
Code : Tout sélectionner
program I2C_LCD
' Declarations section
symbol _LCD_FIRST_ROW = $80 'Move cursor to the 1st row
symbol _LCD_SECOND_ROW = $C0 'Move cursor to the 2nd row
symbol _LCD_THIRD_ROW = $94 'Move cursor to the 3rd row
symbol _LCD_FOURTH_ROW = $D4 'Move cursor to the 4th row
symbol _LCD_CLEAR = $01 'Clear display
symbol _LCD_RETURN_HOME = $02 'Return cursor to home position, returns a shifted display to
'its original position. Display data RAM is unaffected.
symbol _LCD_CURSOR_OFF = $0C 'Turn off cursor
symbol _LCD_UNDERLINE_ON = $0E 'Underline cursor on
symbol _LCD_BLINK_CURSOR_ON = $0F 'Blink cursor on
symbol _LCD_MOVE_CURSOR_LEFT = $10 'Move cursor left without changing display data RAM
symbol _LCD_MOVE_CURSOR_RIGHT = $14 'Move cursor right without changing display data RAM
symbol _LCD_TURN_ON = $0C 'Turn Lcd display on
symbol _LCD_TURN_OFF = $08 'Turn Lcd display off
symbol _LCD_SHIFT_LEFT = $18 'Shift display left without changing display data RAM
symbol _LCD_SHIFT_RIGHT = $1E 'Shift display right without changing display data RAM
' LCD Definitions
symbol LCD_ADDR = $27 'Mod. $4E
' Lcd constants
Dim txt1 as string[10]
Dim txt2 as string[20]
Dim txt3 as string[10]
Dim txt4 as string[10]
sub procedure I2C_LCD_Cmd(Dim out_char as byte)
Dim hi_n, lo_n as byte
Dim rs as byte
rs = 0
hi_n = out_char and $F0
lo_n = (out_char << 4) and $F0
I2C1_Start()
I2C1_Is_Idle()
I2C1_Wr(LCD_ADDR)
I2C1_Is_Idle()
I2C1_Wr(hi_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(hi_n or rs or $00 or $08)
I2C1_Is_Idle()
Delay_us(100)
I2C1_Wr(lo_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(lo_n or rs or $00 or $08)
I2C1_Is_Idle()
I2C1_stop()
if(out_char = $01) then
Delay_ms(2)
end if
end sub
sub procedure I2C_LCD_Chr(Dim row as byte, Dim column as byte, Dim out_char as byte)
Dim hi_n, lo_n as byte
Dim rs as byte
rs = 1
select case (row)
case 1
I2C_LCD_Cmd($80 + (column - 1))
case 2
I2C_LCD_Cmd($C0 + (column - 1))
case 3
I2C_LCD_Cmd($94 + (column - 1))
case 4
I2C_LCD_Cmd($D4 + (column - 1))
end select
hi_n = out_char and $F0
lo_n = (out_char << 4) and $F0
I2C1_Start()
I2C1_Is_Idle()
I2C1_Wr(LCD_ADDR)
I2C1_Is_Idle()
I2C1_Wr(hi_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(hi_n or rs or $00 or $08)
I2C1_Is_Idle()
Delay_us(100)
I2C1_Wr(lo_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(lo_n or rs or $00 or $08)
I2C1_Is_Idle()
I2C1_stop()
end sub
sub procedure I2C_LCD_Chr_Cp(Dim out_char as byte)
Dim hi_n, lo_n as byte
Dim rs as byte
rs = $01
hi_n = out_char and $F0
lo_n = (out_char << 4) and $F0
I2C1_Start()
I2C1_Is_Idle()
I2C1_Wr(LCD_ADDR)
I2C1_Is_Idle()
I2C1_Wr(hi_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(hi_n or rs or $00 or $08)
I2C1_Is_Idle()
Delay_us(100)
I2C1_Wr(lo_n or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr(lo_n or rs or $00 or $08)
I2C1_Is_Idle()
I2C1_stop()
end sub
sub procedure I2C_LCD_Init()
Dim rs as byte
I2C1_Start()
I2C1_Is_Idle()
I2C1_Wr(LCD_ADDR)
I2C1_Is_Idle()
Delay_ms(30)
I2C1_Wr($30 or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr($30 or rs or $00 or $08)
I2C1_Is_Idle()
Delay_ms(10)
I2C1_Wr($30 or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr($30 or rs or $00 or $08)
I2C1_Is_Idle()
Delay_ms(10)
I2C1_Wr($30 or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr($30 or rs or $00 or $08)
I2C1_Is_Idle()
Delay_ms(10)
I2C1_Wr($20 or rs or $04 or $08)
I2C1_Is_Idle()
Delay_us(50)
I2C1_Wr($20 or rs or $00 or $08)
I2C1_Is_Idle()
I2C1_Stop()
Delay_ms(10)
I2C_LCD_Cmd($28)
I2C_LCD_Cmd($06)
end sub
sub procedure I2C_LCD_Out(Dim row as byte, Dim column as byte, Dim byref text as string)
Dim i as byte
for i = 0 to Strlen(text) - 1
I2C_LCD_Chr(row, column, text[i])
column = column + 1
next i
end sub
sub procedure I2C_LCD_Out_Cp(dim byref text as string)
Dim i as byte
for i = 0 to Strlen(text) - 1
I2C_LCD_Chr_Cp(text[i])
next i
end sub
main:
' Main program
ADCON1 = $0F 'Mod. ANSELA = $00
TRISA = $00
PORTA = $00
LATA = $00
txt1 = "I2C LCD"
txt2 = "16x2, 20x2, 20x4"
txt3 = "PIC12F1840"
txt4 = "4 MHz"
I2C1_Init(100000)
I2C_LCD_Init()
I2C_LCD_Cmd(_LCD_CURSOR_OFF)
I2C_LCD_Cmd(_LCD_CLEAR)
I2C_Lcd_Out(1,1,txt1) ' Write text in first row
I2C_Lcd_Out(2,1,txt2) ' Write text in second row
I2C_Lcd_Out(3,1,txt3) ' Write text in third row
I2C_Lcd_Out(4,1,txt4) ' Write text in fourth row
while(TRUE)
Wend
end.