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.