Первый раз я столкнулся с этой проблемой когда делал прибор Измеритель УФ-индекса. Было удобно подключать к нему различные внешние датчики. Но когда я это делал, то прибор зависал. Позже, когда я делал квадрокоптер, то увидел код сброса шины и попробовал его - работало все отлично!
Итак, как же правильно сбросить шину до рабочего состояния. Оказалось - очень легко. Нужно установить линию данных SDA на вход (то есть не прижимать ее к LOW) - это будет сигнал NACK для датчика. И сделать 9 импульсов подряд на линии SCL. Для этого выводы нужно переключить в режим "ногодрыга", подать эти сигналы и вернуть шину в режим работы с перефирией. Вот нужный код на си:
//выключаем модуль i2c_peripheral_disable(i2c); //SCL на выход , SDA на вход PUSH PULL gpio_setup_output(I2C1_GPIO_PORT, I2C1_GPIO_SCL); gpio_setup_input(I2C1_GPIO_PORT, I2C1_GPIO_SDA); //10 сигналов клок for (int i=0; i<10;i++) { i2c_scl_toggle(i2c); delay(10);//10us мкс } //выключаем клок на LOW i2c_scl_set(i2c); //включаем ноги на управление модулем i2c_setup_gpio(i2c); //сброс модуля МК i2c_reset(i2c); //включаем все обратно i2c_peripheral_enable(i2c);
Теперь, если шина часто зависает или прибор должен надежно отрабатывать все зависания, ты знаешь что делать.