Статус:
Offline
Реєстрація: 05.12.2007
Повідом.: 5889
Реєстрація: 05.12.2007
Повідом.: 5889
- 🟡 09:22 Відбій тривоги в Харківська область.Зверніть увагу, тривога ще триває у:- Куп’янський район- Харківський район- Липецька територіальна громада- Вовчанська територіальна громада#Харківська_область
- #1
I2C в STM32. Глюк или особенность работы?
Запускаю мелкую серию железок на STM32F103VCT6. В числе прочего используется I2C1 модуль. Так вот из 6 плат 5 нормально взлетели а шестая в упор отказывалась работать со слейвами на I2C.
Полез анализатором, увидел что линии SCL SDA в какой-то момент проваливаются в 0, обе одновременно и на примерно одинаковое время. Ну, думаю хрен с ним, бывает, наверное инициализация.
Стал разбираться под дебагом и увидел что проц выставляет флаг BUSY в регистре SR2. Схуяли, подумалось мне, но тут вспомнил про те провалы увиденные анализатором. ОК, наступил щупами мультиметра и увидел что по непонятной причине, в момент инициализации портов лапы выставляются в 0. Почему?! Я настраиваю как Alternate function Open Drain, почему мать его, они висят в нуле сколь угодно долго, пока не подашь тактовый сигнал на модуль I2C? Самое веселое что 5 процов эти провалы игнорят, а один реагирует на это установкой BUSY.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Speed = GPIO_Speed_2MHz; //Тут порты в единице
GPIO_Init(GPIOB, &gpio); //Тут порты проседают в ноль
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); //Тут они опять в единице.
//Тут будет костыль
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_ClockSpeed = I2C_SPEED;
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct.I2C_OwnAddress1 = OWN_ADDR;
I2C_Init(I2C1, &I2C_InitStruct);
I2C_AcknowledgeConfig(I2C1, ENABLE);
Логического объяснения этому не нашел, просто добавил это(костыль) и все заработало
delay_us(5);
I2C_SoftwareResetCmd(I2C1, 1 );
delay_us(5);
I2C_SoftwareResetCmd(I2C1, 0 );
Кто нибудь сталкивался с такой херней?
Запускаю мелкую серию железок на STM32F103VCT6. В числе прочего используется I2C1 модуль. Так вот из 6 плат 5 нормально взлетели а шестая в упор отказывалась работать со слейвами на I2C.
Полез анализатором, увидел что линии SCL SDA в какой-то момент проваливаются в 0, обе одновременно и на примерно одинаковое время. Ну, думаю хрен с ним, бывает, наверное инициализация.
Стал разбираться под дебагом и увидел что проц выставляет флаг BUSY в регистре SR2. Схуяли, подумалось мне, но тут вспомнил про те провалы увиденные анализатором. ОК, наступил щупами мультиметра и увидел что по непонятной причине, в момент инициализации портов лапы выставляются в 0. Почему?! Я настраиваю как Alternate function Open Drain, почему мать его, они висят в нуле сколь угодно долго, пока не подашь тактовый сигнал на модуль I2C? Самое веселое что 5 процов эти провалы игнорят, а один реагирует на это установкой BUSY.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Speed = GPIO_Speed_2MHz; //Тут порты в единице
GPIO_Init(GPIOB, &gpio); //Тут порты проседают в ноль
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); //Тут они опять в единице.
//Тут будет костыль
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_ClockSpeed = I2C_SPEED;
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct.I2C_OwnAddress1 = OWN_ADDR;
I2C_Init(I2C1, &I2C_InitStruct);
I2C_AcknowledgeConfig(I2C1, ENABLE);
Логического объяснения этому не нашел, просто добавил это(костыль) и все заработало
delay_us(5);
I2C_SoftwareResetCmd(I2C1, 1 );
delay_us(5);
I2C_SoftwareResetCmd(I2C1, 0 );
Кто нибудь сталкивался с такой херней?