我是PSoC主板的新手,我正在尝试从数字罗盘中读取x,y,z值但是我在使用罗盘本身开始传输时遇到了问题。
我在线发现了一些Arduino教程here,但由于PSoC没有库,我无法复制代码。
此外,我正在阅读HMC5883L数据表here,我想要将字节写入指南针并获取值,但我无法收到任何内容。我收到的所有值都是零,这可能是由于从错误的地址读取值而引起的。
希望尽快回答。
答案 0 :(得分:0)
您链接的设备的数据表在第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 */
}
}