This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

5509A 用I2C接口API怎么输入子地址?

Other Parts Discussed in Thread: LP3913

如题,

CSLAPI int I2C_write(Uint16 *data,int length,int master,Uint16 slaveaddress,int transfermode,int timeout);

只有外设的地址slaveaddress,如果我想往这个外设的某个寄存器写值应该如何操作,也就是说如何往子地址里写值?

是把data里的第一组数据作为子地址吗?

  • 寄存器子地址放在*data数组里,如{reg addr, value}

    可以看一下下面vc5509a如何配置aic23寄存器的。
    http://www.ti.com/lit/an/spra785a/spra785a.pdf

  • 可是,这个文档的Example里,初始化I2C模块使用的是:

    ......

    I2C_Init Init={

                        0,

                        0x0000,

                        144,

                         400,

                         0,

                         0,

                         1

    };

    I2C_init(&amp,Init);

    .......

    而我使用的额csl_i2c.h文件里并没有I2C_Init这个struct和I2C_init()这个函数,有的是I2C_Setup这个struct和I2C_setup()这个函数。请问这两组是同样的功能吗?还是说我用的库文件是错的?

    谢谢。

  • 用I2C_setup没问题。 在cslc55x.src I2C_setup()和I2C_init是一样的。

  • 恩,好的。

    我用I2C接口与LP3913这个电源管理模块(也是TI的产品)通信,程序如下:

    ......

    #define LP3913 0xC0

    Uint16 dataW1[2] = {0x09,0x34};

    Uint16 i2c_status = 0;

    I2C_Setup setup = {
                                  0, /* 7 bit address mode */
                                  0, /* own address - don't care if master */
                                  240, /* dsp clock 240Mhz) */
                                  100, /* 100Khz master clock*/
                                   0, /* number of bits/byte to be received or transmitted (8)*/
                                   0, /* DLB mode on*/
                                   1 /* FREE mode of operation on*/
    };

    I2C_setup(&setup);


    i2c_status =I2C_write( dataW1,                       //pointer to data array 往寄存器0x09里写入0x34
                                              2,                                  //length of data to be transmitted
                                              1,                                  //master or slaver
                                               LP3913_ADDR,       //slave address to transmit to
                                              1,                                 //transfer mode of operation
                                               30000                       //time out for bus busy
    );

    ......

    i2c_status接收到的返回值是1(Bus busy;not able to generate start condition),请问,这种错误是怎么导致的?我在初始化I2C模块时,配置错误吗?

    谢谢。

  • 请问SDA, SCL管脚上拉了么?

  • 恩,上拉了,接的1.8K的上拉电阻,接到3.3V的电位上了

  • 在main()函数一开始的时候调用CSL_init();了吗?

    量一下SDA, SCL管脚是否有时序出来?

  • CSL_init();调用了。

    我量一下管脚的时序看看吧

  • Hi, Shine. 我量了一下这两个管脚,SDA被拉低以后,就一直处于低的状态,没有数据;SCL管脚一直处于高电位,没有时钟输出。

    请问,是否是在配置I2C模块的时候,配置不正确?仅仅一个I2C_setup();就够了吗?

    谢谢

  • SDA初始化电平就是低吗?

  • 初始化是高的,接着上拉电阻呢。

  • 执行到哪句代码后,SDA被拉低了?

  • 执行了第一个写语句后,就被拉低了,

    i2c_status =I2C_write( dataW1,//pointer to data array
                                                      2, //length of data to be transmitted
                                                      1, //master or slaver
                                                      LP3913_ADDR, //slave address to transmit to
                                                      1, //transfer mode of operation
                                                 30000 //time out for bus busy
                                               );

    返回值是4(Timeout for transmit ready(within main loop)),然后执行第二个写语句的时候,返回值就是1了

  • I2C_Setup setup = {
                                  0, /* 7 bit address mode */
                                  0, /* own address - don't care if master */
                                  240, /* dsp clock 240Mhz) */
                                  100, /* 100Khz master clock*/
                                   0, /* number of bits/byte to be received or transmitted (8)*/
                                   0, /* DLB mode on*/
                                   1 /* FREE mode of operation on*/

     240, /* dsp clock 240Mhz) */这个设置有点问题,vc5509A最高主频是200MHz,看一下您用的vc5509a主频是多快的?

  • 我的主频是这样设置的:

    PLL_Config myConfig = {
                                              0, //IAI: the PLL locks using the same process that was underway
                                                  //before the idle mode was entered
                                              1, //IOB: If the PLL indicates a break in the phase lock,
                                                  //it switches to its bypass mode and restarts the PLL phase-locking
                                                  //sequence
                                               20, //PLL multiply value;(2-31)
                                                0 //Divide by 2 PLL divide value; it can be either PLL divide value (0-3)
                                                   //(when PLL is enabled), or Bypass-mode divide value
                                                  //(PLL in bypass mode, if PLL multiply value is set to 1)
    };

    data sheet上写的是,multiply value 可以是2-31,我的晶振是12MHz,如果设置multiply value为20,divide value为0(0+1),理论上来说主频应该是

    12*20/(0+1)=240,这样设置是错误的吗?应该是你所说的,不能超过200MHz?

  • 可以告诉我如何查看I2C_setup()这个函数的源代码吗?因为网上有一种说法是,这个源代码有问题,这个源代码内部并没有调用到I2C_结构体里的master clock参数:

    void I2C_setup(I2C_Setup *Init) { 

    int old_intm; 

    Uint16 IPSC_calc; 

    old_intm = IRQ_globalDisable(); 

    I2C_RSET(I2CMDR,I2C_I2CMDR_RMK(Init->free,0,0,0,1,1,Init->addrmode,0,Init->dlb,1,0,0,Init->bitbyte)); 

    /* set own address */ 

    I2C_RSET(I2COAR,Init->ownaddr); /* if slave, need to specify own address */ 

    /* calculating the IPSC value */ 

    IPSC_calc = (Init->sysinclock)/12; /* must correct rounding issue */ 

    I2C_RSET(I2CPSC,IPSC_calc); 

    /* calculating the ICCLKL and ICCLKH register values */ 

    I2C_RSET(I2CCLKL,15); 

    I2C_RSET(I2CCLKH,15); 

    IRQ_globalRestore(old_intm); 

    } /* end of init */ 

  • Fangbin Dong 说:

    我的主频是这样设置的:

    PLL_Config myConfig = {
                                              0, //IAI: the PLL locks using the same process that was underway
                                                  //before the idle mode was entered
                                              1, //IOB: If the PLL indicates a break in the phase lock,
                                                  //it switches to its bypass mode and restarts the PLL phase-locking
                                                  //sequence
                                               20, //PLL multiply value;(2-31)
                                                0 //Divide by 2 PLL divide value; it can be either PLL divide value (0-3)
                                                   //(when PLL is enabled), or Bypass-mode divide value
                                                  //(PLL in bypass mode, if PLL multiply value is set to 1)
    };

    data sheet上写的是,multiply value 可以是2-31,我的晶振是12MHz,如果设置multiply value为20,divide value为0(0+1),理论上来说主频应该是

    12*20/(0+1)=240,这样设置是错误的吗?应该是你所说的,不能超过200MHz?

    这样设置是有问题的,超过了vc5509A最高主频200MHz,DSP是不建议超频使用的。

  • Fangbin Dong 说:

    可以告诉我如何查看I2C_setup()这个函数的源代码吗?因为网上有一种说法是,这个源代码有问题,这个源代码内部并没有调用到I2C_结构体里的master clock参数:

    void I2C_setup(I2C_Setup *Init) { 

    int old_intm; 

    Uint16 IPSC_calc; 

    old_intm = IRQ_globalDisable(); 

    I2C_RSET(I2CMDR,I2C_I2CMDR_RMK(Init->free,0,0,0,1,1,Init->addrmode,0,Init->dlb,1,0,0,Init->bitbyte)); 

    /* set own address */ 

    I2C_RSET(I2COAR,Init->ownaddr); /* if slave, need to specify own address */ 

    /* calculating the IPSC value */ 

    IPSC_calc = (Init->sysinclock)/12; /* must correct rounding issue */ 

    I2C_RSET(I2CPSC,IPSC_calc); 

    /* calculating the ICCLKL and ICCLKH register values */ 

    I2C_RSET(I2CCLKL,15); 

    I2C_RSET(I2CCLKH,15); 

    IRQ_globalRestore(old_intm); 

    } /* end of init */ 



    源码在C55xxCSL\lib\csl55xx.src

  • sysinclock这个是主频,用来计算I2C clock。

  • 好的,既然这样,我就把主频调低吧。

  • vc5509A有108MHz, 144MHz, 200MHz这三种主频,你看一下你的供电电压是按照哪种主频接的,就配置成哪种频率。

  • 你好,能把你这个完整的程序贴出来看看吗?我现在也在用5509的iic,程序调不出来,想看看你是怎么写的!另外,怎么读取从设备中的寄存器的值?谢谢

  • 请参考这个应用报告里的例程。

    http://www.ti.com/lit/an/spra785a/spra785a.pdf