1

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

我在这里在线找到了一些 Arduino 教程,但由于 PSoC 没有库,我无法复制代码。

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

希望尽快得到您的答复。

4

2 回答 2

2

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

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

所有总线事务都以主设备发出起始序列开始,然后是从地址字节。地址字节包含从机地址;高 7 位 (bits7-1) 和最低有效位 (LSb)。地址字节的 LSb 指定操作是读取 (LSb=1) 还是写入 (LSb=0)。在第 9 个时钟脉冲,接收从设备将发出 ACK(或 NACK)。在这些总线事件之后,主设备将发送数据字节进行写操作,或者从设备将通过读操作输出数据。所有总线事务都以主机发出停止序列而终止。

如果您使用 I2C_MasterWriteBuf 函数,它会包装上面 HMC 数据表中所述的所有内容。启动命令,处理该确认,数据处理等。您唯一需要指定的是如何传输它。

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

I2C_MODE_COMPLETE_XFER 执行从 Start 到 Stop 的完整传输。
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 函数并单击“查找定义”(在您构建项目之后),它会告诉您它在做什么.

于 2016-09-13T21:40:51.923 回答
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 */
        }

 }
于 2019-11-19T00:19:13.603 回答