PIC16F724 communication with PCA9622 using I2C

Discussion in 'Embedded Systems and Microcontrollers' started by nic6911, Jun 22, 2012.

  1. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    Hi all.
    I have recieved a circuitboard that i have to program to do some simple stuff. The only problem is that i have very little experience in C. I am used to programming PLC's in ladder.

    The board has 30 led's that are connected with two PCA9622 chips controlled by the PIC. There are 17 inputs and two outputs on the board. The first 15 led's are green and the last 15 are yellow.
    LED1 and LED16 are combined in one, LED2 and 17 are combined and so on..

    The function should be this:
    If input 1 gets high led1 or led16 goes on, if in2 gets high led2 or led17 goes on and so on. So i should be able to chose if it is the green or the yellow led that is lit whenever input x is high.
    If input 16 goes high all yellow led's should be lit to see if they work.

    The two outputs should be set high if certain led's are on. I should be able to write which led's would set one of the outputs high.

    That is basically it.

    I have read through the datasheet of the PCA9622 and also the PIC. I have programmed this type of PIC before to drive som led´s, but not through i2c.

    I am very confused on how to deal with this.
    I have some code, but i am not sure how to do this. The first thing is to be able to turn on the led's individually.

    So far i have understood this is how it goes:
    Start
    1. adress of slave (PCA9622)
    2. go to mode 1 register (don't know why, but that is what i get from the datasheet)
    3. ReStart
    4. adress of slave again
    5. and know i am lost?!? :S
    Code ( (Unknown Language)):
    1. #include    <htc.h>
    2.  
    3. #define _XTAL_FREQ 16000000
    4.  
    5.  
    6. #define SCL     RC3 // I2C bus
    7. #define SDA     RC4 //
    8.  
    9.  
    10. #define green 0x14;
    11. #define red 0x15;
    12.  
    13.  
    14. void i2c_dly(void)
    15. {
    16. }
    17.  
    18.  
    19. void i2c_start(void)
    20. {
    21.   SDA = 1;             // i2c start bit sequence
    22.   i2c_dly();
    23.   SCL = 1;
    24.   i2c_dly();
    25.   SDA = 0;
    26.   i2c_dly();
    27.   SCL = 0;
    28.   i2c_dly();
    29. }
    30.  
    31.  
    32. void i2c_stop(void)
    33. {
    34.   SDA = 0;             // i2c stop bit sequence
    35.   i2c_dly();
    36.   SCL = 1;
    37.   i2c_dly();
    38.   SDA = 1;
    39.   i2c_dly();
    40. }
    41.  
    42.  
    43.  
    44.  
    45. main(void){
    46. i2c_start();              // send start sequence
    47. SDA = green;            //adress for the green led driver
    48. SDA = 0x00;             //Mode 1 register
    49. _delay_us(600);
    50. i2c_start();            //restart
    51. SDA = green;            //adress for the green led driver
    52. SDA = 0x14;
    53.  
    54.  
    55. i2c_stop();               // send stop sequence
    56.  
    57.  
    58. }
    I have a schematic for the board attached to the thread.

    But the datasheet for PCA9622 is here
    http://www.nxp.com/documents/data_sheet/PCA9622.pdf

    Any help for the part with the i2c and PCA9622 would be much appreciated!

    Regards Nic
     
  2. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    I have used the PCA9635, which is supposed to be same in a lot of ways to the PCA9622. If you can bear with GCBasic syntax, I can lay out some code snippets which may help you along in initializing and writing to the led driver. Good luck :)
    Code ( (Unknown Language)):
    1. Dim PWM(16)
    2. #define Mode1 0x00
    3. #define Mode2 0x01  
    4. PWM(1) = 0x02
    5. PWM(2) = 0x03
    6. PWM(3) = 0x04
    7. PWM(4) = 0x05
    8. ;etc.
    9. ...
    10. ...
    11. ;Standard reset
    12.     write8bit(PCA9635write, MODE1, 0x00)
    13. ;    All addressing acceptable
    14.     write8bit(PCA9635write, MODE2, 0x00)
    15.  
    16.     write8bit(PCA9635write, GRPPWM, 0xFF)
    17.     write8bit(PCA9635write, GRPFREQ, 0x00)
    18.     write8bit(PCA9635write, LEDOUT0, 0xFF)
    19.     write8bit(PCA9635write, LEDOUT1, 0xFF)
    20.     write8bit(PCA9635write, LEDOUT2, 0xFF)
    21.     write8bit(PCA9635write, LEDOUT3, 0xFF)
    22.     write8bit(PCA9635write, GRPFREQ, 0x00)
    23. ...
    24. ...
    25. Main:
    26. For index = 1 to 16
    27.     If index = 1 Then PWMvalue = 15
    28.     write8bit(PCA9635write, PWM(index), PWMvalue)
    29.     If PWMvalue = 255 Then goto skip
    30.     PWMvalue = (index * 16) - 1
    31. skip:
    32. wait 2 10ms
    33. Next
    34. ...
    35. ...    
    36.  
     
  3. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    hmm.. Thanks for the reply. But i still don't get it.

    I have programmed a bit in arduino - and that is far less complex than this C in mplab.

    Anyone got a link to a place where they have programmed a pic to interface with the PCA9622? A tutorial? anything?

    When i look at it, i become more certain that this is kind of a though thing for a beginner like me. Maybe to though...
     
  4. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    You need pullups on SDA, SDC like 4.7kΩ. The OE pin needs to be active low.

    I am no help with Hitech C, and no links either. When I had the PCA9635, it was brand new and had to slog it out with the data sheet. The code snippets that I supplied did work, but by no means did I master all the functions of this chip.

    Really important that the Mode1 (and possibly Mode2?) be initialized for the chip. You send 0x14 to Mode1 which means it is in low power mode and subaddress 2 is active. I recommend writing 0x00 like I have, so that dimming is possible and just ignore the subaddress stuff altogether for now. Set up the other registers that I show too. They may be redundant or unnecessary, but it works, revisit later after first blinky arrives.

    Once you have initialized the chip, then it is time to write to the PWM registers in Main, or While(1) :)

    When working with a new IC chip or even a serial data protocol like I2C it is always beneficial to begin with the lowest level of functionality. Get the led driver chip going before worrying about which led comes on when which button is pushed.
     
  5. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    Yes, my thought was also to get the i2c bus to work before thinking of anything else. I have tried the whole night yesterday and a couple of hours now today. And i am out of ideas. I can't write it as simple as you do in gcbasic when using mplab and C...

    You must have some sort of library? you just write
    Code ( (Unknown Language)):
    1. write8bit(PCA9635write, LEDOUT0, 0xFF)
    I don't know GCbasic, but you must have a library to be able to do this?

    I have tried using some of this http://www.robot-electronics.co.uk/acatalog/I2C_Tutorial.html
    But can't get that to work either...

    Damn i'm in trouble here :S
     
  6. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    What I have written in GCBasic was for the hardware MSSP module of the PIC. Yes it is a library, but no different than the referenced tutorial, just shorthand for:
    Code ( (Unknown Language)):
    1. Start
    2. tx(address)
    3. tx(chip register)
    4. tx(value)
    5. Stop
    What values are used for the pullups, is the OE pin shorted or pulled low by the micro pin, can you disconnect the second chip to eliminate bus contention.

    A cheapo digital logic probe can come in handy, just to see if data is being sent out or received. I2C is a synchronous serial protocol, so you can increase the delays to really slow down data so it can be seen by the logic tool.

    One thing that is not obvious in tutorial is how the data rate is arrived at, as no indication what the OSC speed is. This is not likely to affect the FM+ chip as it can go up to 1Mhz. Surely there is an I2C library and example (folder) in the HitechC download?

    I learned I2C with a Microchip 24L256, you write a value to a register, then read it back on a LCD, simple as it gets.
     
  7. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    Hi. Yeah if there were a library for i2c, it would be much easier i guess.
    It sounds so simple :)
    In the meantime i have found this http://www.hobbytronics.co.uk/hi-tech-c-i2c-master
    I guess that is just what i need!?

    Now it just worries me that you say that there should be resistors on the SDA and SCL lines..? And what is the OE? is that the EN pin on the RCA9622 you mean?
     
  8. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    Wouldn't hurt to try that library, just make sure the SCL and SDA pins on your micro are tristated, that's why you need the pullup resistors on those lines!! I have seen people who have used digital outputs only, it doesn't conform to the standard and would only work for one chip on the bus. Look at the data sheet for the PCA, it shows 10k pullups.
     
  9. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    Okay i will have to make an adjustment with the resistors then.
    When i try to use that code in the link i get error messages

    undefined identifier "SSPCON1"
    undefined identifier "SSPCON2"
    undefined identifier "SEN"
    undefined identifier "RSEN"
    undefined identifier "PEN"
    undefined identifier "RCEN"
    undefined identifier "ACKDT"
    undefined identifier "ACKEN"

    Any idea what that could be? is it because of me using a different pic than in the example?
     
  10. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    I've found a library for hitech C. But again i can't test it before i get the pull-up's on the SDA and SCL lines. The OE will be controlled by digital outputs. I don't know why but the designer has set the OE for each PCA to an output so that it can be disabled. But it doesn't make sense disabling the PCA's ? They should always be enabled? they have indivdual adresses, so i don't see the point?
    Do you think there is a good reason for doing this??

    Regards
     
  11. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    The OE does not disable the chip, just the outputs. That means you can PWM all the leds, or turn them on or off, at once external to what the PCA is doing software wise. The OE pin on shift registers like the 74 HC595 works like that too.

    One reason I see to use the OE pin would be like for an ambient light sensor to adjust brightness. Another possible reason would be for using the micro to do some lighting effects based on led grouping per chip, less overhead, or more convenient that way? Most all the time you see these pins hardwired to the ON state.
     
  12. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    O.K. then I see the PIC16f724 only has the SSP module, which means it only has the I2C slave function in hardware. The example code is for a chip that has the MSSP module, which means it also has the master mode in hardware. So that will not work, you will be looking for a software I2C solution.
     
  13. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    But it does not make sense trying anything as long as i do not have the resistors on SDA and SCL, it wouldn't work anyway. so i will get the resistors mounted first and then try again.

    I can't see why i should use the OE pin. I know it is used with shift registers and that makes sense.
    Those that made this panel knew that it is only for on and off operation of the led's. But anyway, i will just pull it high in the code.
     
  14. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    I got the two resistors mounted as also shown in the datasheet for the pic.
    The OE pin needs to be set as low right?

    Now i am still not getting any good results with my programming...

    Code ( (Unknown Language)):
    1. #include <htc.h>
    2. #define _XTAL_FREQ 16000000
    3. #define SCL     TRISC3 // I2C bus
    4. #define SDA     TRISC4 //
    5. #define SCL_IN  RC3    //
    6. #define SDA_IN  RC4    //
    7.  
    8. void i2c_dly(void)
    9. {
    10. }
    11. void i2c_start(void)
    12. {
    13.   SDA = 1;             // i2c start bit sequence
    14.   i2c_dly();
    15.   SCL = 1;
    16.   i2c_dly();
    17.   SDA = 0;
    18.   i2c_dly();
    19.   SCL = 0;
    20.   i2c_dly();
    21. }
    22. void i2c_stop(void)
    23. {
    24.   SDA = 0;             // i2c stop bit sequence
    25.   i2c_dly();
    26.   SCL = 1;
    27.   i2c_dly();
    28.   SDA = 1;
    29.   i2c_dly();
    30. }
    31. unsigned char i2c_rx(char ack)
    32. {
    33. char x, d=0;
    34.   SDA = 1;
    35.   for(x=0; x<8; x++) {
    36.     d <<= 1;
    37.     do {
    38.       SCL = 1;
    39.     }
    40.     while(SCL_IN==0);    // wait for any SCL clock stretching
    41.     i2c_dly();
    42.     if(SDA_IN) d |= 1;
    43.     SCL = 0;
    44.   }
    45.   if(ack) SDA = 0;
    46.   else SDA = 1;
    47.   SCL = 1;
    48.   i2c_dly();             // send (N)ACK bit
    49.   SCL = 0;
    50.   SDA = 1;
    51.   return d;
    52. }
    53. bit i2c_tx(unsigned char d)
    54. {
    55. char x;
    56. static bit b;
    57.   for(x=8; x; x--) {
    58.     if(d&0x80) SDA = 1;
    59.     else SDA = 0;
    60.     SCL = 1;
    61.     d <<= 1;
    62.     SCL = 0;
    63.   }
    64.   SDA = 1;
    65.   SCL = 1;
    66.   i2c_dly();
    67.   b = SDA_IN;          // possible ACK bit
    68.   SCL = 0;
    69.   return b;
    70. }
    71.  
    72.  
    73. main(void){
    74. TRISB = 0;
    75. PORTB = 0x00;   //OE pin low
    76. SDA = SCL = 1;
    77. SCL_IN = SDA_IN = 0;
    78. i2c_start();              // send start sequence  
    79. i2c_tx(0x28);   //adress
    80. i2c_tx(0x00);   //load mode1
    81. i2c_tx(0x00);   //00
    82. i2c_stop();  
    83. i2c_start();              // send start sequence
    84. i2c_tx(0x28);   //adress
    85. i2c_tx(0x14);   //led0
    86. i2c_tx(0x55);   //turn all led on
    87. i2c_stop();
    88. }
    89.  
    I thought this would do it, but i am not getting any response from the led's...

    Damn it, this just won't work for me :S
     
  15. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    Hi again.
    I found out that someting else is wrong.
    I use the following code:
    Code ( (Unknown Language)):
    1. #include <htc.h>
    2. #define _XTAL_FREQ 16000000
    3. #include  "i2c.h"
    4. /*
    5.  * I2C functions for HI-TECH PIC C - master mode only
    6.  */
    7. /*
    8.  *  TIMING - see Philips document: THE I2C-BUS SPECIFICATION
    9.  */
    10.  
    11. /*
    12.  *  Send stop condition
    13.  *    - data low-high while clock high
    14.  */
    15. void
    16. i2c_Stop(void)
    17. {
    18.  /* don't assume SCL is high on entry */
    19.  SCL_LOW();
    20.  SDA_LOW();     /* ensure data is low first */
    21.  
    22.  __delay_us(I2C_TM_DATA_SU);
    23.  SCL_DIR = I2C_INPUT;  /* float clock high */
    24.  __delay_us(I2C_TM_STOP_SU);
    25.  SDA_HIGH();     /* the low->high data transistion */
    26.  __delay_us(I2C_TM_BUS_FREE); /* bus free time before next start */
    27.  SDA_DIR = I2C_INPUT;  /* float data high */
    28.  return;
    29. }
    30. /*
    31.  *  Send (re)start condition
    32.  *    - ensure data is high then issue a start condition
    33.  *    - see also i2c_Start() macro
    34.  */
    35. void
    36. i2c_Restart(void)
    37. {
    38.  SCL_LOW();     /* ensure clock is low */
    39.  SDA_HIGH();     /* ensure data is high */
    40.  __delay_us(I2C_TM_DATA_SU);
    41.  SCL_DIR = I2C_INPUT;  /* clock pulse high */
    42.  __delay_us(I2C_TM_SCL_HIGH);
    43.  SDA_LOW();     /* the high->low transition */
    44.  __delay_us(I2C_TM_START_HD);
    45.  return;
    46. }
    47. /*
    48.  *  Send a byte to the slave
    49.  *    - returns true on error
    50.  */
    51. unsigned char
    52. i2c_SendByte(unsigned char byte)
    53. {
    54.  signed char i;
    55.  for(i=7; i>=0; i--)
    56.  {
    57.   SCL_LOW();     /* drive clock low */
    58.  
    59.   /* data hold time = 0, send data now */
    60.         SDA_DIR = ((byte>>i)&0x01);
    61.         if ((byte>>i)&0x01) {  /* bit to send */
    62.    SDA_HIGH();
    63.         }else {
    64.    SDA_LOW();
    65.         }
    66.   __delay_us(I2C_TM_DATA_SU);
    67.   SCL_DIR = I2C_INPUT;  /* float clock high */
    68.   if(i2c_WaitForSCL())  /* wait for clock release */
    69.    return TRUE;   /* bus error */
    70.   __delay_us(I2C_TM_SCL_HIGH); /* clock high time */
    71.  }
    72.  
    73.  return FALSE;
    74. }
    75. /*
    76.  *  send an address and data direction to the slave
    77.  *    - 7-bit address (lsb ignored)
    78.  *    - direction (FALSE = write )
    79.  */
    80. unsigned char
    81. i2c_SendAddress(unsigned char address, unsigned char rw)
    82. {
    83.  return i2c_SendByte(address | (rw?1:0));
    84. }
    85. /*
    86.  *  Check for an acknowledge
    87.  *    - returns ack or ~ack, or ERROR if a bus error
    88.  */
    89. signed char
    90. i2c_ReadAcknowledge(void)
    91. {
    92.  unsigned char ack;
    93.  SCL_LOW();      /* make clock is low */
    94.  SDA_DIR = I2C_INPUT;   /* disable data line - listen for ack */
    95.  __delay_us(I2C_TM_SCL_TO_DATA); /* SCL low to data out valid */
    96.  SCL_DIR = I2C_INPUT;   /* float clock high */
    97.  __delay_us(I2C_TM_DATA_SU);
    98.  ack = SDA;      /* read the acknowledge */
    99.  /* wait for slave to release clock line after processing byte */
    100.  if(i2c_WaitForSCL())
    101.   return I2C_ERROR;
    102.  return ack;
    103. }
    104. /*
    105.  *  Read a byte from the slave
    106.  *    - returns the byte, or I2C_ERROR if a bus error
    107.  */
    108. int
    109. i2c_ReadByte(void)
    110. {
    111.  unsigned char i;
    112.  unsigned char byte = 0;
    113.  for(i=0; i<8; i++)
    114.  {
    115.   SCL_LOW();     /* drive clock low */
    116.   __delay_us(I2C_TM_SCL_LOW); /* min clock low  period */
    117.   SDA_DIR = I2C_INPUT;  /* release data line */
    118.   SCL_DIR = I2C_INPUT;  /* float clock high */
    119.   if(i2c_WaitForSCL())
    120.    return I2C_ERROR;
    121.   __delay_us(I2C_TM_SCL_HIGH);
    122.   byte = byte << 1;  /* read the next bit */
    123.   byte |= SDA;
    124.  }
    125.  return (int)byte;
    126. }
    127. /*
    128.  *  Send an (~)acknowledge to the slave
    129.  *    - status of I2C_LAST implies this is the last byte to be sent
    130.  */
    131. void
    132. i2c_SendAcknowledge(unsigned char status)
    133. {
    134.  SCL_LOW();
    135.  if ( status & 0x01) {
    136.   SDA_LOW();    /* drive line low -> more to come */
    137.  }else {
    138.   SDA_HIGH();
    139.  }
    140.  __delay_us(I2C_TM_DATA_SU);
    141.  SCL_DIR = I2C_INPUT;  /* float clock high */
    142.  __delay_us(I2C_TM_SCL_HIGH);
    143.  return;
    144. }
    145. /*
    146.  *  Send a byte to the slave and acknowledges the transfer
    147.  *    - returns I2C_ERROR, ack or ~ack
    148.  */
    149. signed char
    150. i2c_PutByte(unsigned char data)
    151. {
    152.  if(i2c_SendByte(data))
    153.   return I2C_ERROR;
    154.  return i2c_ReadAcknowledge(); /* returns ack, ~ack */
    155. }
    156. /*
    157.  *  Get a byte from the slave and acknowledges the transfer
    158.  *    - returns true on I2C_ERROR or byte
    159.  */
    160. int
    161. i2c_GetByte(unsigned char more)
    162. {
    163.  int byte;
    164.  if((byte = i2c_ReadByte()) == I2C_ERROR)
    165.   return I2C_ERROR;
    166.  i2c_SendAcknowledge(more);
    167.  return byte;
    168. }
    169. /*
    170.  *  Send an array of bytes to the slave and acknowledges the transfer
    171.  *    - returns number of bytes not successfully transmitted
    172.  */
    173. int
    174. i2c_PutString(const unsigned char *str, unsigned char length)
    175. {
    176.  signed char error;
    177.  while(length)
    178.  {
    179.   if((error = i2c_PutByte(*str)) == I2C_ERROR)
    180.    return -(int)length;     /* bus error */
    181.   else
    182.    if(error)
    183.     return (int)length;     /* non acknowledge */
    184.   str++;
    185.   length--;
    186.  }
    187.  return FALSE;         /* everything OK */
    188. }
    189. /*
    190.  *  Reads number bytes from the slave, stores them at str and acknowledges the transfer
    191.  *    - returns number of bytes not successfully read in
    192.  */
    193. unsigned char
    194. i2c_GetString(unsigned char *str, unsigned char number)
    195. {
    196.  int byte;
    197.  while(number)
    198.  {
    199.   if((byte = i2c_GetByte(number-1)) == I2C_ERROR)
    200.    return number;        /* bus error */
    201.   else
    202.    *str = (unsigned char)byte;
    203.   str++;
    204.   number--;
    205.  }
    206.  return FALSE;          /* everything OK */
    207. }
    208. /*
    209.  *  Opens communication with a device at address. mode
    210.  *  indicates I2C_READ or I2C_WRITE.
    211.  *    - returns TRUE if address is not acknowledged
    212.  */
    213. unsigned char
    214. i2c_Open(unsigned char address, unsigned char mode)
    215. {
    216.  i2c_Start();
    217.  i2c_SendAddress(address, mode);
    218.  if(i2c_ReadAcknowledge())
    219.   return TRUE;
    220.  return FALSE;
    221. }
    222. /*
    223.  *  wait for the clock line to be released by slow slaves
    224.  *    - returns TRUE if SCL was not released after the
    225.  *      time out period.
    226.  *    - returns FALSE if and when SCL released
    227.  */
    228. unsigned char
    229. i2c_WaitForSCL(void)
    230. {
    231.  /* SCL_DIR should be input here */
    232.  if(!SCL)
    233.  {
    234.   __delay_us(I2C_TM_SCL_TMO);
    235.   /* if the clock is still low -> bus error */
    236.   if(!SCL)
    237.    return TRUE;
    238.  }
    239.  return FALSE;
    240. }
    241. void
    242. i2c_Free()
    243. {
    244.  unsigned char ucI;
    245.  SDA_DIR=I2C_INPUT;
    246.  for(ucI=0;ucI!=9;ucI++)
    247.  {
    248.   SCL_HIGH();
    249.   __delay_us(5);
    250.   SCL_LOW();
    251.   __delay_us(5);
    252.  }
    253. }
    254. unsigned char i2c_read(unsigned char ucAdr)
    255. {
    256.  unsigned char ucDat;
    257.  if (i2c_ReadFrom(ucAdr)==0)
    258.  {
    259.   ucDat=i2c_GetByte(I2C_MORE);
    260.   i2c_Stop();
    261.  }
    262.  return(ucDat);
    263. }
    264.  
    265. main(void){
    266. TRISB = 0;
    267. PORTB = 0x00;   //OE pin LOW
    268. i2c_WriteTo(0x28);
    269. i2c_PutByte(0x00);
    270. i2c_PutByte(0x00);
    271. i2c_Stop();
    272. i2c_WriteTo(0x28);
    273. i2c_PutByte(0x14);
    274. i2c_PutByte(0x55);
    275. i2c_Stop();  
    276. i2c_WriteTo(0x2A);
    277. i2c_PutByte(0x15);
    278. i2c_PutByte(0x55);
    279. i2c_Stop();  
    280. i2c_WriteTo(0x2A);
    281. i2c_PutByte(0x16);
    282. i2c_PutByte(0x55);
    283. i2c_Stop();
    284. i2c_WriteTo(0x2A);
    285. i2c_PutByte(0x00);
    286. i2c_PutByte(0x00);
    287. i2c_Stop();
    288. i2c_WriteTo(0x2A);
    289. i2c_PutByte(0x17);
    290. i2c_PutByte(0x55);
    291. i2c_Stop();
    292. }
    293.  
    It worked fine at first. I have light in the led's. But it seems like it stays in some infinite loop somewhere. It stays locked in this position. Sometimes when i transfer a edited program it doesn't work - then i unplug the power and wait for 10 seconds and plug it back in, then i get light! But if i plug it in after lets say 3 seconds, then i don't get light!?

    It seems like i am stuck in a loop?
     
  16. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    Congrats, looks like you about have it. Sounds like the bus isn't getting released somewhere. I don't see any i2c_Start()'s. Double check the previously mentioned registers for initialization. That's just to make sure you are starting in the proper condition if it varies from the default 0x00???

    For me it is more clear by defining the registers as constants like mode1, and pwm1, pwm2 etc. When doing lighting effects, then an array for pwm(1), pwm(2), etc. will come in handy when doing the multitudes of code loops .
     
  17. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    The i2c_start is included in the i2c_writeto, but maybe i will try to make it more simple and use start instead. This is a sample code from hitech C i found.
    It works fine, but as mentioned it gets stuck somewhere.. I will have a look at the mode1 and 2 registers for the initialization.

    I am really new to C so i don't even mess around with defining things as constants or creating arrays.

    Also the only thing i should be able to do, is to turn led's on and off, no blinkin or dimming...

    Thanks for the help so far. I will try your suggestion and post again later.
     
  18. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    Just looked at the datasheet for the PCA. The Mode1 is okay as 0x00 and mode2 should just be left default as i see it.

    But it is weird that it gets stuck...
     
  19. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    Back in post #2 I gave other init states of registers. It looks like the GRPPWM and GRPFREQ registers just repeat the defaults. The init power up on the led drivers is off, and that is why LEDOUT0-3 are set to 0xFF. This type of troubleshooting is unappetizing, because I cannot duplicate the setup.

    Edit: beg your pardon I see thoughs registers are supposed to be turned full on with your code.
     
    Last edited: Jun 25, 2012
  20. nic6911

    Thread Starter New Member

    Jun 22, 2012
    24
    0
    It doesnt have something to do with my OE pin? i set it low at the beginning of main... It doesn't help using the lower level code like start, address, and send byte.
    The slave sends ack after data is recieved, but in my code i don't look at this, could that do something??
     
Loading...