Mengatasi register dengan perpustakaan HAL I2C STM32F0

12

Saya sangat baru menggunakan CUBE dan HAL_libraries STM. Saya menggunakan mikrokontroler STM32F0 dengan 32 pin. Skema untuk I2C benar. Jadi saya butuh sedikit bantuan di sini.

Saya memiliki sensor kapasitif ( FDC1004 ) yang menggunakan komunikasi I2C. Saya harus menulis register ini untuk membaca data.

Bagaimana saya bisa mengirim master formulir permintaan START ke slave dengan benar (alamat slave A0)?

Bagaimana cara mengatur pointer ke register 0x0C?

  • Datasheet melihat (Daftarkan 0x0C: bit [7: 4]) ke 1.) Saya tidak tahu, bagaimana cara melakukannya? Dan akhirnya bagaimana BACA dari register yang sama?
  • Ditambah lagi, saya harus menunggu bidang DONE_x (Daftar 0x0C: bit [3: 0]) sebelum saya membacanya?

Tapi saya tidak tahu apakah saya menangani register yang tepat! Karena saya tidak mendapatkan data apa pun dari sensor!

Ini kode saya:

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];
}
yest111
sumber
Silakan ajukan pertanyaan yang lebih spesifik. seperti Bagaimana cara mengatasi X mendaftar dengan benar? Ini adalah pertanyaan dengan kata-kata yang buruk. Untuk panduan lebih lanjut, lihat electronics.stackexchange.com/help/how-to-ask
Voltage Spike
Lalu apakah lebih baik menulis pertanyaan baru atau hanya mengedit yang ini?
yest111
Lebih baik diedit, lebih sedikit pertanyaan dan kami tidak harus menutup yang ini.
Voltage Spike

Jawaban:

16

Mari kita mulai dengan HAL_I2C_Master_Transmit()fungsinya. Jika Anda memeriksa deklarasi:

 HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
  1. Masalah kecil dengan parameter ke - 2 , alamat perangkat slave. Alamat perangkat slave adalah b1010000jika kita melengkapi ke format 8bit, itu akan menjadi 0xA0, seperti yang Anda katakan. Sekarang ketika meneruskan ini kepada HAL_I2C_Master_Transmit()Anda tidak harus mengatur bit R / W secara manual, HAL akan melakukannya untuk Anda. Jadi ketika Anda memanggil HAL_I2C_Master_Transmit()bit R / W yang ditransmisikan akan secara otomatis 0 mengindikasikan operasi tulis dan ketika Anda memanggil HAL_I2C_Master_Receive()bit R / W yang ditransmisikan akan secara otomatis 1 mengindikasikan operasi tulis . Anda telah mencampur nilai-nilai R / W tetapi saya pikir ini sedikit tidak peduli untuk fungsi, jadi itu bukan kesalahan aktual dalam kode Anda.

  2. Parameter ke - 3 ( uint8_t *pData) adalah penunjuk ke buffer yang berisi data yang akan dikirim . Sekarang, dalam panggilan Anda, parameter ke - 3 adalah 0x0Cdata aktual Anda, alamat register. Masalahnya adalah, itu akan ditafsirkan sebagai pointer (oleh HAL_I2C_Master_Transmit()) ke lokasi memori, di mana beberapa data yang tidak ditentukan dapat ditemukan.

  3. Parameter ke - 4 adalah ukuran buffer , jumlah byte yang akan dikirim. Jika Anda ingin mengirim satu byte maka parameter ini harus 1 dan bukan 10.

saya2C

Tulis register

Berikut adalah diagram yang sesuai dari lembar data.

masukkan deskripsi gambar di sini

Jadi setelah mengirim alamat slave ke bus, tiga byte lagi harus dikirim: register pointer , MSB byte , LSB byte . Implementasi umum dengan register HAL menulis 16bit:

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
}

Contoh dengan nilai-nilai Anda: write_register(0x0C, 0x0054);

Atau, fungsi tulis register HAL yang ditentukan dapat digunakan juga, yang memiliki parameter tambahan untuk meneruskan alamat register dan ukuran alamat.

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
    }
}

Sekarang, HAL_I2C_Master_Receive()fungsinya hampir sama dengan yang lain.

HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);

Satu-satunya perbedaan adalah bahwa parameter ke - 3 adalah pointer ke buffer di mana data yang diterima akan disimpan. Ada 0x02dalam kode Anda dan saya tidak tahu apa tujuan Anda dengan itu, tetapi itu akan ditafsirkan sebagai pointer (sayangnya ke lokasi memori acak).

Baca register

masukkan deskripsi gambar di sini

saya2Csaya2C

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);   
}

Contoh:

uint8_t reg_ptr = 0x0C;
uint8_t buffer[2];

read_register(reg_ptr, buffer);

// the register content available in the buffer

Ada juga fungsi baca register HAL didefinisikan juga, yang memiliki.

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;
}

Baca melalui 8.5 Bagian pemrograman pada lembar data untuk detail lebih lanjut.

Bence Kaulics
sumber
Terima kasih atas jawaban Anda, sekarang akhirnya bekerja. Tapi satu pertanyaan lagi? Apakah saya harus menunggu beberapa mili detik untuk membaca atau dapatkah saya membaca tanpa penundaan?
yest111
Saya tidak berpikir bahwa keterlambatan diperlukan, Anda dapat mencoba tanpa terlebih dahulu.
Bence Kaulics
1
Anda tidak perlu menunggu, I2C melibatkan pengulangan pada sinyal jam sampai budak selesai.
Mahmoud Al-Qudsi