11#include "driver/i2c_master.h"
14#include "freertos/FreeRTOS.h"
15#include "freertos/task.h"
17static const char *
TAG =
"pcf8574";
20#define I2C_PORT I2C_NUM_0
23#define I2C_SCL_GPIO 14
24#define I2C_SDA_GPIO 15
27#define I2C_FREQ_HZ 100000
30#define I2C_TIMEOUT_MS 1000
33#define PCF8574_I2C_ADDR 0x20
36#define LED_CHASE_PIN_COUNT 3
37#define LED_CHASE_PIN_MASK 0x07
38#define LED_CHASE_PORT_IDLE 0xF8
39#define LED_CHASE_STEP_MS 300
62 i2c_master_bus_config_t bus_cfg = {
66 .clk_source = I2C_CLK_SRC_DEFAULT,
67 .glitch_ignore_cnt = 7,
68 .flags.enable_internal_pullup =
true,
70 ESP_RETURN_ON_ERROR(i2c_new_master_bus(&bus_cfg, &
s_i2c_bus),
TAG,
"i2c bus init failed");
72 i2c_device_config_t dev_cfg = {
73 .dev_addr_length = I2C_ADDR_BIT_LEN_7,
78 TAG,
"i2c device add failed");
88 ESP_LOGI(
TAG,
"PCF8574 at 0x%02X, I2C SCL=GPIO%d SDA=GPIO%d, port=0x%02X",
95 ESP_RETURN_ON_FALSE(
s_initialized, ESP_ERR_INVALID_STATE,
TAG,
"not initialized");
98 ESP_RETURN_ON_ERROR(err,
TAG,
"write failed");
106 ESP_RETURN_ON_FALSE(
s_initialized, ESP_ERR_INVALID_STATE,
TAG,
"not initialized");
107 ESP_RETURN_ON_FALSE(value, ESP_ERR_INVALID_ARG,
TAG,
"null value");
114 ESP_RETURN_ON_FALSE(pin < 8, ESP_ERR_INVALID_ARG,
TAG,
"pin out of range");
116 uint8_t mask = (uint8_t)(1U << pin);
122 next &= (uint8_t)~mask;
130 ESP_RETURN_ON_FALSE(pin < 8, ESP_ERR_INVALID_ARG,
TAG,
"pin out of range");
131 ESP_RETURN_ON_FALSE(level, ESP_ERR_INVALID_ARG,
TAG,
"null level");
136 *level = (value & (1U << pin)) != 0;
150 ESP_LOGD(
TAG,
"Chase: P%d on (port=0x%02X)", pin, port);
160 static bool started =
false;
162 ESP_RETURN_ON_FALSE(
s_initialized, ESP_ERR_INVALID_STATE,
TAG,
"not initialized");
168 BaseType_t created = xTaskCreate(
led_chase_task,
"led_chase", 2048, NULL, 5, NULL);
169 ESP_RETURN_ON_FALSE(created == pdPASS, ESP_ERR_NO_MEM,
TAG,
"chase task create failed");
#define I2C_FREQ_HZ
Частота I2C, Гц
#define LED_CHASE_STEP_MS
esp_err_t pcf8574_read(uint8_t *value)
Читает текущее состояние порта P0..P7.
esp_err_t pcf8574_init(void)
Инициализирует шину I2C и устройство PCF8574T.
static i2c_master_bus_handle_t s_i2c_bus
static uint8_t s_port_shadow
#define I2C_SCL_GPIO
GPIO шины I2C.
static bool s_initialized
esp_err_t pcf8574_get_pin(uint8_t pin, bool *level)
Читает уровень одного пина (0..7).
static esp_err_t pcf8574_read_raw(uint8_t *value)
esp_err_t pcf8574_led_chase_start(void)
Запускает задачу «бегущий огонь» на светодиодах P0..P2.
#define PCF8574_I2C_ADDR
7-битный адрес PCF8574 на шине (A0=A1=A2=0 → 0x20)
static void led_chase_task(void *arg)
Циклически включает по одному светодиоду на P0, P1, P2.
static i2c_master_dev_handle_t s_pcf8574_dev
static esp_err_t pcf8574_write_raw(uint8_t value)
#define I2C_TIMEOUT_MS
Таймаут транзакции, мс
#define LED_CHASE_PIN_COUNT
Светодиоды на P0..P2 (остальные пины не трогаем)
#define I2C_PORT
Порт I2C.
esp_err_t pcf8574_write(uint8_t value)
Записывает байт в порт расширителя (состояние P0..P7).
#define LED_CHASE_PORT_IDLE
esp_err_t pcf8574_set_pin(uint8_t pin, bool level)
Устанавливает уровень одного пина (0..7).
Драйвер I2C-расширителя портов PCF8574T.