让我们从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);
第2个参数(从站地址)存在小问题。如您所说,从设备地址是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。
当使用,最好的办法是获取从设备的数据表并查找写入和读取操作的文档。一世2C
写寄存器
这是数据表中的对应图。
因此,在将从机地址发送到总线之后,应再发送三个字节:寄存器指针,MSB字节,LSB字节。HAL写入16位寄存器的一般实现:
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
在您的代码中,我不知道您的用途是什么,但是它将被解释为指针(不幸的是指向随机内存位置)。
读取寄存器
要读取寄存器,必须使用写操作通过发送适当的寄存器指针来对其进行选择(请注意,如果您在读取之前就已写入该寄存器,则不必再次将其地址发送给指针注册,因为您已经在写入过程中进行了设置)。然后通过读取操作,回读16位数据。一世2C一世2C
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编程部分以获取更多详细信息。