Vamos começar com a HAL_I2C_Master_Transmit()
função Se você verificar sua declaração:
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Problema menor com o 2º parâmetro, o endereço do dispositivo escravo. O endereço do dispositivo escravo é b1010000
que, se o completarmos no formato 8 bits, será 0xA0
, exatamente como você disse. Agora, ao passar isso para HAL_I2C_Master_Transmit()
você, você não precisa definir o bit R / W manualmente, o HAL fará isso por você. Portanto, quando você chamar HAL_I2C_Master_Transmit()
o bit R / W transmitido, será automaticamente 0 indicando a operação de gravação e quando você chamar HAL_I2C_Master_Receive()
o bit R / W transmitido será automaticamente 1, indicando a operação de gravação . Você misturou os valores de R / W, mas acho que não é um problema para a função, portanto, não é um erro real no seu código.
O terceiro parâmetro ( uint8_t *pData
) é um ponteiro para um buffer que contém os dados a serem enviados . Agora, na sua chamada, o terceiro parâmetro é 0x0C
quais são seus dados reais, o endereço de registro. O problema é que ele será interpretado como um ponteiro (pelo HAL_I2C_Master_Transmit()
) para um local de memória, onde alguns dados indefinidos podem ser encontrados.
O quarto parâmetro é o tamanho do buffer , o número de bytes a serem enviados. Se você deseja enviar um único byte, esse parâmetro deve ser 1 e não 10.
I2C
Gravar registros
Aqui está o diagrama correspondente da folha de dados.
Então, depois de enviar o endereço escravo para o barramento, mais três bytes devem ser transmitidos: ponteiro de registro , byte MSB , byte LSB . Uma implementação geral com registros HAL de gravação de 16 bits:
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
}
Exemplo com seus valores: write_register(0x0C, 0x0054);
Como alternativa, também pode ser usada a função de gravação de registro definida pelo HAL, que possui parâmetros adicionais para a passagem do endereço e tamanho do endereço.
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
}
}
Agora, a HAL_I2C_Master_Receive()
função é quase a mesma que a outra.
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
A única diferença é que o terceiro parâmetro é um ponteiro para o buffer em que os dados recebidos serão armazenados. Ele está 0x02
no seu código e não sei qual era o seu objetivo, mas será interpretado como um ponteiro (infelizmente para um local de memória aleatória).
Ler registros
I2CI2C
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);
}
Exemplo:
uint8_t reg_ptr = 0x0C;
uint8_t buffer[2];
read_register(reg_ptr, buffer);
// the register content available in the buffer
Também existe uma função de leitura de registro definida pelo HAL, que possui.
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;
}
Leia a seção 8.5 Programação da folha de dados para obter mais detalhes.