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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> GPIO прерывания Rising/Falling edge приходят одновременно?
evgen2
сообщение Jan 10 2014, 17:43
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688



Есть дивайс для измерения температуры TMP03, с него идет ШИМ с частотой около 30 Гц.
Точнее - два дивайса. Выходы подаются на GPIO ноги, на которые можно назначить прерывания Rising/Falling edge. Микроконтроллер - lpc1768

Меряем одно время прихода Rising edge, меряем время прихода Falling edge, получаем два интервала времени, потом по формуле
Temp= CoeffSensorA + CoeffSensorB * td0 / dt1;

получаем температуру, и всё работает замечательно.

Только вот изредка меряется какая-то ерунда. Стал разбираться.

Сделал тест

Код
int TL[1000];
int TS[1000];
int tln=0;

void EINT3_IRQHandle(void)
{  int ti, v;
    static int tiold=0;
      ti = LPC_TIM1->TC;
        if((LPC_GPIOINT->IO0IntStatR &  0x00000001) || (LPC_GPIOINT->IO0IntStatF &  0x0000001)) // это ШИМ с первого TMP03
      { v = (LPC_GPIOINT->IO0IntStatR &  0x00000001) | (((LPC_GPIOINT->IO0IntStatF &  0x0000001)<<1));
        if(tln == 0)
             TL[tln] = ti;
        else
            TL[tln] = ti - tiold;
                tiold = ti;
        TS[tln] =v;  
        tln++;        
        if(tln == 1000)
           tln = 0;
                LPC_GPIOINT->IO0IntClr =0x00000001;
    }
       if((LPC_GPIOINT->IO0IntStatR &  0x00000002) || (LPC_GPIOINT->IO0IntStatF &  0x0000002)) // это ШИМ с второго TMP03
      {
          LPC_GPIOINT->IO0IntClr =0x00000002;
      }    
}


Смотрю на TS и вижу вот такое:

1
2
1
2
3 <== этого не может быть, потому что не может быть никогда
2
1
2
1

Т.е. одновременно приходит и Rising м Falling edge
причем, если смотреть на TL - никакого дребезга с небольшими временами не видно.
Одновременно Rising и Falling (3) получаются вроде бы точно вместо Rising (1), но это на небольшом интервале измерения. Причем, если Rising и Falling одновременно считать за Rising, то смотри начало - все меряется замечательно, кроме как изредка какая-то фигня. Причем эта фигня систематическая и не лечится усреднением. Связано ли это как-то с одновременным приходом Rising м Falling edge - пока неясно.

Сообщение отредактировал evgen2 - Jan 10 2014, 17:45
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jan 10 2014, 19:09
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а сколько времени между падающим и восходящим?
прерывание имеет же некоторую плавающую задержку, может наплывает одно на другое?

и не лучше ли это капчем таймера делать?
Go to the top of the page
 
+Quote Post
alexdos
сообщение Jan 10 2014, 19:20
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 339
Регистрация: 10-07-08
Из: Херсон
Пользователь №: 38 856



Цитата(Golikov A. @ Jan 10 2014, 22:09) *
а сколько времени между падающим и восходящим?
прерывание имеет же некоторую плавающую задержку, может наплывает одно на другое?

и не лучше ли это капчем таймера делать?

Наплывать при частоте "30 Гц."
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 10 2014, 21:00
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(alexdos @ Jan 10 2014, 21:20) *
Наплывать при частоте "30 Гц."
А вдруг у него задержки в прерываниях (на пустых циклах)?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
evgen2
сообщение Jan 10 2014, 21:09
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688



Цитата(Сергей Борщ @ Jan 11 2014, 01:00) *
А вдруг у него задержки в прерываниях (на пустых циклах)?

если б были большие задержки, я б их увидел в массиве TL, а так идут значения типа
369699 //25=1мкс
205851
369120
204589
........
Даже если предположить, что есть какая-то наводка, типа дребезга контактов, то куда девается второй edge ?

Сообщение отредактировал evgen2 - Jan 10 2014, 21:14
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 11 2014, 16:14
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



А где у вас чтение IOIntStatus для квитирования прерывания?

Цитата(evgen2 @ Jan 10 2014, 23:43) *
if((LPC_GPIOINT->IO0IntStatR & 0x00000001) || (LPC_GPIOINT->IO0IntStatF & 0x0000001)) // это ШИМ с первого TMP03
{ v = (LPC_GPIOINT->IO0IntStatR & 0x00000001) | (((LPC_GPIOINT->IO0IntStatF & 0x0000001)<<1));

Зачем два раза одну и ту-же операцию делать?

Цитата(evgen2 @ Jan 10 2014, 23:43) *
if((LPC_GPIOINT->IO0IntStatR & 0x00000002) || (LPC_GPIOINT->IO0IntStatF & 0x0000002)) // это ШИМ с второго TMP03

И вообще лучше однократно считать IO0IntStatR и IO0IntStatF в начале ISR, а потом работать уже с переменными в регистрах, а не читать многократно
с портов... Чтобы чудес меньше было... rolleyes.gif

Цитата(evgen2 @ Jan 10 2014, 23:43) *
if(tln == 1000)
tln = 0;

Уж не из-за этого-ли случается периодическая фигня biggrin.gif
При переходе индекса массива через 1000 у вас записывается просто ti, а иначе - разница между ti и предыдущим.
Go to the top of the page
 
+Quote Post
evgen2
сообщение Jan 11 2014, 16:22
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688



Цитата(jcxz @ Jan 11 2014, 20:14) *
А где у вас чтение IOIntStatus для квитирования прерывания?


Чего-чего?

Цитата(jcxz @ Jan 11 2014, 20:14) *
Зачем два раза одну и ту-же операцию делать?

И вообще лучше однократно считать IO0IntStatR и IO0IntStatF в начале ISR, а потом работать уже с переменными в регистрах, а не читать многократно
с портов... Чтобы чудес меньше было... rolleyes.gif


Уж не из-за этого-ли случается периодическая фигня biggrin.gif
При переходе индекса массива через 1000 у вас записывается просто ti, а иначе - разница между ti и предыдущим.

написано ж - и тест, и времени - попой ешь
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 11 2014, 16:25
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(evgen2 @ Jan 11 2014, 22:22) *
Чего-чего?

UM откройте.

Цитата(evgen2 @ Jan 11 2014, 22:22) *
написано ж - и тест, и времени - попой ешь

тады и не удивляйтесь что и результат как из попы smile3046.gif
Go to the top of the page
 
+Quote Post
evgen2
сообщение Jan 11 2014, 16:38
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688



Цитата(jcxz @ Jan 11 2014, 20:14) *
Уж не из-за этого-ли случается периодическая фигня biggrin.gif
При переходе индекса массива через 1000 у вас записывается просто ti, а иначе - разница между ti и предыдущим.


Ага, при переходе индекса массива внезапно выпрыгивает прерывание rolleyes.gif
Эта фигня встречается через примерно от 12 до 100 прерываний, так что там дальше не сильно влияет на размышления cranky.gif

Цитата(jcxz @ Jan 11 2014, 20:25) *
UM откройте.

и что это даст ?
Не чтение UM, а чтение информации о возможном наличии pending interrupt внутри прерывания для понимания причины появления одновременно Rizing и Falling прерывания ?

Сообщение отредактировал IgorKossak - Jan 11 2014, 16:44
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 11 2014, 17:13
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(evgen2 @ Jan 11 2014, 22:38) *
и что это даст ?
Не чтение UM, а чтение информации о возможном наличии pending interrupt внутри прерывания для понимания причины появления одновременно Rizing и Falling прерывания ?

Я же уже сказал: чтение IOIntStatus - квитирование прерывания.
Go to the top of the page
 
+Quote Post
evgen2
сообщение Jan 11 2014, 17:42
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688



Цитата(jcxz @ Jan 11 2014, 21:13) *
Я же уже сказал: чтение IOIntStatus - квитирование прерывания.


квитирование - техн., комп. действие по значению гл. квитировать; подтверждение приёма-передачи структурной единицы информации

ну и как это прерывание квитировать? IO0IntClr - это не квитирование?



Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 11 2014, 18:10
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Просто прочитать этот регистр. Чтение его - это и есть подтверждение модулю GpioInt.
У меня были проблемы на LPC17x когда использовал GpioInt и не читал IOIntStatus в ISR.
Go to the top of the page
 
+Quote Post
evgen2
сообщение Jan 11 2014, 19:31
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688



Цитата(jcxz @ Jan 11 2014, 22:10) *
Просто прочитать этот регистр. Чтение его - это и есть подтверждение модулю GpioInt.
У меня были проблемы на LPC17x когда использовал GpioInt и не читал IOIntStatus в ISR.


Спасибо, попробую. В понедельник.
В UM про это ничего не написано, в нарытых примерах для GPIO прерываний в LPC17xx тоже нет.
Go to the top of the page
 
+Quote Post
evgen2
сообщение Jan 13 2014, 16:26
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688



Цитата(jcxz @ Jan 11 2014, 22:10) *
Просто прочитать этот регистр. Чтение его - это и есть подтверждение модулю GpioInt.
У меня были проблемы на LPC17x когда использовал GpioInt и не читал IOIntStatus в ISR.

попробовал - ничего не дало.
Убил всё, кроме этого прерывания - пропало. Методом последовательного включения определил, что появлется после включения I2C2Init - Initialize I2C controller as a master
Т.е. проинициализировал, ничего c I2 не делаю, прерывание I2 не появляется...
Хрень какая-то, завтра попробуем с осциллографом посмотреть что меняется после инициализации иваси.
Go to the top of the page
 
+Quote Post
evgen2
сообщение Jan 22 2014, 13:26
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688



Пока резюме такое:

Пока не включаю I2C2 никакой потери GPIO прерываний нет

Код
void I2C2Init( void )
{
  LPC_SC->PCONP |= (1 << 26);

  /* set PIO0.10 and PIO0.11 to I2C2 SDA and SCL */
  /* function to 10 on both SDA and SCL. */
  LPC_PINCON->PINSEL0 &= ~((0x03<<20)|(0x03<<22));
  LPC_PINCON->PINSEL0 |= ((0x02<<20)|(0x02<<22));

  /*--- Clear flags ---*/
  LPC_I2C2->I2CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;    

  /*--- Reset registers ---*/
  LPC_I2C2->I2SCLL   = I2SCLL_SCLL;
  LPC_I2C2->I2SCLH   = I2SCLH_SCLH;

  /* Install interrupt handler */
  NVIC_EnableIRQ(I2C2_IRQn);

  LPC_I2C2->I2CONSET = I2CONSET_I2EN;
  return;
}


Если вызываю I2C2Init - (и чуть поработаю с I2C - один раз прочитаю коффициенты) через произвольное время (от секунд до нескольких минут) )происходит потеря прерывания GPIO с последующим коротким, порядка 0.5 мкс "вторичным" или "ложным" прерыванием.

Если при этом (после инициализации и чтения коэффициентов) поставить брейкпонт в функции прерывания I2C2_IRQn, то отладчик туда не попадает, т.е. прерывания от I2C2 никак не могут "убить" прерывания GPI.

Такое впечатление, что прерывания запрещаются каким-то внутренним резидентным процессом, который непонятно как искать и непонятно как связан с I2C
cranky.gif

Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 16th July 2025 - 04:00
Рейтинг@Mail.ru


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