6nog 0 18 апреля, 2016 Опубликовано 18 апреля, 2016 (изменено) · Жалоба Недавно возникла проблема с микросхемой STM32F103C8T6. На новой партии микросхем не заработал старый, уже проверенный код. Как оказалось проблема возникала при инициализации модуля I2C. Вот проблемный кусок кода: 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 и больше не меняет его. Если закомментировать эту строчку всё начинает работать нормально. Никто не сталкивался с подобной проблемой? Очень странно, что МК из предыдущих партий работали отлично и без комментирования этой строчки. Изменено 18 апреля, 2016 пользователем IgorKossak [codebox] для длинного кода. [code]-для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
golf2109 0 19 апреля, 2016 Опубликовано 19 апреля, 2016 · Жалоба попробуйте настроить регистры 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 0 19 апреля, 2016 Опубликовано 19 апреля, 2016 · Жалоба Если настроить выводы в самом начале, то шина тоже устанавливается в Busy, только уже теперь при подаче тактирования на модуль i2c. А сбрасываю биты перед настройкой всегда по привычке. А потом выставляю которые мне нужны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 19 апреля, 2016 Опубликовано 19 апреля, 2016 · Жалоба А сбрасываю биты перед настройкой всегда по привычке.При этом нога переходит в аналоговый режим, снося крышу аналоговому фильтру на входе I2C. Хорошая привычка . Почитайте раздел 2.12.7 "I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry" в errata, возможно это именно ваш случай. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 19 апреля, 2016 Опубликовано 19 апреля, 2016 · Жалоба Хорошая привычка Не говоря уже о том, что кошернее сбрасывать и устанавливать вот так: REG = (REG & ~clear_bits) | set_bits; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
6nog 0 21 апреля, 2016 Опубликовано 21 апреля, 2016 · Жалоба При этом нога переходит в аналоговый режим, снося крышу аналоговому фильтру на входе I2C. Хорошая привычка . Почитайте раздел 2.12.7 "I2C analog filter may provide wrong value, locking BUSY flag and preventing master mode entry" в errata, возможно это именно ваш случай. Спасибо! А то я голову сломал почему так происходит. Не говоря уже о том, что кошернее сбрасывать и устанавливать вот так: REG = (REG & ~clear_bits) | set_bits; Спасибо! Возьму на заметку. =)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться