Инструменты пользователя

Инструменты сайта


chibios:hal:i2c

I2C

Так как я использую второе устройство I2C, которое использует выводы PB10-PB11, то настраиваю его так:

#define VAL_GPIOBCRH            0x....EE..

Включаем поддержку I2C в halconf.h:

#define HAL_USE_I2C                 TRUE
// если планируется использовать несколько мастер-устройств на шине
#define I2C_USE_MUTUAL_EXCLUSION    TRUE

Включаем поддержку соответствующего устройства в mcuconf.h:

#define STM32_I2C_USE_I2C2                  TRUE

Адрес устройства на I2C шине кодируется семи битами, например для микросхем PCA9555/PCF8574 это делается так:

#define I2C_ADDRESS     0b0100000
#define I2C_SEND        i2cMasterTransmitTimeout
#define I2C_DRIVER      I2CD2
#define TIMEOUT         MS2ST(1000)

Также были указаны другие удобные определения.

Определяем конфигурацию I2C шины с помощью структуры I2CConfig:

static const I2CConfig i2c_config = {
    OPMODE_I2C,
    100000,
    STD_DUTY_CYCLE
};

Первый параметр управляет режимом (см. биты 0-1 регистра I2C_CR1):

  • OPMODE_I2C = 1
  • OPMODE_SMBUS_DEVICE = 2
  • OPMODE_SMBUS_HOST = 3

Второй параметр определяет скорость передачи. Кстати, подтягивающие резисторы для частоты в 100кГц должны быть не более 10кОм, для частоты в 400кГц не более 4.7кОм, а для частоты в 1МГц вообще не стоит ставить резисторы более 2кОм.

Третий параметр управляет рабочим циклом (см. биты 14-15 регистра I2C_CCR):

  • STD_DUTY_CYCLE = 1
  • FAST_DUTY_CYCLE_2 = 2
  • FAST_DUTY_CYCLE_16_9 = 3

Теперь явно определяем альтернативную функцию для выводов, которые использует I2C, и немного ждём:

palSetPadMode(GPIOB, 10, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
palSetPadMode(GPIOB, 11, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
chThdSleepMilliseconds(100);

После этого можно запустить I2C:

i2cStart(&I2C_DRIVER, &i2c_config);

Функция i2cMasterTransmitTimeout может возвращать следующие значения:

  • RDY_OK = 0
  • RDY_TIMEOUT = -1
  • RDY_RESET = -2

В случае получения RDY_TIMEOUT следует проверить соединение микроконтроллёра с шиной, работоспособность подтягивающих резисторах, корректность подсоединения устройств к шине.

В случае получения RDY_RESET следует получить расширенный код ошибки:

i2cflags_t errors = i2cGetErrors(&I2C_DRIVER);

Расширенный код ошибки определён так:

#define I2CD_NO_ERROR               0x00   // Нет ошибки
#define I2CD_BUS_ERROR              0x01   // Ошибка шины
#define I2CD_ARBITRATION_LOST       0x02   // Потеря арбитража
#define I2CD_ACK_FAILURE            0x04   // Сбой подтверждения
#define I2CD_OVERRUN                0x08   // Пере- или недополнение
#define I2CD_PEC_ERROR              0x10   // PEC ошибка при приёме
#define I2CD_TIMEOUT                0x20   // Таймаут в железе
#define I2CD_SMB_ALERT              0x40   // Тревога SMBus
chibios/hal/i2c.txt · Последние изменения: 2014/10/29 16:08 — Ruslan Popov