реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> STM32 Вопрос про I2C, непонимаю даташит или что-то не то
dfyz.s
сообщение Feb 8 2013, 17:10
Сообщение #16





Группа: Участник
Сообщений: 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. Получается здесь как раз обращение к адресу устройства и к его внутренему регистру. Может он и не должен приходить?

Был бы благодарен за помощь!
Go to the top of the page
 
+Quote Post
polyname
сообщение Feb 8 2013, 17:47
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 147
Регистрация: 18-05-12
Пользователь №: 71 915



Непонятно что они курили когда разрабатывали I2C ?
После AVR думал невозможно сделать еще сложнее, а нет - сделали...
Пользую программный I2C, и горя не знаю (тем более что работает на любом контроллере).
Go to the top of the page
 
+Quote Post
dfyz.s
сообщение Feb 8 2013, 18:04
Сообщение #18





Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Feb 8 2013, 20:25
Сообщение #19


Знающий
****

Группа: Участник
Сообщений: 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
Причина редактирования: лишние пробельные строки!!!
Go to the top of the page
 
+Quote Post
dfyz.s
сообщение Feb 10 2013, 19:31
Сообщение #20





Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Feb 10 2013, 20:07
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 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 (или любой другой интерфейс, который можно выделить для отладки);
запись лога обмена в ОЗУ, с последующим просмотром лога после завершения обмена;
и тд и тп.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Feb 11 2013, 11:02
Сообщение #22


Знающий
****

Группа: Участник
Сообщений: 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).
Go to the top of the page
 
+Quote Post
dfyz.s
сообщение Feb 11 2013, 12:46
Сообщение #23





Группа: Участник
Сообщений: 13
Регистрация: 10-01-11
Пользователь №: 62 132



Да, скорее всего я где-то напортачил. Надо протестить нормально. Свободного времени не очень много, когда будет - поплотнее займусь
По i2c опрашиваются датчики (акселерометр + магнетометр) lsm303dlhc и гироскоп (l3gd20).

Сами они опрашивались, используя стандартные либы, проблема была в том, что когда запускаю параллельно какие нибудь измерения от таймера по прерыванию - перестает работать. Видать некоторые ответы от слейва теряются и и2с перестает нормально работать.

Цитата
Отладчик сбрасывает нужные биты всегда или только когда открыто окно просмотра регистров i2c?


Реально, сбрасывает только при просмотре регистров! Пробежал по алгоритму - пошагово нормально работает. А когда запускаю с проскакиванием участков возвращает ошибку. Часто слетатет на i2c busy.

Сообщение отредактировал dfyz.s - Feb 11 2013, 20:05
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Feb 12 2013, 08:39
Сообщение #24


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(dfyz.s @ Feb 11 2013, 13:46) *
Пробежал по алгоритму - пошагово нормально работает. А когда запускаю с проскакиванием участков возвращает ошибку. Часто слетатет на i2c busy.

i2c busy означает лишь, что Вы пытаетесь обратиться к устройству, пока еще обмен идет. А вообще, как там с подтяжками на линиях I2C? Если фронты сильно завалены (резисторы имеют большие номиналы, а линия длиная), это может привести к проблемам в автомате ведомого...
Go to the top of the page
 
+Quote Post
dfyz.s
сообщение Feb 13 2013, 06:34
Сообщение #25





Группа: Участник
Сообщений: 13
Регистрация: 10-01-11
Пользователь №: 62 132



Да, с схемотехнической точки зрения похоже все хорошо, т.к. один и2с без других прерываний работает нормально. Резисторы 5 КОм на обоих линиях, и2с на плате, длина линий очень небольшая.

Забежал к другу посмотреть на осциллографе, что происходит на шине.
Правильно ли я понимаю, что при попытке чтения из регистра нормально передается адрес устройства и адрес регистра , а после рестарта для чтения байта не приходит ответ от слейва?

Цитата
Вроде заработало, но, кажется, основная ошибка была совсем в другом...
Я посылал один пакет в след за другим сразу. Гипотеза, что слейв не успевал поймать старт после стопа. Может такое быть?
Поэтому он не подтверждал прием, срабатывало прерывание на ошибку. ошибка сбрасывалась, но что при этом с передачей происходит дальше я не знаю.
Поставил паузу перед отправкой. Но как то это стремно, контроллер тратит свеё время на ожидание...
Хотя меня тревожат сомненья что это не причина. Может просто условия изменились и пока ошибки не возникает...

Спасибо всем огромное, а особенно KnightIgor!!!
Кажись заработало! Тоже вставил такую задержку и стало работать!
Дома попробую с прерываниями.

С прерываниями работает на отлично!)

Сообщение отредактировал dfyz.s - Feb 13 2013, 18:24
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 07:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01377 секунд с 7
ELECTRONIX ©2004-2016