Địa chỉ các thanh ghi với các thư viện I2C STM32F0 HAL


12

Tôi rất mới sử dụng CUBE và HAL_l Library của STM. Tôi đang sử dụng một vi điều khiển STM32F0 với 32 chân. Các sơ đồ cho I2C là chính xác. Vì vậy, tôi cần một chút giúp đỡ ở đây.

Tôi có một cảm biến điện dung ( FDC1004 ) sử dụng giao tiếp I2C. Tôi phải viết các thanh ghi này để đọc dữ liệu.

Làm thế nào tôi có thể gửi chính xác mẫu yêu cầu BẮT ĐẦU tới nô lệ (địa chỉ nô lệ là A0)?

Làm cách nào để đặt con trỏ đến thanh ghi 0x0C?

  • Datasheet thấy (Đăng ký 0x0C: bit [7: 4]) thành 1.) Tôi không biết, làm thế nào để làm điều đó? Và cuối cùng làm thế nào để ĐỌC từ cùng một đăng ký?
  • Ngoài ra, tôi phải đợi trường DONE_x (Đăng ký 0x0C: bits [3: 0]) trước khi tôi đọc nó?

Nhưng tôi không biết nếu tôi giải quyết đúng sổ đăng ký! Bởi vì tôi không nhận được bất kỳ dữ liệu nào từ cảm biến!

Đây là mã của tôi:

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

Vui lòng hỏi một câu hỏi cụ thể hơn. Làm thế nào để tôi giải quyết đăng ký X đúng cách? Đây là một câu hỏi tồi. Để biết thêm hướng dẫn, hãy xem Electronics.stackexchange.com/help/how-to-ask
Điện áp tăng đột biến vào

Sau đó, tốt hơn là viết một câu hỏi mới hoặc chỉ cần chỉnh sửa câu hỏi này?
yest111

Tốt hơn để chỉnh sửa, ít câu hỏi hơn và chúng tôi sẽ không phải đóng cái này.
Điện áp tăng đột biến

Câu trả lời:


16

Hãy bắt đầu với HAL_I2C_Master_Transmit()chức năng. Nếu bạn kiểm tra khai báo của nó:

 HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
  1. Vấn đề nhỏ với tham số thứ 2 , địa chỉ thiết bị nô lệ. Địa chỉ thiết bị nô lệ là b1010000nếu chúng tôi hoàn thành định dạng 8 bit, nó sẽ 0xA0giống như bạn đã nói. Bây giờ khi chuyển cái này cho HAL_I2C_Master_Transmit()bạn không phải thiết lập bit R / W theo cách thủ công, HAL sẽ làm điều đó cho bạn. Vì vậy, khi bạn gọi HAL_I2C_Master_Transmit()bit R / W được truyền sẽ tự động 0 chỉ báo hoạt động ghi và khi bạn gọi HAL_I2C_Master_Receive()bit R / W được truyền sẽ tự động 1 chỉ báo hoạt động ghi . Bạn đã trộn các giá trị R / W nhưng tôi nghĩ rằng đó là một chút không quan tâm đến hàm, vì vậy nó không phải là một lỗi thực tế trong mã của bạn.

  2. Các thứ 3 tham số ( uint8_t *pData) là một con trỏ đến một bộ đệm chứa dữ liệu được gửi . Bây giờ, trong cuộc gọi của bạn, tham số thứ 30x0Cdữ liệu thực tế của bạn, địa chỉ đăng ký. Vấn đề là, nó sẽ được hiểu là một con trỏ (theo HAL_I2C_Master_Transmit()) đến một vị trí bộ nhớ, nơi có thể tìm thấy một số dữ liệu không xác định.

  3. Các thứ 4 tham số là kích thước của bộ đệm , số byte được gửi đi. Nếu bạn muốn gửi một byte đơn thì tham số này phải là 1 chứ không phải 10.

I2C

Viết sổ đăng ký

Đây là sơ đồ tương ứng từ biểu dữ liệu.

nhập mô tả hình ảnh ở đây

Vì vậy, sau khi gửi địa chỉ nô lệ đến bus, cần truyền thêm ba byte: con trỏ thanh ghi , byte MSB , byte LSB . Một triển khai chung với HAL viết các thanh ghi 16 bit:

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
}

Ví dụ với các giá trị của bạn: write_register(0x0C, 0x0054);

Ngoài ra, chức năng ghi thanh ghi được xác định HAL cũng có thể được sử dụng, có các tham số bổ sung để truyền địa chỉ thanh ghi và kích thước địa chỉ.

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

Bây giờ, HAL_I2C_Master_Receive()chức năng gần giống như khác.

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

Chỉ khác là tham số thứ 3 là một con trỏ tới bộ đệm nơi dữ liệu nhận được sẽ được lưu trữ. Nó nằm 0x02trong mã của bạn và tôi không biết mục đích của bạn với nó là gì, nhưng nó sẽ được hiểu là một con trỏ (không may là một vị trí bộ nhớ ngẫu nhiên).

Đọc sổ đăng ký

nhập mô tả hình ảnh ở đây

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

Thí dụ:

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

read_register(reg_ptr, buffer);

// the register content available in the buffer

Ngoài ra còn có một chức năng đọc thanh ghi được xác định HAL là tốt, trong đó có.

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

Đọc qua phần Lập trình 8,5 của biểu dữ liệu để biết thêm chi tiết.


Cảm ơn bạn đã trả lời của bạn, bây giờ nó cuối cùng đã làm việc. Nhưng thêm một câu hỏi nữa? Tôi có phải đợi một vài giây bí mật để đọc hay tôi có thể đọc mà không bị chậm trễ?
yest111

Tôi không nghĩ rằng bất kỳ sự chậm trễ là cần thiết, bạn có thể thử mà không cần bất kỳ sự chậm trễ nào.
Bence Kaulics

1
Bạn không cần chờ đợi, I2C liên quan đến việc lặp tín hiệu đồng hồ cho đến khi nô lệ hoàn thành.
Mahmoud Al-Qudsi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.