Давайте начнем с HAL_I2C_Master_Transmit()
функции. Если вы проверите свою декларацию:
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Незначительная проблема со вторым параметром, адрес подчиненного устройства. Адрес ведомого устройства: b1010000
если мы заполним его до 8-битного формата, он будет 0xA0
, как вы сказали. Теперь при передаче этого HAL_I2C_Master_Transmit()
вам не нужно устанавливать бит R / W вручную, HAL сделает это за вас. Таким образом, при вызове HAL_I2C_Master_Transmit()
переданный бит R / W будет автоматически равен 0, что означает операцию записи, а при вызове HAL_I2C_Master_Receive()
переданный бит R / W будет автоматически равен 1, что означает операцию записи . Вы смешали значения R / W, но я думаю, что это не важен для функции, так что это не фактическая ошибка в вашем коде.
Третий параметр ( uint8_t *pData
) представляет собой указатель на буфер , который содержит данные , которые должны быть отправлено . Теперь в вашем вызове третий параметр - 0x0C
это ваши фактические данные, адрес регистра. Проблема в том, что он будет интерпретироваться как указатель (на HAL_I2C_Master_Transmit()
) на область памяти, где можно найти некоторые неопределенные данные.
Четвёртый параметр является размером буфера , количество байт , которые должны быть отправлено. Если вы хотите отправить один байт, тогда этот параметр должен быть 1, а не 10.
я2С лучше всего получить спецификацию ведомого устройства и просмотреть документацию по операциям записи и чтения.
Пишите регистры
Вот соответствующая схема из таблицы.
Таким образом , после отправки адреса ведомого к шине, еще три байта должен быть передан: регистр указателя , MSB байт , LSB байт . Общая реализация с записью 16-битных регистров HAL:
void write_register(uint8_t register_pointer, uint16_t register_value)
{
uint8_t data[3];
data[0] = register_pointer; // 0x0C in your example
data[1] = register_value>>8; // MSB byte of 16bit data
data[2] = register_value; // LSB byte of 16bit data
HAL_I2C_Master_Transmit(&hi2c1, 0xA0, data, 3, 100); // data is the start pointer of our array
}
Пример с вашими ценностями: write_register(0x0C, 0x0054);
В качестве альтернативы также может использоваться определенная HAL функция записи в регистр, которая имеет дополнительные параметры для передачи адреса регистра и размера адреса.
void write_register(uint8_t register_pointer, uint16_t register_value)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&hi2c1, 0xA0, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(®ister_value), 2, 100);
/* Check the communication status */
if(status != HAL_OK)
{
// Error handling, for example re-initialization of the I2C peripheral
}
}
Теперь HAL_I2C_Master_Receive()
функция почти такая же, как и у других.
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Разница лишь в том, что третий параметр является указателем на буфер, в котором будут храниться полученные данные . это0x02
в вашем коде, и я не знаю, с какой целью вы его использовали, но он будет интерпретирован как указатель (к сожалению, на случайную ячейку памяти).
Читать регистры
я2Ся2С
void read_register(uint8_t register_pointer, uint8_t* receive_buffer)
{
// first set the register pointer to the register wanted to be read
HAL_I2C_Master_Transmit(&hi2c1, 0xA0, ®ister_pointer, 1, 100); // note the & operator which gives us the address of the register_pointer variable
// receive the 2 x 8bit data into the receive buffer
HAL_I2C_Master_Receive(&hi2c1, 0xA0, receive_buffer, 2, 100);
}
Пример:
uint8_t reg_ptr = 0x0C;
uint8_t buffer[2];
read_register(reg_ptr, buffer);
// the register content available in the buffer
Существует также HAL-определенная функция чтения регистров, которая имеет.
uint16_t read_register(uint8_t register_pointer)
{
HAL_StatusTypeDef status = HAL_OK;
uint16_t return_value = 0;
status = HAL_I2C_Mem_Read(&hi2c1, 0xA0, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, &return_value, 2, 100);
/* Check the communication status */
if(status != HAL_OK)
{
}
return return_value;
}
Прочитайте раздел 8.5 Программирование таблицы данных для более подробной информации.