I2C STM32F0 HAL kütüphaneleriyle kayıtları adresleme


12

STM'nin CUBE ve HAL_libraries'ini kullanmakta çok yeniyim. 32 pimli bir STM32F0 mikrodenetleyici kullanıyorum. I2C için şema doğrudur. Burada biraz yardıma ihtiyacım var.

I2C iletişimini kullanan bir kapasitif sensöre ( FDC1004 ) sahibim . Verileri okumak için bu kayıtları yazmak zorundayım.

BAŞLANGIÇ istek formu yöneticisini slave'e nasıl doğru şekilde gönderebilirim (slave adresi A0)?

İşaretçiyi 0x0C kaydına nasıl ayarlayabilirim?

  • Veri sayfası (Kayıt 0x0C: bit [7: 4]) 1'e bakar.) Bilmiyorum, nasıl yapılır? Ve son olarak aynı kayıttan nasıl okunur?
  • Ayrıca okumadan önce DONE_x alanını (Kayıt 0x0C: bit [3: 0]) beklemek zorunda mıyım?

Ama doğru kayıtları ele alıp almadığımı bilmiyorum! Çünkü sensörden veri almıyorum!

İşte benim kod:

int I2Ccomm ()
{

    HAL_I2C_Master_Transmit(&hi2c1,0xA1,0x0C, 10, 100); //start bit and pointer to register
    HAL_Delay(50);
    HAL_I2C_Master_Transmit(&hi2c1,0xA1,0x054, 10, 100); // setting the register
    HAL_Delay(50);

    HAL_I2C_Master_Receive(&hi2c1, 0xA0, 0x0C, 10, 100); //read from this register
    HAL_Delay(50);
    HAL_I2C_Master_Receive(&hi2c1, 0xA0, 0x02, 10, 100); //read data from register

    return ReadREG[1];
}

Lütfen daha spesifik bir soru sorun. Nasıl X kayıt düzgün adres? Bu kötü ifade edilen bir soru. Daha fazla kılavuz için bkz. Electronics.stackexchange.com/help/how-to-ask
Voltaj

O zaman yeni bir soru yazmak veya bunu düzenlemek daha mı iyi?
yest111

Daha iyi düzenlemek, daha az soru ve bunu kapatmak zorunda kalmayacağız.
Voltaj

Yanıtlar:


16

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);
  1. 2. parametre, bağımlı cihaz adresi ile ilgili küçük problem . Slave cihaz adresi, b10100008bit 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.

  2. 3. parametresi ( uint8_t *pData) a, bir tampon için işaretçi ihtiva gönderilen verileri . Şimdi, aramanızda 3. parametre 0x0Cgerç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 .

  3. 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 .

I2C

Kayıt yazma

İşte veri sayfasındaki ilgili diyagram.

resim açıklamasını buraya girin

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*)(&register_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 0x02Kodunuzdaki ve onunla amacınız neydi bilmiyorum ama (maalesef rastgele bellek konumuna) bir işaretçi olarak yorumlanır.

Kayıtları oku

resim açıklamasını buraya girin

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, &register_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 .


Cevabınız için teşekkür ederim, şimdi işe yarıyor. Ama bir soru daha? Okumak için birkaç mili saniye beklemek zorunda mıyım yoksa gecikmeden okuyabilir miyim?
yest111

Herhangi bir gecikmenin gerekli olduğunu düşünmüyorum, ilk önce deneyebilirsiniz.
Bence Kaulics

1
Beklemenize gerek yok, I2C, slave tamamlanana kadar saat sinyalinde döngü yapmayı içerir.
Mahmoud Al-Qudsi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.