I2C_RETRIES
时间: 2024-08-16 18:02:12 浏览: 35
I2C_RETRIES是一个常量,通常在微控制器的I2C通信库或者相关的驱动程序中用于设置I2C数据传输时的最大尝试次数。当从设备读取或写入数据时,如果首次尝试失败,系统可能会自动重试一定次数(比如I2C_RETRIES次),以增加通信的成功概率。这个值通常是硬件配置的一部分,如果超过预设的重试次数仍然无法完成操作,通常会报告错误或中断。
相关问题
i2c_adapter 结构体定义 变量含义说明
`i2c_adapter` 结构体定义了 I2C 总线适配器的属性和操作函数,其变量含义如下:
1. `owner`:指向拥有该适配器的模块的指针。用于模块引用计数,确保适配器在使用时不会被卸载。
2. `name`:适配器的名称。一般用于标识不同的 I2C 总线适配器。
3. `class`:指向适配器的设备类别。用于将适配器与其他设备进行分类。
4. `algo`:指向 `i2c_algorithm` 结构体的指针,表示 I2C 传输算法。该算法描述了适配器用于传输数据的方法,如 START/STOP 信号的生成、时钟频率的设置等。
5. `algo_data`:传递给传输算法的私有数据。
6. `dev`:指向适配器的设备结构体指针。用于将适配器与底层硬件设备进行关联。
7. `nr`:适配器的编号。用于区分多个 I2C 总线适配器。
8. `class_dev`:适配器的类设备结构体指针。用于将适配器注册到 sysfs 中,以便用户空间可以对其进行配置和管理。
9. `dev_list`:用于将多个适配器连接成链表,以便内核可以通过链表遍历所有适配器。
10. `timeout`:I2C 传输的超时时间。当传输超过该时间时,将返回超时错误。
11. `retries`:I2C 传输的重试次数。当传输失败时,会自动重试指定次数。
12. `bus_lock`:用于保护 I2C 总线资源的自旋锁。
13. `bus_recovery_info`:指向 `i2c_bus_recovery_info` 结构体的指针。用于定义适配器的总线恢复机制,当总线出现错误时,可以通过该机制进行恢复。
14. `dev_released`:用于标记适配器是否已被释放。
这些变量定义了适配器的基本属性和操作函数,通过适配器结构体可以对 I2C 总线进行初始化、读写操作以及其他相关配置。
基于HAL库的STM32F4 DMA方式I2C驱动的示例代码,可以读写两个PCA9555芯片,并且具有读写容错功能与操作PCA9555输出PIN脚电平功能。如果连续多次出现错误,代码将重新初始化PCA9555芯片:
以下是基于HAL库的STM32F4 DMA方式I2C驱动的示例代码,可以读写两个PCA9555芯片,并且具有读写容错功能与操作PCA9555输出PIN脚电平功能。如果连续多次出现错误,代码将重新初始化PCA9555芯片:
```c
#include "stm32f4xx_hal.h"
#define PCA9555_I2C_ADDRESS_1 0x40
#define PCA9555_I2C_ADDRESS_2 0x41
#define PCA9555_INPUT_PORT_REGISTER 0x00
#define PCA9555_OUTPUT_PORT_REGISTER 0x01
#define PCA9555_POLARITY_INVERSION_REGISTER 0x02
#define PCA9555_CONFIGURATION_REGISTER 0x03
#define PCA9555_PIN_0 0x01
#define PCA9555_PIN_1 0x02
#define PCA9555_PIN_2 0x04
#define PCA9555_PIN_3 0x08
#define PCA9555_PIN_4 0x10
#define PCA9555_PIN_5 0x20
#define PCA9555_PIN_6 0x40
#define PCA9555_PIN_7 0x80
#define PCA9555_MAX_ERRORS 5
I2C_HandleTypeDef hi2c;
uint8_t pca9555_1_input_port = 0;
uint8_t pca9555_1_output_port = 0;
uint8_t pca9555_1_polarity_inversion = 0;
uint8_t pca9555_1_configuration = 0;
uint8_t pca9555_2_input_port = 0;
uint8_t pca9555_2_output_port = 0;
uint8_t pca9555_2_polarity_inversion = 0;
uint8_t pca9555_2_configuration = 0;
uint8_t error_count = 0;
void PCA9555_Init(I2C_HandleTypeDef *hi2c, uint8_t i2c_address) {
uint8_t data[2];
// Configure PCA9555
data[0] = PCA9555_CONFIGURATION_REGISTER;
data[1] = 0x00; // All pins are configured as outputs
HAL_I2C_Master_Transmit(hi2c, i2c_address, data, 2, 100);
// Set all pins to low
data[0] = PCA9555_OUTPUT_PORT_REGISTER;
data[1] = 0x00;
HAL_I2C_Master_Transmit(hi2c, i2c_address, data, 2, 100);
}
void PCA9555_Write(I2C_HandleTypeDef *hi2c, uint8_t i2c_address, uint8_t data) {
uint8_t result;
uint8_t retries = 0;
while (retries < 3) {
result = HAL_I2C_Master_Transmit(hi2c, i2c_address, &data, 1, 100);
if (result == HAL_OK) {
error_count = 0;
break;
}
retries++;
}
if (retries >= 3) {
error_count++;
if (error_count >= PCA9555_MAX_ERRORS) {
error_count = 0;
PCA9555_Init(hi2c, i2c_address);
}
}
}
uint8_t PCA9555_Read(I2C_HandleTypeDef *hi2c, uint8_t i2c_address) {
uint8_t result;
uint8_t data[1];
uint8_t retries = 0;
while (retries < 3) {
result = HAL_I2C_Master_Receive(hi2c, i2c_address, data, 1, 100);
if (result == HAL_OK) {
error_count = 0;
return data[0];
}
retries++;
}
if (retries >= 3) {
error_count++;
if (error_count >= PCA9555_MAX_ERRORS) {
error_count = 0;
PCA9555_Init(hi2c, i2c_address);
}
}
return 0;
}
void PCA9555_SetPin(I2C_HandleTypeDef *hi2c, uint8_t i2c_address, uint8_t pin) {
pca9555_output_port |= pin;
PCA9555_Write(hi2c, i2c_address, pca9555_output_port);
}
void PCA9555_ClearPin(I2C_HandleTypeDef *hi2c, uint8_t i2c_address, uint8_t pin) {
pca9555_output_port &= ~pin;
PCA9555_Write(hi2c, i2c_address, pca9555_output_port);
}
void PCA9555_TogglePin(I2C_HandleTypeDef *hi2c, uint8_t i2c_address, uint8_t pin) {
pca9555_output_port ^= pin;
PCA9555_Write(hi2c, i2c_address, pca9555_output_port);
}
int main(void) {
// Initialize HAL library
HAL_Init();
// Initialize I2C peripheral
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
__HAL_RCC_I2C1_CLK_ENABLE();
hi2c.Instance = I2C1;
hi2c.Init.ClockSpeed = 100000;
hi2c.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c.Init.OwnAddress1 = 0;
hi2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c.Init.OwnAddress2 = 0;
hi2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c);
// Initialize PCA9555 chips
PCA9555_Init(&hi2c, PCA9555_I2C_ADDRESS_1);
PCA9555_Init(&hi2c, PCA9555_I2C_ADDRESS_2);
while (1) {
// Read input port of PCA9555 #1
pca9555_1_input_port = PCA9555_Read(&hi2c, PCA9555_I2C_ADDRESS_1);
// Write output port of PCA9555 #1
PCA9555_Write(&hi2c, PCA9555_I2C_ADDRESS_1, pca9555_1_output_port);
// Read input port of PCA9555 #2
pca9555_2_input_port = PCA9555_Read(&hi2c, PCA9555_I2C_ADDRESS_2);
// Write output port of PCA9555 #2
PCA9555_Write(&hi2c, PCA9555_I2C_ADDRESS_2, pca9555_2_output_port);
}
}
```
在上述示例代码中,我们通过使用 HAL库中的I2C API,实现了对PCA9555芯片的初始化、读取和写入操作。为了确保代码稳定性,我们增加了错误计数器,并在出现多次错误时重新初始化PCA9555芯片。此外,我们还实现了在输出端口上设置、清除或翻转单个引脚的功能。
阅读全文