|
STM32 Вопрос про I2C, непонимаю даташит или что-то не то |
|
|
|
Feb 8 2013, 17:10
|
Группа: Участник
Сообщений: 13
Регистрация: 10-01-11
Пользователь №: 62 132

|
Да, какая то фигня с личными сообщениями, хотя в настройках стоит, что разрешены, тоже ничего не могу отправлять. А помощь на сайте вообще не работает) (( Попытался на почту вопрос задать, но не пойму дошел ли он или нет. При использовании библиотеки возникают проблемы с чтением BTF. Может я чего то упустил при инициализации? Моя последовательность действий. Код ... Init_I2C(1, 100000);// Реально все инициализируется. Пробовал стандартными функциями отправлять - работает, но при работе //с прерываниями все равно виснет DWT_Init();// счетчик ядра - крутая вещь! ...
u8_t ReadReg(u8_t deviceAddr, u8_t Reg, u8_t* Data) { unsigned char buffer[2+1]; unsigned int result; buffer[0] = deviceAddr; buffer[1] = Reg; buffer[2] = 0;
result = ReadW_I2C(1, buffer, 1, 1);
if(result != 1) return MEMS_ERROR; else { Data = &buffer[2]; return MEMS_SUCCESS; } }
... Заходит в обрабоку прерывания Код // ATTENTION! - since 03.11.11. does not work without the simple // case I2C_EVENT_MASTER_BYTE_TRANSMITTING below as if // I2C_EVENT_MASTER_BYTE_TRANSMITTING occures sometimes // before I2C_EVENT_MASTER_BYTE_TRANSMITTED. // Possible reasons (due to the following changes): // 1). Interrupt priority of I2C has been changed to the highest one; // 2). The I2C speed has been reduced down to 100kHz from 400kHz, // the driver has been tested before. // case I2C_EVENT_MASTER_BYTE_TRANSMITTING: // Data being SENT; TRA, BSY, MSL and { // TxE but BTF are set. uint8_t ex = 0; int32_t tp = I2C_SBTimeoutInit(port, 2*BITS_ONE_BYTE); // Two I2C bytes to wait while (!I2C_BTF(i2c) && !(ex = I2C_SBTimeoutExpired(&tp))); // Wait for BTF! It MUST arrive else // it were a severe hardware error... if (ex) // BTF still off: expired! { I2C_ERROR_HANDLER(port, ctrl->code = ctrl->evnt); break; } Не Возвращает BTF. По таймауту переходит в I2C_ERROR_HANDLER Никто не пробовал работать с данными функциями? Видно, что напсано все очень грамотно, учтены все косяки. Прочитал, что на адрес не приходит BTF. Получается здесь как раз обращение к адресу устройства и к его внутренему регистру. Может он и не должен приходить? Был бы благодарен за помощь!
|
|
|
|
|
Feb 8 2013, 18:04
|
Группа: Участник
Сообщений: 13
Регистрация: 10-01-11
Пользователь №: 62 132

|
)))) Согласен. Но это не решает проблемы. Сейчас посмотрел еще раз отладчиком. Сейчас происходит так. Шлет старт -> Отсылает адрес(нормально приходит) -> Дальше бы надо послать адрес регистра, а он переходит на проверку BTF, который пока точно не придет. Код // Send I2C ID (slave Address to receive) // with R/W bit ==1 I2C_SEND_ADDR(i2c, ctrl->ptr[0] | I2C_Direction_Receiver);
// Prevent reading of SR2 to avoid resetting of ADDR bit, // if two or less bytes to read (cases N == 1 or N == 2). // See RM0008.PDF, Doc ID 13902 Rev 12, Page 739.
if (ctrl->icnt <= 2) ctrl->readsr2 = 0; Как я понял из документации надо запомнить, что пришел ответ от адреса. Но этого не происходит( Стирается, то, что пришел ответ от адреса и прерывание обрабатывается по неправильной ветке автомата
Сообщение отредактировал dfyz.s - Feb 8 2013, 19:23
|
|
|
|
|
Feb 8 2013, 20:25
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(dfyz.s @ Feb 8 2013, 19:04)  Сейчас происходит так. Шлет старт -> Отсылает адрес(нормально приходит) -> Дальше бы надо послать адрес регистра, а он переходит на проверку BTF, который пока точно не придет. Если предполагается операция [START]-[ADDR]-[WRITE]-[RESTART]-[READ]-[STOP], то автомат должен сработать так: После старта попадаем в: case I2C_EVENT_MASTER_MODE_SELECT: // MASTER, (RE)START sent: BUSY, MSL and SB are set где (ctrl->wcnt) будет больше нуля, поэтому вызовется I2C_SEND_ADDR(i2c, ctrl->ptr[0] & ~I2C_Direction_Receiver); для посылки адреса устройства со сброшенным битом чтения, то есть, будет начата операция записи! После этого автомат должен попасть в case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: // ADDR sent with /W bit и лишь после посылки байта там (если не DMA) I2C_WRITE_NEXT(ctrl, ctrl->ptr[ctrl->indx++]); // .wnt-- inside... когда-то попадем в case I2C_EVENT_MASTER_BYTE_TRANSMITTING: // Data being SENT; TRA, BSY, MSL and где после ожидания BTF прямиком далее в case I2C_EVENT_MASTER_BYTE_TRANSMITTED: // Data byte's been SENT; TRA, BSY, MSL and Если посылался только один байт в режиме [WRITE], то (ctrl->wcnt == 0), посему будет выдан рестарт I2C_START(i2c); И т.д. ВНИМАНИЕ! Отладчик нарушает временные характеристики на шине I2C с точки зрения SLAVE, что может приводить к странным результатам! Я заметил также, что отладчик может считывать регистр статуса, что приводит к преждевременному сбросу бита ADDR.
Сообщение отредактировал IgorKossak - Feb 9 2013, 18:15
Причина редактирования: лишние пробельные строки!!!
|
|
|
|
|
Feb 10 2013, 19:31
|
Группа: Участник
Сообщений: 13
Регистрация: 10-01-11
Пользователь №: 62 132

|
Игорь, большое спасибо за ваши обяснения!
Мне сейчас необходимо записать адресс устройства на шине, а потом послать адресс регистра, изкоторого считать информацию. (ST -> SAD+W -> ................. -> SubAddres.......... ST -> SAD+R -> ........................ NMAK -> STOP-> ......................... <- answ SAK .................. <-SAK...........................<-SAK <-DATA.......................... )
Поделитесь опытом, ка вы отлаживали программу, т.к. отладчиком нормально не получается посмотеть (и вправду сбрасывает биты как BTF, так и ADDR). Только при помощи осцилографа?
Сообщение отредактировал dfyz.s - Feb 10 2013, 19:46
|
|
|
|
|
Feb 10 2013, 20:07
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(dfyz.s @ Feb 10 2013, 21:31)  отладчиком нормально не получается посмотеть (и вправду сбрасывает биты как BTF, так и ADDR). Отладчик сбрасывает нужные биты всегда или только когда открыто окно просмотра регистров i2c? Цитата(dfyz.s @ Feb 10 2013, 21:31)  Только при помощи осцилографа? Вариантов множество: вывод в comport (или любой другой интерфейс, который можно выделить для отладки); запись лога обмена в ОЗУ, с последующим просмотром лога после завершения обмена; и тд и тп.
|
|
|
|
|
Feb 11 2013, 11:02
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(dfyz.s @ Feb 10 2013, 20:31)  Мне сейчас необходимо записать адресс устройства на шине, а потом послать адресс регистра, изкоторого считать информацию. Сообщите же, что за датчик? Я хоть гляну, какой протокол. Вообще, функция ReadW_I2C с параметром wcnt > 0 и предназначена для последовательности START-ADDR[W]-WRITE-RESTART-ADDR[R]-READ-STOP. Цитата Поделитесь опытом, ка вы отлаживали программу, т.к. отладчиком нормально не получается посмотеть (и вправду сбрасывает биты как BTF, так и ADDR). Только при помощи осцилографа? По-всякому. И осциллографом, и проскакиванием каких-то участков кода без остановки с последующим анализом содержимого памяти. Муторное дело было. Сейчас на устройстве на I2C EEPROM работает файловая система (причем, как EFS KEIL, так и Chan-FS пробовалась). Все очень стабильно. Я бы сказал, мы тут уже забыли об отладке, просто все работает как надо. И быстро (с учетом DMA).
|
|
|
|
|
Feb 11 2013, 12:46
|
Группа: Участник
Сообщений: 13
Регистрация: 10-01-11
Пользователь №: 62 132

|
Да, скорее всего я где-то напортачил. Надо протестить нормально. Свободного времени не очень много, когда будет - поплотнее займусь По i2c опрашиваются датчики (акселерометр + магнетометр) lsm303dlhc и гироскоп (l3gd20). Сами они опрашивались, используя стандартные либы, проблема была в том, что когда запускаю параллельно какие нибудь измерения от таймера по прерыванию - перестает работать. Видать некоторые ответы от слейва теряются и и2с перестает нормально работать. Цитата Отладчик сбрасывает нужные биты всегда или только когда открыто окно просмотра регистров i2c? Реально, сбрасывает только при просмотре регистров! Пробежал по алгоритму - пошагово нормально работает. А когда запускаю с проскакиванием участков возвращает ошибку. Часто слетатет на i2c busy.
Сообщение отредактировал dfyz.s - Feb 11 2013, 20:05
|
|
|
|
|
Feb 13 2013, 06:34
|
Группа: Участник
Сообщений: 13
Регистрация: 10-01-11
Пользователь №: 62 132

|
Да, с схемотехнической точки зрения похоже все хорошо, т.к. один и2с без других прерываний работает нормально. Резисторы 5 КОм на обоих линиях, и2с на плате, длина линий очень небольшая. Забежал к другу посмотреть на осциллографе, что происходит на шине. Правильно ли я понимаю, что при попытке чтения из регистра нормально передается адрес устройства и адрес регистра , а после рестарта для чтения байта не приходит ответ от слейва? Цитата Вроде заработало, но, кажется, основная ошибка была совсем в другом... Я посылал один пакет в след за другим сразу. Гипотеза, что слейв не успевал поймать старт после стопа. Может такое быть? Поэтому он не подтверждал прием, срабатывало прерывание на ошибку. ошибка сбрасывалась, но что при этом с передачей происходит дальше я не знаю. Поставил паузу перед отправкой. Но как то это стремно, контроллер тратит свеё время на ожидание... Хотя меня тревожат сомненья что это не причина. Может просто условия изменились и пока ошибки не возникает... Спасибо всем огромное, а особенно KnightIgor!!! Кажись заработало! Тоже вставил такую задержку и стало работать! Дома попробую с прерываниями. С прерываниями работает на отлично!)
Сообщение отредактировал dfyz.s - Feb 13 2013, 18:24
Эскизы прикрепленных изображений
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|