Здравствуйте!
Пытаюсь подключить дисплей по I2C-каналу. Делаю все по инструкции, но HAL-функции работающие с I2C-интерфейсом зависают. Бросил я пока подключение решил просканировать I2C-устройства. Код ниже:
void I2C_Scan() { HAL_StatusTypeDef res; char info[] = "Scanning I2C bus...\r\n"; HAL_UART_Transmit(&huart1, (uint8_t*)info, strlen(info), HAL_MAX_DELAY); for(i = 0; i < 128; i++) { HAL_GPIO_WritePin(GPIOC, led13_Pin, 0); res = HAL_I2C_IsDeviceReady(&hi2c2, i << 1, 1, HAL_MAX_DELAY); HAL_GPIO_WritePin(GPIOC, led13_Pin, 1); if(res == HAL_OK) { char msg[64]; LCD = i; snprintf(msg, sizeof(msg), "0x%02X", LCD); HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n", 2, HAL_MAX_DELAY); } else HAL_UART_Transmit(&huart1, (uint8_t*)".", 1, HAL_MAX_DELAY); } HAL_UART_Transmit(&huart1, (uint8_t*)"\r\n", 2, HAL_MAX_DELAY); }
Но и тут зависание на функции HAL_I2C_IsDeviceReady.
Для создания интерфейса I2C использовал STM32CubeMX. В ней функция инициализации I2C выглядит так:
static void MX_I2C2_Init(void) { /* USER CODE BEGIN I2C2_Init 0 */ /* USER CODE END I2C2_Init 0 */ /* USER CODE BEGIN I2C2_Init 1 */ /* USER CODE END I2C2_Init 1 */ hi2c2.Instance = I2C2; hi2c2.Init.ClockSpeed = 100000; hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c2.Init.OwnAddress1 = 0; hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c2.Init.OwnAddress2 = 0; hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN I2C2_Init 2 */ /* USER CODE END I2C2_Init 2 */ }
Что здесь может быть не так? Пины подключил правильно к B10 и В11.
Привет, а электрически все нормально? Подтягивающие резисторы?
Да скорее всего с электрической частью, так как я напрямую подсоединил монитор к пинам. Если есть возможность скиньте правильную схему подключения!
LCD 1602 c конвертером I2C.
Меня смущает что при сканировании устройств I2C зависает функция
HAL_I2C_IsDeviceReady(&hi2c2, i << 1, 1, HAL_MAX_DELAY);
Она должна работать как бы правильно или не правильно подсоединил устройство I2C. Может дело в неправильном дескрипторе hi2c2, который вернула функция инициализации I2C:
HAL_I2C_Init(&hi2c2)
Скорее всего висит на ожидании какого-то из флагов.
Пока Бог с ним с этим LCD. Мне бы понять почему зависает вроде простейшая HAL-функция проверки: есть ли подключение устройства I2C c определенным адресом? Если есть, то выводим его, если нет, пропускаем. Может быть на этапе формирования конфигурации I2C в STMCubeMX я что-то пропустил? Вроде делаю все по инструкции.
Вы говорите про флаги. К сожаленью битовые операции мне не знакомы.
@aveal А на каком месте зависает (внутри функции)?
HAL_I2C_IsDeviceReady
вот эта строчка под отладчиком зависает!
/* Wait until SB flag is set */
if (I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK)
что ожидает выставления SB-флага.
Наводит на мысль, что I2C неправильно сконфигурирован.
Что делать?
@mihayk Доброго дня ) Скинь проект, я посмотрю завтра или вечером, если успею.
@aveal Привет!
Код упростился до сканирования I2C-устройств. LCD вообще отключил. Основной цикл: Ввод значения oneData с терминала и вывод каждую секунду в порт отладочных данных. Для запуска сканирования oneData должна быть '1' (вводиться с терминала). Терминал Termite в папке bin.
Зависание в функции I2C_Scan(oneData) на строке
res = HAL_I2C_IsDeviceReady(&hi2c1, i << 1, 1, HAL_MAX_DELAY).
Удивительный факт: Один раз за всю историю ПО показало все подключенные устройства (не зависло на вышеуказанной строке), хотя я ничего в коде не менял. Чудеса....
Нет подтягивающих резисторов.
Завтра соберу данную схему.
Смущает то, что канал замыкается на питание (3V).
Это правильно? Не бейте меня :)))