Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с I2C STM32
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
6nog
Недавно возникла проблема с микросхемой STM32F103C8T6. На новой партии микросхем не заработал старый, уже проверенный код. Как оказалось проблема возникала при инициализации модуля I2C.

Вот проблемный кусок кода:
CODE
void Accel::init()
{
RCC->APB1ENR |= (RCC_APB1Periph_I2C1);//Вкл. тактирование И2Ц
I2C1->CR2 |= 36;//36 MHz входит в модуль I2C

// I2C использует две ноги микроконтроллера, их тоже нужно настроить
GPIOB->CRL &=~(GPIO_CRL_MODE6|GPIO_CRL_MODE7|GPIO_CRL_CNF6|GPIO_CRL_CNF7);
GPIOB->CRL |= (GPIO_CRL_MODE6|GPIO_CRL_MODE7|GPIO_CRL_CNF6|GPIO_CRL_CNF7);
GPIOB->BSRR=GPIO_BSRR_BS6|GPIO_BSRR_BS7;

I2C1->CR1 &= ~0x000F;// I2C mode, Peripheral disable
I2C1->CR1 &= ~0x0400;//No acknowledge returned

I2C1->CR2 |= 36;//36 MHz входит в модуль I2C

I2C1->CCR &= ~0xFFFF;
I2C1->CCR |= 180;// Получаем 100kHz из 36MHz
I2C1->CCR &= ~0xC000; //Standart Master Mode, Fast mode 2/1

I2C1->TRISE = 37;//Maximum rise time 1000;

I2C1->OAR1 &= ~(0x00fe);
I2C1->OAR1 &= ~(0x8000);//7-bit slave address
I2C1->OAR1 |= 0x4000; // Must be configured and kept at 1.
I2C1->OAR1 |= (0x15<<1);//Адрес выставим 0х15 на всякий
I2C1->CR1 |= 0x0001;//Peripheral enable

outBuf.point=0;

TH_INIT();
}

После строчки
GPIOB->CRL &=~(GPIO_CRL_MODE6|GPIO_CRL_MODE7|GPIO_CRL_CNF6|GPIO_CRL_CNF7);
I2C выставляет в регистре статуса состояние шины Busy и больше не меняет его.
Если закомментировать эту строчку всё начинает работать нормально.

Никто не сталкивался с подобной проблемой? Очень странно, что МК из предыдущих партий работали отлично и без комментирования этой строчки.
golf2109
попробуйте настроить регистры GPIO в самомначале,
до этого

I2C1->CR2 |= 36;//36 MHz входит в модуль I2C

и не совсем понятно зачем сначала сбрасывать, а затем устанавливать биты
GPIOB->CRL &=~(GPIO_CRL_MODE6|GPIO_CRL_MODE7|GPIO_CRL_CNF6|GPIO_CRL_CNF7);
GPIOB->CRL |= (GPIO_CRL_MODE6|GPIO_CRL_MODE7|GPIO_CRL_CNF6|GPIO_CRL_CNF7);
6nog
Если настроить выводы в самом начале, то шина тоже устанавливается в Busy, только уже теперь при подаче тактирования на модуль i2c.

А сбрасываю биты перед настройкой всегда по привычке. А потом выставляю которые мне нужны.
Сергей Борщ
QUOTE (6nog @ Apr 19 2016, 16:31) *
А сбрасываю биты перед настройкой всегда по привычке.
При этом нога переходит в аналоговый режим, снося крышу аналоговому фильтру на входе I2C. Хорошая привычка wacko.gif. Почитайте раздел 2.12.7 "I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry" в errata, возможно это именно ваш случай.
scifi
Цитата(Сергей Борщ @ Apr 19 2016, 18:11) *
Хорошая привычка wacko.gif

Не говоря уже о том, что кошернее сбрасывать и устанавливать вот так:
Код
REG = (REG & ~clear_bits) | set_bits;
6nog
QUOTE (Сергей Борщ @ Apr 19 2016, 18:11) *
При этом нога переходит в аналоговый режим, снося крышу аналоговому фильтру на входе I2C. Хорошая привычка wacko.gif. Почитайте раздел 2.12.7 "I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry" в errata, возможно это именно ваш случай.

Спасибо! А то я голову сломал почему так происходит.

QUOTE (scifi @ Apr 19 2016, 18:24) *
Не говоря уже о том, что кошернее сбрасывать и устанавливать вот так:
CODE
REG = (REG & ~clear_bits) | set_bits;

Спасибо! Возьму на заметку. =))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.