PDA

View Full Version : i2c interface with LED driver PCA9532



koodiifin
- 11th July 2012, 00:11
Hi everybody,
I am attempting to interface a PIC16F887 with a PCA9532 LED driver. I've read the PCA9532 datasheet http://www.nxp.com/documents/data_sheet/PCA9532.pdf and I am trying to follow the "Programming Example" on page 14. I am new to the i2c protocol and having problems receiving any response from the PCA9532. I have attached the programming example page and my test code. I will post my schematic shortly.

Any help would be greatly appreciated. Thank you very much!



'************************************************* ***************
'* Name : i2c comms test with led driver *
'* Author : Cody Finden *
'* Version : 1.0 *
'* Notes : SOFTWARE FOR A 16F887 TO WRITE TO A LED DRIVER *
'* : OVER THE I2C PROTOCOL *
'************************************************* ***************


#config
__CONFIG _CONFIG1, _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _BOR_ON & _IESO_ON & _FCMEN_ON & _LVP_OFF
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF
#endconfig


DEFINE OSC 20


ANSEL = %00000000
ANSELH = %00000000
TRISA = %00000000
TRISB = %00000000
TRISC = %00000000
TRISD = %00000000


SDA VAR PORTD.3
SCL VAR PORTD.2
led var portc.5
addr var byte


INIT:
PAUSE 400 'let hardware settle
addr = $c0 'PCA9532 i2c address


MAIN:

I2CWRITE SDA,SCL,ADDR,[$12,$97,$80,$00,$40,$55,$FA,$00,$00]

led = 1 'blink led for feedback
PAUSE 250
led = 0
pause 250


goto main

koodiifin
- 11th July 2012, 17:33
I've drawn a schematic of my test setup for reference. Let me know if anything doesn't look right. Thanks!

Dave
- 12th July 2012, 11:40
I notice the led's are drawn backwards.... It will be kind of tough to get them to light....

koodiifin
- 12th July 2012, 16:25
Lol, that's what happens when I draw a schematic in a hurry. Thanks for noticing. The leds are wired correctly on my breadboard though. I just can't get any response from the PCA9532. I've scoped the SDA and SCL pins and I can see the correct clock signal on SCL and various "data" on SDA, so I know that the PIC is outputting something. When I add the optional label argument to the i2cwrite function, the program constantly jumps to the label. Which means that I'm not receiving an acknowledge from the device. I've also tried adding "DEFINE I2C_SLOW 1" to my program because I'm running a 20MHz clock, but it did not help.

koodiifin
- 12th July 2012, 20:52
Here is my new code and a shot of my oscilloscope to show the output. I can see that I'm not getting an acknowledge, but I do not know why.



'************************************************* ***************
'* Name : i2c comms test with led driver *
'* Author : Cody Finden *
'* Version : 1.0 *
'* Notes : SOFTWARE FOR A 16F887 TO WRITE TO A LED DRIVER *
'* : OVER THE I2C PROTOCOL *
'************************************************* ***************


#config
__CONFIG _CONFIG1, _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _BOR_ON & _IESO_ON & _FCMEN_ON & _LVP_OFF
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF
#endconfig


DEFINE OSC 20


ANSEL = %00000000
ANSELH = %00000000
TRISA = %00000000
TRISB = %00000000
TRISC = %00000000
TRISD = %00000000


SDA VAR PORTD.3
SCL VAR PORTD.2
led var portc.5
addr var byte


INIT:
PAUSE 400 'let hardware settle


'PCA9532 i2c address(7 bits + 1 bit for R/W)
'Slave address is 1100(A2)(A1)(A0) + (R/W)
'In my setup A2 is pulled low, A1 pulled high, A0 pulled low
addr = %11000100


MAIN:

' I2CWRITE SDA,SCL,ADDR,[$12,$97,$80,$00,$40,$55,$FA,$00,$00]


I2CWRITE SDA,SCL,ADDR,$06,[$00] 'turn off led 0-3
led = 1 'blink led for feedback
PAUSE 250

I2CWRITE SDA,SCL,ADDR,$06,[$55] 'turn on led 0-3
led = 0
pause 250


goto main


6582

Sherbrook
- 13th July 2012, 11:45
Two things I would try.
1. Set SDA and SCL high at start
2. The PCA9532 has a reset pin so after PAUSE 400 get the PIC to reset the PCA9532

Phil

koodiifin
- 13th July 2012, 17:07
Two things I would try.
1. Set SDA and SCL high at start
2. The PCA9532 has a reset pin so after PAUSE 400 get the PIC to reset the PCA9532

Phil

Thanks for the reply! I added both of your ideas to my code, but I still cannot receive an acknowledge from the PCA9532. When I look at my scoped output and the datasheet, it looks like it should work with no problem... The address is correctly clocked out along with the R/W bit... there should be no problem. Anyways here's updated code: More advice will be greatly appreciated! Thanks.



'************************************************* ***************
'* Name : i2c comms test with led driver *
'* Author : Cody Finden *
'* Version : 1.0 *
'* Notes : SOFTWARE FOR A 16F887 TO WRITE TO A LED DRIVER *
'* : OVER THE I2C PROTOCOL *
'************************************************* ***************


#config
__CONFIG _CONFIG1, _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _BOR_ON & _IESO_ON & _FCMEN_ON & _LVP_OFF
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF
#endconfig


DEFINE OSC 20 '20MHz crystal
'DEFINE I2C_SLOW 1
'DEFINE I2C_SCLOUT 1


ANSEL = %00000000 'no analog, all digital!
ANSELH = %00000000
TRISA = %00000000 'all ports output
TRISB = %00000000
TRISC = %00000000
TRISD = %00000000


SDA VAR PORTD.3 'i2c data line
SCL VAR PORTD.2 'i2c clock line
led var portc.5 'led for testing
RST VAR portc.6 'pca9532 reset pin (active low)
addr var byte 'pca9532 address storage var


INIT:
PAUSE 400 'let hardware settle
RST = 0 'reset pca9532
pause 10
SDA = 1 'i2c pins high on startup
SCL = 1
RST = 1 'pca9532 on


'PCA9532 i2c address(7 bits + 1 bit for R/W)
'Slave address is 1100(A2)(A1)(A0) + (R/(/W))
'In my setup A2 is pulled low, A1 pulled low, A0 pulled low
addr = %11000000


MAIN:

' I2CWRITE SDA,SCL,ADDR,[$12,$97,$80,$00,$40,$55,$FA,$00,$00]


I2CWRITE SDA,SCL,ADDR,$06,[$00] 'turn off led 0-3
led = 1 'blink led for feedback
PAUSE 500

I2CWRITE SDA,SCL,ADDR,$06,[$55] 'turn on led 0-3
led = 0
pause 500


goto main

koodiifin
- 13th July 2012, 17:45
I got it working! The chip is in a SO24 package so I had to use a SMD to breadboard adapter, which was apparently faulty... Anyways there was no problem with my code, so it all works now! Thanks.

koodiifin
- 13th July 2012, 19:04
Now that I have it working I will post a simple example of utilizing the PWM features on the PCA9532. Thanks. Also added an updated (and correct schematic) for anyone that wants to test out this 16 channel PWM LED driver.



'************************************************* ***************
'* Name : i2c comms test with led driver *
'* Author : Cody Finden *
'* Version : 1.0 *
'* Notes : SOFTWARE FOR A 16F887 TO CONTROL A PCA9532 *
'* : OVER THE I2C PROTOCOL *
'************************************************* ***************


#config
__CONFIG _CONFIG1, _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _BOR_ON & _IESO_ON & _FCMEN_ON & _LVP_OFF
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF
#endconfig


'PCA9532 Control Registers
psc0 con 000010 'frequency prescaler 0 (PERIOD = (PSC0 + 1) / 152)
pwm0 con 000011 'PWM register 0 (0-255 PWM)
psc1 con 000100 'frequency prescaler 1 (PERIOD = (PSC1 + 1) / 152)
pwm1 con 000101 'PWM register 1 (0-255 PWM)
ls0 con 000110 'LED0 to LED3 selector
ls1 con 000111 'LED4 to LED7 selector
ls2 con 001000 'LED8 to LED11 selector
ls3 con 001001 'LED12 to LED15 selector


DEFINE OSC 20 '20MHz crystal
'DEFINE I2C_SLOW 1
'DEFINE I2C_SCLOUT 1


ANSEL = 000000 'no analog, all digital!
ANSELH = 000000
TRISA = 000000 'all ports output
TRISB = 000000
TRISC = 000000
TRISD = 000000


SDA VAR PORTD.3 'i2c data line
SCL VAR PORTD.2 'i2c clock line
led var portc.5 'led for testing
RST VAR portc.6 'pca9532 reset pin (active low)
addr var byte 'pca9532 address storage var
duty0 var byte
duty1 var byte


INIT:
duty0 = 0
duty1 = 255
PAUSE 400 'let hardware settle
RST = 0 'reset pca9532
pause 10
SDA = 1 'i2c pins high on startup
SCL = 1
RST = 1 'pca9532 on


'PCA9532 i2c address(7 bits + 1 bit for R/W)
'Slave address is 1100(A2)(A1)(A0) + (R/(/W))
'In my setup A2 is pulled low, A1 pulled low, A0 pulled low
addr = 000000


MAIN:

I2CWRITE SDA,SCL,ADDR,psc0,[$00] 'set both pwm prescalers to max pwm freq
I2CWRITE SDA,SCL,ADDR,psc1,[$00]

duty0 = duty0 + 1 'increment duty0 for pwm0
duty1 = duty1 - 1 'decrement duty1 for pwm1

I2CWRITE SDA,SCL,ADDR,pwm0,[duty0] 'set duty cycle on pwm0
I2CWRITE SDA,SCL,ADDR,pwm1,[duty1] 'set duty cycle on pwm1

I2CWRITE SDA,SCL,ADDR,ls0,[101010] 'enable led0-3 with pwm0
I2CWRITE SDA,SCL,ADDR,ls1,[111111] 'enable led4-7 with pwm1

if duty0=255 then 'restart count on overflow
duty0=0
endif
if duty1=0 then 'restart count on overflow
duty1=255
endif

pause 5 'delay for viewing pleasure

' led = 1 'blink led for feedback
' PAUSE 50
' led = 0
' pause 50


goto main