HAL_I2C_Master_Transmit()
Fonksiyonla başlayalım . Beyanını kontrol ederseniz:
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
2. parametre, bağımlı cihaz adresi ile ilgili küçük problem . Slave cihaz adresi, b1010000
8bit formatına tamamlarsak 0xA0
, aynen dediğin gibi olacak. Şimdi bunu HAL_I2C_Master_Transmit()
size iletirken R / W bitini manuel olarak ayarlamanıza gerek yok, HAL sizin için yapacak. Böylece HAL_I2C_Master_Transmit()
, iletilen R / W bitini aradığınızda otomatik olarak 0 yazarak yazma işlemi gösterilir ve HAL_I2C_Master_Receive()
ilettiğiniz R / W biti otomatik olarak 1 yazarak yazma işlemini gösterir . R / W değerlerini karıştırdınız, ancak işlev için umursamadığınızı düşünüyorum, bu yüzden kodunuzda gerçek bir hata değil.
3. parametresi ( uint8_t *pData
) a, bir tampon için işaretçi ihtiva gönderilen verileri . Şimdi, aramanızda 3. parametre 0x0C
gerçek verileriniz olan kayıt adresidir. Sorun şu ki, HAL_I2C_Master_Transmit()
bazı tanımlanmamış verilerin bulunabileceği bir bellek konumuna bir işaretçi (tarafından ) olarak yorumlanacaktır .
4. parametredir tampon boyutu , bayt sayısı gönderecektir. Tek bir bayt göndermek istiyorsanız, bu parametre 10 değil 1 olmalıdır .
ben2C
Kayıt yazma
İşte veri sayfasındaki ilgili diyagram.
Slave adresi veri yoluna gönderildikten sonra, üç bayt daha iletilmelidir: kayıt işaretçisi , MSB baytı , LSB baytı . HAL yazma 16 bit kayıtları ile genel bir uygulama:
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
}
Değerlerinizle örnek: write_register(0x0C, 0x0054);
Alternatif olarak, kayıt adresini ve adres boyutunu iletmek için ek parametrelere sahip HAL tanımlı yazma yazma fonksiyonu da kullanılabilir.
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
}
}
Şimdi, HAL_I2C_Master_Receive()
fonksiyon neredeyse diğeriyle aynı.
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
Tek fark, 3. parametrenin alınan verinin saklanacağı tamponun bir göstergesidir . Öyle 0x02
Kodunuzdaki ve onunla amacınız neydi bilmiyorum ama (maalesef rastgele bellek konumuna) bir işaretçi olarak yorumlanır.
Kayıtları oku
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);
}
Misal:
uint8_t reg_ptr = 0x0C;
uint8_t buffer[2];
read_register(reg_ptr, buffer);
// the register content available in the buffer
Ayrıca bir HAL tanımlı yazmaç okuma fonksiyonu da vardır.
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;
}
Daha fazla bilgi için veri sayfasının 8.5 Programlama bölümünü okuyun .