Начните передачу и получение байта, используя 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 */
        }

 }
Другие вопросы по тегам