Доброго времени.
Переезжаю с AVRки на STM32. Необходимо запустить i2c шину на самом маленьком камне семейства, а именно stm32f030f4. Никак не могу заставить камень проявить какую либо активность на шине.
CODE
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);
I2C_DeInit(I2C1);
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 1;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1 = 0x4;
I2C_InitStructure.I2C_Timing = 0x10805E89;
I2C_Init(I2C1,&I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
while ((I2C_BUS->CR1 & I2C_CR1_PE)==0) {}; // Жду пока включится
I2C_BUS->CR2 &= ~I2C_CR2_RD_WRN; // Режим передачи
I2C_BUS->CR2 &= ~I2C_CR2_NBYTES; // Очистить размер данных
I2C_BUS->CR2 |= Size<<I2C_OFFSET_CR2_NBYTES; // Установить размер данных
I2C_BUS->CR2 &= ~I2C_CR2_SADD; // Очистить адрес ведомого устройства
I2C_BUS->CR2 |= Adress; // Установить адрес ведомого устройства
I2C_BUS->CR2 |= I2C_CR2_START; // Выдать старт на шину
while ((I2C_BUS->ISR & I2C_ISR_BUSY)==0) {}; // Ожидать выдачу старта
Здесь, насколько я понимаю, SDA должна быть прижата к земле, но этого не происходит. Вижу это осциллографом. Хотя флаг I2C_ISR_BUSY устанавливается. Далее...
Код
// Сейчас либо I2C запросит первый байт для отправки,
// Либо взлетит NACK-флаг, говорящий о том, что микросхема не отвечает.
// Если взлетит NACK-флаг, отправку прекращаем.
while ((((I2C_BUS->ISR & I2C_ISR_TXIS)==0) && ((I2C_BUS->ISR & I2C_ISR_NACKF)==0)) && (I2C_BUS->ISR & I2C_ISR_BUSY)) {};
На этой строчке все виснет.
Проверил на 2ух камнях, т.к. подозревал что порт умер. Подтяжка обоих линий к питанию 4к7.
Голова кипит уже, подскажите в чем ошибка.
Сообщение отредактировал IgorKossak - Dec 20 2015, 21:35
Причина редактирования: [codeebox] для длинного кода, [code] - для короткого!