基于HAL库的STM32F4 I2C驱动的示例代码,可以读写两个PCA9555芯片,并且具有读写容错功能与操作PCA9555输出PIN脚电平功能。如果连续多次出现错误,代码将重新初始化PCA9555芯片
时间: 2023-06-27 21:03:36 浏览: 677
以下是基于HAL库的STM32F4 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_REG 0x00
#define PCA9555_OUTPUT_PORT_REG 0x01
#define PCA9555_POLARITY_INVERSION_REG 0x02
#define PCA9555_CONFIGURATION_REG 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_PIN_ALL 0xFF
#define PCA9555_MAX_RETRY 3
I2C_HandleTypeDef hi2c1;
uint8_t pca9555_write(I2C_HandleTypeDef* hi2c, uint8_t address, uint8_t reg, uint8_t data)
{
uint8_t buffer[2];
buffer[0] = reg;
buffer[1] = data;
uint8_t retry = 0;
while (HAL_I2C_Master_Transmit(hi2c, address, buffer, 2, 1000) != HAL_OK)
{
retry++;
if (retry >= PCA9555_MAX_RETRY)
{
return 0;
}
HAL_I2C_DeInit(hi2c);
HAL_I2C_Init(hi2c);
}
return 1;
}
uint8_t pca9555_read(I2C_HandleTypeDef* hi2c, uint8_t address, uint8_t reg, uint8_t* data)
{
uint8_t buffer[1];
buffer[0] = reg;
uint8_t retry = 0;
while (HAL_I2C_Master_Transmit(hi2c, address, buffer, 1, 1000) != HAL_OK)
{
retry++;
if (retry >= PCA9555_MAX_RETRY)
{
return 0;
}
HAL_I2C_DeInit(hi2c);
HAL_I2C_Init(hi2c);
}
retry = 0;
while (HAL_I2C_Master_Receive(hi2c, address, data, 1, 1000) != HAL_OK)
{
retry++;
if (retry >= PCA9555_MAX_RETRY)
{
return 0;
}
HAL_I2C_DeInit(hi2c);
HAL_I2C_Init(hi2c);
}
return 1;
}
void pca9555_set_pin_output_level(I2C_HandleTypeDef* hi2c, uint8_t address, uint8_t pin, uint8_t level)
{
uint8_t data;
pca9555_read(hi2c, address, PCA9555_OUTPUT_PORT_REG, &data);
if (level == 0)
{
data &= ~pin;
}
else
{
data |= pin;
}
pca9555_write(hi2c, address, PCA9555_OUTPUT_PORT_REG, data);
}
void pca9555_init(I2C_HandleTypeDef* hi2c, uint8_t address)
{
pca9555_write(hi2c, address, PCA9555_CONFIGURATION_REG, 0x00);
pca9555_write(hi2c, address, PCA9555_POLARITY_INVERSION_REG, 0x00);
pca9555_write(hi2c, address, PCA9555_OUTPUT_PORT_REG, 0x00);
}
int main(void)
{
HAL_Init();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE();
GPIO_InitTypeDef gpio_init;
gpio_init.Pin = GPIO_PIN_9 | GPIO_PIN_10;
gpio_init.Mode = GPIO_MODE_AF_OD;
gpio_init.Pull = GPIO_PULLUP;
gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio_init.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &gpio_init);
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c1);
pca9555_init(&hi2c1, PCA9555_I2C_ADDRESS_1);
pca9555_init(&hi2c1, PCA9555_I2C_ADDRESS_2);
while (1)
{
pca9555_set_pin_output_level(&hi2c1, PCA9555_I2C_ADDRESS_1, PCA9555_PIN_0, 1);
pca9555_set_pin_output_level(&hi2c1, PCA9555_I2C_ADDRESS_1, PCA9555_PIN_1, 0);
pca9555_set_pin_output_level(&hi2c1, PCA9555_I2C_ADDRESS_2, PCA9555_PIN_ALL, 1);
HAL_Delay(1000);
pca9555_set_pin_output_level(&hi2c1, PCA9555_I2C_ADDRESS_1, PCA9555_PIN_0, 0);
pca9555_set_pin_output_level(&hi2c1, PCA9555_I2C_ADDRESS_1, PCA9555_PIN_1, 1);
pca9555_set_pin_output_level(&hi2c1, PCA9555_I2C_ADDRESS_2, PCA9555_PIN_ALL, 0);
HAL_Delay(1000);
}
}
```
阅读全文