Начните передачу и получение байта, используя I2C, PSOC
Я новичок в плате PSoC и пытаюсь прочитать значения x,y,z с цифрового компаса, но у меня проблема с началом передачи с самого компаса.
Я нашел здесь какое-то учебное пособие по Arduino, но поскольку в PSoC нет библиотеки, я не могу продублировать код.
Также я читал таблицу данных HMC5883L здесь, и я предполагаю записать байты в компас и получить значения, но я не смог ничего получить. Все значения, которые я получил, равны нулю, что может быть вызвано чтением значений с неправильного адреса.
Надеемся на ваш ответ в ближайшее время.
1 ответ
PSoC довольно сложно, когда вы начинаете с него. Вам необходимо внимательно прочитать документацию как устройства, с которым вы хотите общаться, так и самого модуля i2c.
Таблица данных для устройства, которое вы связали, утверждает это на странице 18:
Все шинные транзакции начинаются с того, что ведущее устройство выдает последовательность запуска, за которой следует байт адреса ведомого. Байт адреса содержит адрес подчиненного устройства; старшие 7 бит (биты 7-1) и младший значащий бит (LSb). LSb байта адреса обозначает, является ли операция чтением (LSb=1) или записью (LSb=0). При 9-м тактовом импульсе принимающее ведомое устройство выдаст ACK (или NACK). После этих событий шины ведущий будет отправлять байты данных для операции записи, или ведомый будет синхронизировать данные с операцией чтения. Все транзакции шины завершаются, когда мастер выдает последовательность останова.
Если вы используете функцию I2C_MasterWriteBuf, она упаковывает все вышеперечисленные состояния таблицы данных HMC выше. Команда запуска, работа с этим подтверждением, обработка данных и т. Д. Единственное, что вам нужно указать, - это как передать его.
Если вы обращаетесь к спецификации I2C модуля PSoC, функция 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 и нажать "Найти определение" (после создания проекта), она покажет вам, что она делает.,
Ниже приведены примеры операций чтения и записи I2C на PSoC.
простая операция записи:
//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 */
}
}