Jump to content
ELFORUM - Forumul electronistilor
mariuss_suciu

LCD 2x16 conectat la uC prin i2c PCF9574A

Recommended Posts

Salutare,

 

Ma lupt de cateva zile cu simularea unui LCD conectat la Atmega328 prin interfata i2c, folosind un modul cu PCF8574A, insa nu reusesc sa afisez nimic pe Display.

 

M-am orientat dupa modele scrise de altii care functioneaza (http://electronics598.rssing.com/browser.php?indx=8435866&item=5615) , insa la mine nu vrea nici cum in simulator si nu imi dau seama de ce. Programul este scris in BASCOM, si simularea o rulez in Proteus 8.1.

$regfile = "m328def.dat"$crystal = 8000000$hwstack = 40$swstack = 16$framesize = 32$baud = 9600$lib "i2c_twi.lib"$lib "bl_lcd_i2c.lib"Config Twi = 100000Config I2cdelay = 10Const Pcf_d4 = 4Const Pcf_d5 = 5Const Pcf_d6 = 6Const Pcf_d7 = 7Const Pcf_rs = 0Const Pcf_rw = 1Const Pcf_e1 = 2Declare Sub I2c_scanDim A As ByteDim B As ByteDim _lcd_e As ByteDim Backlight as ByteBacklight = &H08_lcd_e = 128Config Scl = Portc.5Config Sda = Portc.4I2cinitConst Pcf8574_lcd = &H70Call I2c_scanWait 2ClsHomeLcd "Salut"Print "Salut"DoLoopSub I2c_scanPrint "Scan start"For B = 0 To 254 Step 2   I2cstart   I2cwbyte B   If Err = 0 Then      Print "Slave at : " ; B ; " hex : " ; Hex(b) ; " bin : " ; Bin(b)   End If   I2cstopNextPrint "End Scan"End Sub

Rutina de scanare pe i2c functioneaza, si detecteaza IC-ul PCF8574A la adresa &H70 (conform cu datasheet).

 

post-224932-0-42653400-1455699159_thumb.jpg

 

uC pare sa functioneze pentru ca pe serial vad mesajul "Salut"...iar libraria am downloadat-o si am pus-o in folderul cu librarii din bascom...

 

 

Aveti vreo idee unde as fi gresit ? Sau sa existe vreo problema in simularea acestuia ? Urmeaza sa testez pe placa de dezvoltare acest montaj daca nu reusesc nicicum in simulare.

 

 

 

Marius.

Edited by mariuss_suciu

Share this post


Link to post
Share on other sites

pune si pe iesirile pcf-ului rezistente catre vcc

 

LE: nu cred ca va avea influenta, am zis o prostie

Edited by costi002

Share this post


Link to post
Share on other sites

PCF8574 are trei pini A0,A1,A2 pentru configurarea adresei, trebuie sa-i configurezi in asa fel incat adresa PCF sa fie la fel cum e definita in codul scris de tine.

Share this post


Link to post
Share on other sites

Asa este, se vede si in cod ca aceasta este setata...mai mult de atata, in rutina de scanare pe i2c , PCF8574 este detectat la adresa respectiva &H70.

 

Inca ma gandesc sa existe vreo problema de incompatibilitate intre Proteus si uC/Display/Soft .... habar n-am...

Share this post


Link to post
Share on other sites

incearca si cu adresa H38. nu ai nimic de pierdut. se intampla cateodata ca adresa sa fie shift-ata spre stanga la scanare

Share this post


Link to post
Share on other sites

Eu m-am uitat in datasheet-ul celor de la NXP care zice altceva: http://www.nxp.com/documents/data_sheet/PCF8574.pdf

 

In functie de cum setez jumperii de la A0-A2, rutina de i2c_scan il detecteaza la adresa respectiva , iar conform cu datasheet-ul, adresa i2c este sub urmatoarea forma:

0 | 1 | 1 | 1 | A2 | A1 | A0 | 0

 

Banuiesc ca am setat corect adresa i2c: 0x70

 

p.s. Folosesc PCF8574A , am uitat mai sus sa precizez lucrul asta, insa problema nu se schimba cu nimic. 

Share this post


Link to post
Share on other sites

Depinde cum foloseste bascom (cum e implementata in biblioteca folosita) adresa.

Daca functiile din biblioteca vor adresa completa, care include si codul pentru operatii, atunci trebuie sa folosesti 0x70 pentru scriere si 0x71 pentru citire (&H70 si &H71 in basic).

Daca functiile din biblioteca vor adresa efectiva, urmand sa adauge ele codul pentru operatii, atunci adresa e 0x38 (&H38). In cazul asta functiile se ocupa de shiftarea adresei primite ca parametru (&H38 shift left 1 = &H70) si adaugarea bitului de operatie.

Edited by Liviu M

Share this post


Link to post
Share on other sites

Am incercat o secventa sa vad daca pot transmite ceva la PCF8574A:

wait 2i2cstarti2cwbyte &H70   'trimit adresa i2c a lui PCF8574Ai2cwbyte &HAA   'pun iesirile in P0 -> P7    01010101i2cstop

Intradevar, dupa wait-ul de 2 secunde, starea pinilor de iesire se modifica din starea de 11111111 -> 01010101. Presupun ca e corecta adresa &H70.

 

Credeti ca libraria nu este compatibila cu display-ul ? Desi am selectat un display 16 * 2 caractere, la descrierea acestuia este trecut LM032L. Am testat acest display conectat direct la microcontroller si a functionat normal (RS, E, D4, D5, D6, D7)...

Edited by mariuss_suciu

Share this post


Link to post
Share on other sites

Incearca sa muti 

Const Pcf8574_lcd = &H70

inainte de initializare. Adica sa ai asa:

_lcd_e = 128Const Pcf8574_lcd = &H70Config Scl = Portc.5Config Sda = Portc.4I2cinit

Share this post


Link to post
Share on other sites

Intre timp am gasit o librarie care imi functioneaza in simulare corect.

 

Codul sursa folosit pentru testare:

$regfile = "m328def.dat"$crystal = 8000000$hwstack = 40$swstack = 16$framesize = 32'-----------------------------------------------------------------------------------------'$lib "i2c_twi.lbx"                                          ' uncomment this for hardware I2C$lib "i2c_lcd_suggestion.lib"Dim _lcd_e As ByteDim _backlight As ByteConfig Scl = Portc.5                                        ' I2c SclConfig Sda = Portc.4                                        ' I2c SdaConst Pcf8574_lcd = &H70                                    ' PCF8574 address'-------------------------------------------------------------------------------'------------------------------------------------------------------'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |'|-------------|----------------------------|----------------------|'|  A0  A1  A2 |     Write   |     Read     |    Write  |   Read   |'|-------------|-------------|--------------|-----------|----------|'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |'------------------------------------------------------------------'-------------------------------------------------------------------------------' Config pins:Const Pcf_rs = 0Const Pcf_bl = 1Const Pcf_e1 = 2Const Pcf_e2 = 3Const Pcf_d4 = 4Const Pcf_d5 = 5Const Pcf_d6 = 6Const Pcf_d7 = 7_lcd_e = 192                                                ' 64=E2 (3 & 4 stering) 128=E1 (1 & 2 string) 192=E1+E2 (all 4 strings)_backlight = 0                                              'initial Backlight state'-------------------------------------------------------------------------------InitlcdDo    _lcd_e = 192    Cls    Waitms 100    _lcd_e = 128    Locate 1 , 1    Lcd "Linia 1"    Waitms 200    Locate 2 , 1    Lcd "Linia 2"    Waitms 200LoopEnd

Si codul sursa a librariei (nu am putut-o atasa, desi i-am schimbat extensia in .jpg .

copyright = Kent Anderssonwww       = noneemail     = [email protected]   = I2C LCD driverlibversion   = 3.04date         = 31 march 2002 / Updated by Mshilov 29 july 2013statement    = You are free to use this code any way you like, if you are able to optimizestatement    = 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 - Backlight;P6 - E2 (on 1 or 2 line display nc);P7 - E1;; EDIT 07.01.2011 according an Hint from MagicWhiteSmoke of bascom-forum.de; now you can define the PINs used using constants like this:; Const Pcf_d4 = 4; Const Pcf_d5 = 5; Const Pcf_d6 = 6; Const Pcf_d7 = 7; Const Pcf_rs = 0; Const Pcf_bl = 1  - this is backlight pin ; Const Pcf_e2 = 3; Const Pcf_e1 = 2;;Backlight pin switched on or off with every Display command (like Display on);NOTE! At power on, all I/Os of PCF8574 are high, therefore better connect Backlight from Vcc to P5 pin. ;In this case Backlight will be OFF at power on. But command _backlight=0 will mean ON and vice versa.[_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 _Write_lcd_nibble *BASIC: waitms 4 Rcall _Write_lcd_nibble Rcall _Write_lcd_nibble Ldi _temp1, &h02 Rcall _Write_lcd_nibble Ldi _temp1, &h28 Rcall _Lcd_Control  ;RS flag should to be 0, so jump directly to write byte Ldi _temp1, &h06 Rcall _Lcd_Control Ldi _temp1, &h0c Rcall _Lcd_Control Ldi _temp1, &h01 Rjmp _Lcd_Control[END][_Write_lcd]_Write_lcd:	*lds r16,{_lcd_e}		; Packe den Inhalt von der Speicheradresse der Variable _lcd_e in Register 16 	ldi r25,&h10			; ;set RS flag (4 high bits is used as control)	rjmp _write_lcd_byte		; Springe zu _write_lcd_byte_Lcd_Control:	*lds r16,{_lcd_e} 		; Packe den Inhalt von der Speicheradresse der Variable _lcd_e in Register 16 	ldi r25,&h00	_write_lcd_byte:	push r24			; Register 24 ab auf den Stack	Swap _temp1                     ; in _temp1 die oberen 4 mit den unteren 4 Bit tauschen         Rcall _Write_lcd_Nibble 	; Rufe _Write_lcd_Nibble auf	pop r24        			; Register 24 wieder vom Stack zur?ck_Write_lcd_nibble:	Cbr _temp1,&HF0			;  E1, E2, RW, RS low	eor _temp1,r25			; set RS_Send_to_LCD:push r26			; Register 26 ab auf den Stack push r27			; Register 27 ab auf den Stack	  mov r26,_temp1	BST  r26, 0			; Bit0 aus _temp1 ins T-Bit	*BLD  _temp1, PCF_D4		; Das T-Bit wird in _temp2 an Position PCD_D4 geschrieben  	BST  r26, 1			; Bit1 aus _temp1 ins T-Bit	*BLD  _temp1, PCF_D5		; Das T-Bit wird in _temp2 an Position PCD_D5 geschrieben	BST  r26, 2			; Bit2 aus _temp1 ins T-Bit	*BLD  _temp1, PCF_D6		; Das T-Bit wird in _temp2 an Position PCD_D6 geschrieben	BST  r26, 3			; Bit3 aus _temp1 ins T-Bit	*BLD  _temp1, PCF_D7		; Das T-Bit wird in _temp2 an Position PCD_D7 geschrieben	BST  r26, 4			; Bit4 aus _temp1 ins T-Bit	*BLD  _temp1, PCF_RS		; Das T-Bit wird in _temp2 an Position PCD_RS geschrieben	*lds r26,{_backlight}  		; read backlight state	bst r26, 0   				; save it state in T register	*bld _temp1, PCF_BL  		; copy state to register	set	*BLD  _temp1, PCF_E2		; set E2	*BLD  _temp1, PCF_E1		; set E1	ldi r26, &H00	bst r16, 6	*bld r26, PCF_E2	bst r16, 7	*bld r26, PCF_E1_i2c_send_to_lcd: *BASIC: i2cstart *BASIC: I2cwbyte pcf8574_lcd *BASIC: I2cwbyte _temp1 eor _temp1, r26 @genus(250)  *BASIC: I2cwbyte _temp1 eor _temp1, r26 @genus(250)  *BASIC: I2cwbyte _temp1 *BASIC: i2cstop  @genus(250) eor _temp1, r26pop r27				pop r26				ret						[END]
Edited by mariuss_suciu

Share this post


Link to post
Share on other sites

Salutare,

 

Revin cu alta intrebare. Intentionez sa dezvolt montajul de mai sus si sa conectez in prima faza 8 display-e pe bus-ul i2c (fiecare cu adresa lui), si pe fiecare voi afisa alte informatii.

Problema de care m-am lovit este ca nu reusesc sa imi dau seama cum as putea scrie aceasta parte de cod, deoarece am incercat sa modific linia in care este definita adresa de i2c:

Const Pcf8574_lcd = &h70

in declararea unei variabile pe care o voi egala cu "pcf8574_lcd", si anume:

Dim addr as byteaddr = &h70Pcf8574_lcd = addr...Locate 1 , 1LCD "Display 1"...addr = &h72Pcf8574_lcd = addr...locate 1 , 1LCD " Display 2"...

Problema apare inclusiv daca modific doar din constanta in variabila, chiar daca are aceeasi valoare, codul nu mai functioneaza.

 

Spuneti-mi va rog ce anume imi scapa....sau ce solutii as mai avea?

 

Multumesc.

 

 

p.s. proiectul final va afisa pe 20 display-e (daca va functiona) folosind un mux pt i2c PCA9544.

Share this post


Link to post
Share on other sites

Incearca asa 

Dim A As Byte Const A1 = &H70Const A2 = alta adresaConst Pcf8574_lcd = A1
Edited by Elison

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines