|
|
  |
STM32F100C6T6 и I2C1, работать не хочет |
|
|
|
Apr 12 2012, 14:36
|

Профессионал
    
Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807

|
По примеру в IAR EWARM написал небольшую программу инициализации интерфейса I2C для работы через прерывания: CODE void I2C_Ini(void){ I2C_InitTypeDef I2C_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // I2C RCC RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); // I2C GPIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_I2C1,ENABLE);// SCL=B8,SDA=B9 PININI(SCL,GPIO_Mode_AF_OD,GPIO_Speed_50MHz);PINLOCK(SCL); // макросы проверены, ошибок нет PININI(SDA,GPIO_Mode_AF_OD,GPIO_Speed_50MHz);PINLOCK(SDA);// макросы проверены, ошибок нет // I2C config I2C_InitStructure.I2C_ClockSpeed = 100000; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0xAA; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_Init(I2C1,&I2C_InitStructure); I2C_Cmd(I2C1,ENABLE); // I2C NVIC NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn; NVIC_Init(&NVIC_InitStructure); I2C_ITConfig(I2C1,I2C_IT_EVT,ENABLE); // enable event IRQ I2C_ITConfig(I2C1,I2C_IT_ERR,ENABLE); // enable error IRQ I2C_ITConfig(I2C1,I2C_IT_BUF,ENABLE); // enable buffer IRQ } Странно, но результатом ее выполнения является установка бита BUSY, хотя осцилл показывает, что линии SCL и SDA находятся в высоком уровне. По описанию этого бита, его установка свидетельствует о низком уровне хотя бы одной линии. Что же тут не так? Дальнейшая выдача START бессмысленна, т. к. судя по всему интерфейс неправильно инициализирован...
Сообщение отредактировал IgorKossak - Apr 12 2012, 17:43
Причина редактирования: [codebox]!!!
|
|
|
|
|
Apr 13 2012, 11:31
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 5-10-06
Из: Зеленоград
Пользователь №: 21 007

|
попробуйте поменять местами команды включения и инициализации, и добавить ещё один вызов: Код I2C_Cmd(I2C1,ENABLE); I2C_Init(I2C1,&I2C_InitStructure); I2C_AcknowledgeConfig(I2C1, ENABLE); по крайней мере я сегодня I2C код на базе примеров написал, всё заработало с первого раза. И у меня именно так команды стоят.
|
|
|
|
|
Apr 13 2012, 13:06
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата I2C_Cmd(I2C1,ENABLE); I2C_Init(I2C1,&I2C_InitStructure); Странная последовательность. Надо бы наоборот. А то разрешается I2C, которая еще не проинициализирована. P.S. @ivainc1789: в своем коде нашел такое замечание: // ATTENTION: some forums say, first init I2C, then GPIO... У Вас же сначала инициализируется GPIO, потом I2C. Я бы тоже так сделал по логике вещей, но мой работающий код следует-таки замечанию: Код I2C_INIT(I2C_DEVICE, I2C_InitStruct); // (sets PE, too) GPIO_Configuration(I2CGPIOs, sizeof(I2CGPIOs)); #ifdef I2C1_REMAPPED
GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE); #endif IRQ_INIT(NVIC_I2CInitStructure); IRQ_INIT(NVIC_I2CErrStructure); (всякие макросы использованы, но суть остается).
Сообщение отредактировал KnightIgor - Apr 13 2012, 13:15
|
|
|
|
|
Apr 13 2012, 13:32
|

Профессионал
    
Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807

|
Цитата(KnightIgor @ Apr 13 2012, 17:06)  Странная последовательность. Надо бы наоборот. А то разрешается I2C, которая еще не проинициализирована. Я того же мнения, хотя в примерах от IAR именно так и сделано: разрешается работа того, что еще не настроено... ))) Цитата в своем коде нашел такое замечание: // ATTENTION: some forums say, first init I2C, then GPIO... вот это фундаментальное наблюдение! Я тоже сложа руки не сидел, но пришел к другому выводу. Для того, чтобы мой код из первого поста заработал, достаточно строку: Код // I2C RCC RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); опустить ниже секции инициализации GPIO - и все начинает работать! Т. е. хочется сделать вывод, что сначала все же настраиваем GPIO (в том числе ремаппинг, если есть) и только потом подаем тактирование и инициализируем переферийный модуль! Причем в примерах у IAR все работать может только потому, что не используется ремаппинг... Короче, в ref manual прямо про эти тонкости не сказано, а проблема вроде бы существует: как все же правильно инициализировать?
|
|
|
|
|
Apr 13 2012, 15:00
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(ivainc1789 @ Apr 13 2012, 14:32)  как все же правильно инициализировать? Правильно так, как заработает. Я, как уже писал, подсмотрел в форуме самого ST то самое замечание, сделал, - работает. Больше над темой не задумывался. Может правы Вы: у меня такт на GPIO подается где-то в начале всей программы (чтобы привести ноги в танцевальную позицию номер 5 максимально быстро), а уж потом в разных подмодулях начинается инициализация периферий. Кстати, что я еще себе за правило взял: перед XXX_Init() я вызываю XXX_DeInit() на случай, если вздумаю вызвать переинициализацию подмодулей изнутри уже работающей программы, а не только единожды после RESET.
Сообщение отредактировал KnightIgor - Apr 13 2012, 15:01
|
|
|
|
|
Apr 13 2012, 15:03
|
Частый гость
 
Группа: Участник
Сообщений: 169
Регистрация: 31-08-05
Из: New York
Пользователь №: 8 118

|
Я сначала инициализирую GPIO, а потом - I2C. Иначе иногда инициализированный I2C во время инициализации GPIO заклинивает
--------------------
ASB
|
|
|
|
|
Apr 13 2012, 15:44
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Aleksandr Baranov @ Apr 13 2012, 16:03)  Я сначала инициализирую GPIO, а потом - I2C. Иначе иногда инициализированный I2C во время инициализации GPIO заклинивает Попробовал и я: "наплевал" на собственное предостережение и сделал инициализацию пинов GPIO для I2C перед самим I2C (как, собственно, логика и подсказывает). Работает и так. Правда, тактирование на GPIO порт и AFIO к этому моменту уже имеется, и я лишь задаю режимы требуемых пинов в данном подмодуле. Поэтому я предположу, что автор темы прав и раскопал верную особенность: дай такт на GPIO, поставь ноги прямо и лишь потом запускай периферию.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|