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.

[参考译文] PCA9539:随机数据读取

Guru**** 2387080 points
Other Parts Discussed in Thread: MSP430F4784, PCA9539
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1121233/pca9539-random-data-read

器件型号:PCA9539
主题中讨论的其他器件:MSP430F4784

您好!

我目前正在使用 PCA9539 I/O 扩展器。使用 I2C 连接 MSP430F4784。

IC 上电(3.3)时,INT 引脚是否初始为低电平? 即使连接了上拉(10k)。

INT 引脚是否仅在读取输入寄存器之后才会变高?

下面是程序。

每当我读取输入寄存器 1时 、UCB0RXBUF 都会提供2个字节  

但在循环中、数据[0]和数据[1]的字节会连续跳跃。

以便我无法读取字节的特定位。

问题是什么?

请帮我解决这个问题

uint8_t data[2];


void i2c_beginTx(uint8_t address)
{
    UCB0I2CSA = address;
    UCB0CTL1 |= UCTR + UCTXSTT;
    while((UCB0STAT & UCNACKIFG));
}

void i2c_write(uint8_t byte)
{
    UCB0TXBUF = byte;
    while((UCB0STAT & UCNACKIFG));
    __delay_cycles(5000);
}

void i2c_read(uint8_t address, uint8_t reg, uint8_t len)
{
    int i;
    UCB0I2CSA = address;
    UCB0CTL1 |= UCTR + UCTXSTT;
    while((UCB0STAT & UCNACKIFG));
    UCB0TXBUF = reg;
    __delay_cycles(5000);
    UCB0CTL1 |= UCTXSTP;

    UCB0I2CSA = address;
    UCB0CTL1 &= ~UCTR;
    UCB0CTL1 |= UCTXSTT;
    while((UCB0STAT & UCNACKIFG));
    for(i=0;i<len;i++)
    {
        data[i] = UCB0RXBUF;
        __delay_cycles(5000);
    }
    UCB0CTL1 |= UCTXNACK;
    UCB0CTL1 |= UCTXSTP;

}

void read(uint8_t address, uint8_t len)
{
    UCB0I2CSA = address;
   UCB0CTL1 &= ~UCTR;
   UCB0CTL1 |= UCTXSTT;
   while((UCB0STAT & UCNACKIFG));
   for(i=0;i<len;i++)
   {
       data[i] = UCB0RXBUF;
       __delay_cycles(5000);
   }
   UCB0CTL1 |= UCTXNACK;
   UCB0CTL1 |= UCTXSTP;
}

void i2c_stop()
{
    UCB0CTL1 |= UCTXSTP;
}

int main()
{
    WDTCTL = WDTPW | WDTHOLD;

    SCFQCTL |= SCFQ_4M;
    SCFI0 |= FN_2;
    FLL_CTL0 |= DCOPLUS;

    do
    {
        IFG1 &= ~OFIFG;
        __delay_cycles(5000);
    }while(IFG1 & OFIFG);


    P1DIR |= BIT1;
    P1SEL |= BIT1;

    P1DIR |= BIT4;
    P1SEL |= BIT4;

    P3SEL |= BIT1 + BIT2; // i2c pins

    basic_tmr();

    P9DIR |= BIT5; //LED blink
    P9OUT &= ~BIT5;

    P5DIR |= BIT5; // led
    P5OUT &= ~BIT5;

    P5DIR |= BIT4; // led 
    P5OUT &= ~BIT4;

   
    P10DIR |= BIT6; // reset IO EXP
    P10OUT &= ~BIT6;

    __delay_cycles(500);

    P10OUT |= BIT6;


    UCB0CTL1 |= UCSWRST;
    UCB0CTL0 |= UCMST + UCMODE_3 + UCSYNC;
    UCB0CTL1 |= UCSSEL_2 + UCSWRST;
    UCB0BR0 = 20;
    UCB0BR1 = 0;
    UCB0CTL1 &= ~UCSWRST;

    __delay_cycles(100000);

    i2c_beginTx(0x77);
    i2c_write(0x06);
    i2c_write(0x60);
    i2c_write(0xFF);
    i2c_stop();

    __delay_cycles(50000);
    
    i2c_read(0x77, 0x01, 2);
    
    /** interrupt  pin **/
       P1DIR &= ~BIT5;
       P1IE |= BIT5;
       P1IES |= BIT5;

       __bis_SR_register(GIE);
    while(1)
    {

        P5OUT ^= BIT4;
        __delay_cycles(1000000);

        if(a == 1)
        {
            read(0x77, 2);
            if((data[0] & (1<<5)) == 1)
            {
                a = 0;

                P9OUT ^= BIT5;
                __delay_cycles(1000000);
            }
        }


    }

}

#pragma vector=PORT1_VECTOR
__interrupt void port_1_ISR(void)
{

    if(P1IFG & BIT5)
    {
        read(0x77, 2);
        if((data[0] & (1<<5)) == 0)
        {
            __delay_cycles(10000000);
            P5OUT |= BIT5;
            __delay_cycles(10000000);
            P5OUT &= ~BIT5;

            a = 1;
        }
        P1IFG &= ~BIT5;
    }
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="431635" URL"~/support/interface-group/interface/f/interface-forum/1121233/pca9539-random-data-read"]

    IC 上电(3.3)时,INT 引脚是否初始为低电平? 即使连接了上拉(10k)。

    INT 引脚是否仅在读取输入寄存器之后才会变高?

    [/报价]

    如果在加电期间 POR 电路被切换后、P 端口上引脚的状态改变、它可被置为低电平。 通常、在 p 端口上放置强大的上拉/下拉电阻器可以防止这种情况发生。  

    [引用 userid="431635" URL"~/support/interface-group/interface/f/interface-forum/1121233/pca9539-random-data-read"]但在循环中,数据[0]和数据[1]的字节连续交换。

    当您从我们的器件读取数据0和数据1时、您是否有我们可以查看的 I2C 读取事务的范围?  

    我不太熟悉代码、但我可以查看 I2C 通信上的模拟波形、看看是否有问题。 如果数据正在交换、可能是因为每次读取后都不会重置输入寄存器的指针。 每次读取后 I2C 器件的寄存器地址可能会自动递增。  

    -Bobby

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    一个5000周期的等待不能与状态机正确同步;在访问 TXBUF/RXBUF 之前测试 TXIFG/RXIFG。 如果不对寄存器地址进行写操作、则可能不会进行读操作(μ I²C 没有纠错或检测功能)。

    使用如下功能:

    void i2c_beginTx(uint8_t address)
    {
        while (UCB0CTL1 & UCTXSTP) ;
        UCB0I2CSA = address;
        UCB0CTL1 |= UCTR | UCTXSTT;
    }
    
    void i2c_write(uint8_t byte)
    {
        while (!(IFG2 & UCB0TXIFG)) ;
        UCB0TXBUF = byte;
    }
    
    void i2c_stop()
    {
        while (!(IFG2 & UCB0TXIFG)) ;
        UCB0CTL1 |= UCTXSTP;
        IFG2 &= ~UCB0TXIFG;
    }
    
    void i2C_read(uint8_t address, uint8_t reg, unsigned int len)
    {
        unsigned int i;
        
        while (UCB0CTL1 & UCTXSTP) ;
    
        UCB0I2CSA = address;
        UCB0CTL1 |= UCTR | UCTXSTT;
        while (!(IFG2 & UCB0TXIFG)) ;
        UCB0TXBUF = reg;
        while (!(IFG2 & UCB0TXIFG)) ;
    
        IFG2 &= ~UCB0TXIFG;
        UCB0CTL1 &= ~UCTR;
        UCB0CTL1 |= UCTXSTT;
        for (i = 0; i < len; i++)
        {
            if (i == len - 1)
                UCB0CTL1 |= UCTXSTP;
            while (!(IFG2 & UCB0RXIFG)) ;
            data[i] = UCB0RXBUF;
        }
    }