Showing results for 
Search instead for 
Did you mean: 

I don't understand how to use the HAL_I2C_Master_Transmit function. RTC DS3231

Senior II

I am using I2C to transfer data from STM32F4 to DS3231 Real Time Clock registers.

HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

*hi2c - I2C structure
DevAddress - Device address

*pData - I don't understand this parameter.
It is written on the Internet that this is a pointer for data, but this pointer is used to transfer the register address in the Slave device.

Size - data size in Bytes.

What parameter should the data be passed?

I can use the HAL_I2C_Mem_Write function. This function has a parameter for data transfer.
This parameter is also called *pData
HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)


int main()
uint8_t RegisterAddress=0x0;
HAL_I2C_Master_Transmit(&hi2c1, 0xD0, &RegisterAddress, 1, 1000 );


I think that something is wrong with the &RegisterAddress parameter, but I don’t understand how it will be right.

As a result, I need to write data to the I2C Slave Device at the address I chose.



@MMust.5 wrote:

I did not find any extended information on the HAL_I2C_Master_Transmit function.
There are a lot of incorrect codes on the Internet with this function, there are even videos on YouTube with the incorrect use of HAL_I2C_Master_Transmit.
Only TDK explained to me how to use this function correctly.




It might be interesting to study the C language, there are tutorials on the internet.

Before asking a question, I tried many times to figure it out myself.
Why do I need links to Wikipedia in the topic?
You send me to learn C, as if I were asking about the operation of the printf function.
Thanks, but I don't need any more instructions from you.

I describe all my questions in great detail, trying to help not only myself, but also those who will be looking for an answer to this question.
Your "very necessary instructions" filled my entire topic.
To be honest, this is the first time I've seen this on this forum.

I found the answer, thanks.
Exactly the same as I expected. My last code was almost correct.
First you need to send the address of the register, and then read from this register with the HAL_I2C_Master_Receive function.
I had an error in my code
It was necessary to transfer a pointer to the address of the register, but I transferred 0x0.


uint8_t data[2]={0,7};
uint8_t result[10]={0};
HAL_I2C_Master_Transmit(&hi2c1, 0xD0,data, 2, 1000 );
HAL_I2C_Master_Transmit(&hi2c1, 0xD0,&data[0], 1, 1000 );  //Reading from register
HAL_I2C_Master_Receive(&hi2c1, 0xD1, result, 1, 1000 );    //Reading from register
printf("%x\n", result[0]);
Pavel A.
Evangelist III

Well, now it is clear that you don't know about I2C "repeated start" transactions (write then read in one transaction). You may want to google/bing/chatgpt it for better understanding.  HAL_I2C_Mem_Read does the "repeated start" thing.

I don't use HAL_I2C_Mem_Read
Yes, I know that HAL_I2C_Mem_Read reads the value at the selected address in one function.

What makes this function unique is that it first performs an I2C transmit operation to tell the slave device what memory address to source the data from. This is followed by a repeated start condition to begin the receive operation. The complete I2C sequence is shown below. Note that HAL_I2C_Mem_Read() is the only function capable of generating a repeated start condition in blocking mode. If a repeated start is required, it is not sufficient to call HAL_I2C_Master_Transmit() immediately followed by a call to HAL_I2C_Master_Receive().

My task was to do exactly that with the HAL_I2C_Master_Receive function.
The issue has been resolved, thanks everyone.