Đối với tài liệu tham khảo: vấn đề tương tự được mô tả ở đó, nhưng giải pháp của tác giả không phù hợp với tôi - I2C bận cờ hành vi lạ
Tôi đã sử dụng STM32CubeMX để tạo mẫu dự án với khởi tạo ngoại vi I2C. Thật không may, nó hoạt động bằng cách nào đó kỳ lạ: sau khi HAL_I2C_MspInit(I2C1)
được gọi, xe buýt được coi là bận rộn vĩnh viễn.
Nếu tôi cố gắng áp dụng
__HAL_RCC_I2C1_FORCE_RESET();
HAL_Delay(1000);
__HAL_RCC_I2C1_RELEASE_RESET();
Điều đó giải quyết vấn đề với BUSY
cờ, nhưng gây ra sự cố - SB
bit không được đặt sau khi START
được tạo. Theo trình gỡ lỗi, các thanh ghi I2C bị xóa hoàn toàn sau khi thiết lập lại - tôi nghi ngờ đây là vấn đề với phương thức đó.
Tôi cũng thú nhận sự sụt giảm điện áp ngắn ở đường SDA trong khi khởi động, đó có lẽ là nguyên nhân của vấn đề. Tôi đã xem xét kỹ hơn về mã khởi tạo chân SDA / SCL được tạo bởi CubeMX:
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
Tôi đã thay đổi nó để kích hoạt đồng hồ trước khi HAL_GPIO_Init()
gọi và bây giờ giao tiếp I2C của tôi hoạt động (ít nhất là tôi chưa nhận thấy điều gì kỳ lạ).
Cuối cùng, câu hỏi của tôi là - có giải pháp nào tốt hơn cho việc này không? CubeMX đặt mã kích hoạt đồng hồ sau khi gọi phương thức khởi tạo GPIO. Tôi có thể ở lại với hai yêu cầu __HAL_RCC_I2C1_CLK_ENABLE()
, nhưng theo tôi thì khá là xấu, vì vậy tôi đang tìm kiếm bất kỳ giải pháp nào tốt hơn, cả phần mềm hoặc phần cứng.
Thiết bị là STM32F100RB trên bảng STM32VLDiscovery (với STLink v1), trong trường hợp có vấn đề.