Zacznijmy od HAL_I2C_Master_Transmit()
funkcji. Jeśli sprawdzisz jego deklarację:
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Drobny problem z drugim parametrem, adresem urządzenia podrzędnego. Adres urządzenia podrzędnego to, b1010000
jeśli uzupełnimy go do formatu 8-bitowego, będzie tak 0xA0
, jak powiedziałeś. Teraz, gdy przekazujesz to do HAL_I2C_Master_Transmit()
ciebie, nie musisz ręcznie ustawiać bitu R / W, HAL zrobi to za ciebie. Tak więc, kiedy wywołasz HAL_I2C_Master_Transmit()
transmitowany bit R / W, automatycznie wyniesie 0, co oznacza operację zapisu, a kiedy wywołasz HAL_I2C_Master_Receive()
transmitowany bit R / W, automatycznie wyniesie 1, wskazując operację zapisu . Zmieszałeś wartości R / W, ale myślę, że to nie obchodzi mnie funkcja, więc nie jest to prawdziwy błąd w kodzie.
3-ci parametrów ( uint8_t *pData
) stanowi wskaźnik na bufor , który zawiera dane do wysłania . Teraz w rozmowie trzecim parametrem 0x0C
jest Twoje rzeczywiste dane, adres rejestru. Problem polega na tym, że zostanie zinterpretowany jako wskaźnik (do HAL_I2C_Master_Transmit()
) w miejscu pamięci, w którym można znaleźć niektóre niezdefiniowane dane.
4-ci parametrem jest wielkość bufora , liczba bajtów do wysłania. Jeśli chcesz wysłać pojedynczy bajt, ten parametr powinien wynosić 1, a nie 10.
ja2)do
Napisz rejestry
Oto odpowiedni schemat z arkusza danych.
Więc po wysłaniu adresu slave do autobusu, trzy kolejne bajty powinny być przesyłane: zarejestruj wskaźnik , MSB bajt , LSB bajt . Ogólna implementacja z rejestrowaniem 16-bitowych rejestrów 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
}
Przykład z twoimi wartościami: write_register(0x0C, 0x0054);
Alternatywnie można również użyć funkcji zapisu rejestru zdefiniowanej w HAL, która ma dodatkowe parametry do przekazywania adresu rejestru i wielkości adresu.
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
}
}
Teraz HAL_I2C_Master_Receive()
funkcja jest prawie taka sama jak druga.
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Jedyną różnicą jest to, że trzeci parametr jest wskaźnikiem do bufora, w którym będą przechowywane odebrane dane . Jest 0x02
w twoim kodzie i nie wiem, jaki był twój cel, ale będzie interpretowany jako wskaźnik (niestety do przypadkowej lokalizacji w pamięci).
Czytaj rejestry
ja2)doja2)do
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);
}
Przykład:
uint8_t reg_ptr = 0x0C;
uint8_t buffer[2];
read_register(reg_ptr, buffer);
// the register content available in the buffer
Istnieje również funkcja odczytu rejestru zdefiniowana przez HAL, która ma.
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;
}
Zapoznaj się z częścią 8.5 dotyczącą programowania w arkuszu danych, aby uzyskać więcej informacji.