Comencemos con la HAL_I2C_Master_Transmit()
función. Si revisas su declaración:
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Problema menor con el segundo parámetro, la dirección del dispositivo esclavo. La dirección del dispositivo esclavo es b1010000
si la completamos en formato de 8 bits, será 0xA0
, tal como usted dijo. Ahora, al pasarle esto HAL_I2C_Master_Transmit()
, no tiene que configurar el bit R / W manualmente, HAL lo hará por usted. Entonces, cuando llame HAL_I2C_Master_Transmit()
al bit R / W transmitido, será automáticamente 0 lo que indica la operación de escritura y cuando llame HAL_I2C_Master_Receive()
al bit R / W transmitido será automáticamente 1 lo que indica la operación de escritura . Ha mezclado los valores R / W, pero creo que es un poco no importa la función, por lo que no es un error real en su código.
El tercer parámetro ( uint8_t *pData
) es un puntero a un búfer que contiene los datos que se enviarán . Ahora, en su llamada, el tercer parámetro es 0x0C
cuál es su información real, la dirección de registro. El problema es que se interpretará como un puntero (por el HAL_I2C_Master_Transmit()
) a una ubicación de memoria, donde se pueden encontrar algunos datos indefinidos.
El cuarto parámetro es el tamaño del búfer , el número de bytes que se enviarán. Si desea enviar un solo byte, este parámetro debe ser 1 y no 10.
yo2C
Escribir registros
Aquí está el diagrama correspondiente de la hoja de datos.
Entonces, después de enviar la dirección del esclavo al bus, se deben transmitir tres bytes más: puntero de registro , byte MSB , byte LSB . Una implementación general con HAL escribiendo registros 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
}
Ejemplo con tus valores: write_register(0x0C, 0x0054);
Alternativamente, también se puede utilizar la función de escritura de registro definida por HAL, que tiene parámetros adicionales para pasar la dirección de registro y el tamaño de la dirección.
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
}
}
Ahora, la HAL_I2C_Master_Receive()
función es casi la misma que la otra.
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
La única diferencia es que el tercer parámetro es un puntero al búfer donde se almacenarán los datos recibidos . Está 0x02
en su código y no sé cuál fue su propósito con él, pero se interpretará como un puntero (desafortunadamente a una ubicación de memoria aleatoria).
Leer registros
yo2Cyo2C
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);
}
Ejemplo:
uint8_t reg_ptr = 0x0C;
uint8_t buffer[2];
read_register(reg_ptr, buffer);
// the register content available in the buffer
También hay una función de lectura de registro definida por HAL, que tiene.
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;
}
Lea la sección 8.5 Programación de la hoja de datos para obtener más detalles.