使用I2C,PSOC开始传输和接收字节

时间:2016-08-30 16:41:39

标签: arduino psoc

我是PSoC主板的新手,我正在尝试从数字罗盘中读取x,y,z值但是我在使用罗盘本身开始传输时遇到了问题。

我在线发现了一些Arduino教程here,但由于PSoC没有库,我无法复制代码。

此外,我正在阅读HMC5883L数据表here,我想要将字节写入指南针并获取值,但我无法收到任何内容。我收到的所有值都是零,这可能是由于从错误的地址读取值而引起的。

希望尽快回答。

2 个答案:

答案 0 :(得分:0)

当你第一次开始使用它时,PSoC很棘手。您需要仔细阅读要与之通信的设备和i2c模块本身的文档。

您链接的设备的数据表在第18页说明了这一点:

  

所有总线事务都以主设备发出启动序列,然后是从地址字节开始。该   地址字节包含从地址;高7位(位7-1)和最低有效位(LSb)。的LSb   地址字节表示操作是读(LSb = 1)还是写(LSb = 0)。在9点   时钟脉冲,接收从机   设备将发出ACK(或NACK)。在这些总线事件之后,主机将发送数据字节用于写操作,或   从器件将通过读操作来输出数据。所有总线交易都在主机发出停止时终止   序列

如果您使用I2C_MasterWriteBuf函数,它将包含HMC数据表中所述的所有内容。 start命令,处理ack,数据处理等。你唯一需要指定的是如何传输它。

如果您参考PSoC的I2C模块数据表,MasterWriteBuf函数会接收设备地址,指向要发送的数据的指针,要发送的字节数以及“模式”。它显示了文档中的各种传输模式。

  

I2C_MODE_COMPLETE_XFER执行从开始到停止的完整传输   I2C_MODE_REPEAT_START发送重复启动而不是启动   I2C_MODE_NO_STOP执行无停止传输

如果我没弄错的话,MODE_COMPLETE_XFRE传输会为你发送启动和停止命令。

如果你愿意,你也可以“bit-bang”这个,但是直接调用I2C_MasterSendStart,WriteByte,SendStop等等。但是调用它们的writebuf函数会更容易。

你需要编写如下代码:

// fill in your data or pass in the buffer of data you want to write 
// if this is contained in a function call. I'm basing this off of HMC's docs
uint8 writeBuffer[3];
uint8 readBuffer[6];
writeBuffer[0] = 0x3C;
writeBuffer[1] = 0x00;
writeBuffer[2] = 0x70;
I2C_MasterWriteBuf(HMC_SLAVE_ADDRESS, &writeBuffer, 3, I2C_MODE_COMPLETE_XFER);
while((I2C_MasterStatus() & I2C_MSTAT_WR_CMPLT) == 0u)
{
    // wait for operation to finish
}

writeBuffer[1] = 0x01;
writeBuffer[2] = 0xA0;
I2C_MasterWriteBuf(HMC_SLAVE_ADDRESS, &writeBuffer, 3, I2C_MODE_COMPLETE_XFER);
// wait for operation to finish

writeBuffer[1] = 0x02;
writeBuffer[2] = 0x00;
I2C_MasterWriteBuf(HMC_SLAVE_ADDRESS, &writeBuffer, 3, I2C_MODE_COMPLETE_XFER);
// wait for operation to finish
CyDelay(6); // docs state 6ms delay before you can start looping around to read

for(;;)
{
    writeBuffer[0] = 0x3D;
    writeBuffer[1] = 0x06;
    I2C_MasterWriteBuf(HMC_SLAVE_ADDRESS, &writeBuffer, 2, I2C_MODE_COMPLETE_XFER);
    // wait for operation to finish

    // Docs don't state any different sort of bus transactions for reads. 
    // I'm assuming it'll be the same as a write
    I2C_MasterReadBuf(HMC_SLAVE_ADDRESS, readBuffer, 6, I2C_MODE_COMPLETE_XFER);  
    // wait for operation to finish, wait on I2C_MSTAT_RD_CMPLT instead of WR_COMPLT  

    // You should have something in readBuffer to work with

    CyDelay(67); // docs state to wait 67ms before reading again
}

我只是把它写在了我的头顶。我不知道这是否有效,但我认为这应该是一个开始尝试的好地方。我认为他们还有I2C示例项目。

另外要看看WriteBuf函数不仅仅是一些神奇的命令,如果你右键单击MasterWriteBuf函数并点击“Find Definition”(在你构建项目之后),它会告诉你它正在做什么。

答案 1 :(得分:0)

以下是在PSoC上进行I2C读写操作的示例,

简单的写操作:

//Dumpy data values to write 
uint8 writebuffer[3]
writebuffer[0] = 0x23
writebuffer[1] = 0xEF
writebuffer[2] = 0x0F

uint8 I2C_MasterWrite(uint8 slaveAddr, uint8 nbytes)
{
    uint8 volatile status;

    status = I2C_MasterClearStatus();
    if(!(status & I2C_MSTAT_ERR_XFER))
    {
      status = I2C_MasterWriteBuf(slaveAddr, (uint8 *)&writebuffer, nbytes, I2C_MODE_COMPLETE_XFER);
        if(status == I2C_MSTR_NO_ERROR)
        {
            /* wait for write complete and no error */
            do
            {
                status = I2C_MasterStatus();
            } while((status & (I2C_MSTAT_WR_CMPLT | I2C_MSTAT_ERR_XFER)) == 0u);
        }
        else
        {
            /* translate from I2CM_MasterWriteBuf() error output to
            *  I2C_MasterStatus() error output */
            status = I2C_MSTAT_ERR_XFER;
        }
    }

    return status;
}

读取操作:

void I2C_MasterRead(uint8 slaveaddress, uint8 nbytes)
{
    uint8 volatile status;

    status = I2C_MasterClearStatus();
      if(!(status & I2C_MSTAT_ERR_XFER))
        {
            /* Then do the read */
            status = I2C_MasterClearStatus();
            if(!(status & I2C_MSTAT_ERR_XFER))
            {
                status = I2C_MasterReadBuf(slaveaddress,
                                           (uint8 *)&(readbuffer),
                                           nbytes, I2C_MODE_COMPLETE_XFER);
                if(status == I2C_MSTR_NO_ERROR)
                {
                    /* wait for reading complete and no error */
                    do
                    {
                        status = I2C_MasterStatus();
                    } while((status & (I2C_MSTAT_RD_CMPLT | I2C_MSTAT_ERR_XFER)) == 0u);
                    if(!(status & I2C_MSTAT_ERR_XFER))
                    {
                        /* Decrement all RW bytes in the EZI2C buffer, by different values */
                        for(uint8 i = 0u; i < nbytes; i++)
                        {
                            readbuffer[i] -= (i + 1);
                        }
                    }
                }
                else
                {
                    /* translate from I2C_MasterReadBuf() error output to
                    *  I2C_MasterStatus() error output */
                    status = I2C_MSTAT_ERR_XFER;
                }
            }
        }
        if(status & I2C_MSTAT_ERR_XFER)
        {
            /* add error handler code here */
        }

 }