|
GPIO прерывания Rising/Falling edge приходят одновременно? |
|
|
|
Jan 10 2014, 17:43
|
Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jan 10 2014, 19:20
|
Местный
  
Группа: Участник
Сообщений: 339
Регистрация: 10-07-08
Из: Херсон
Пользователь №: 38 856

|
Цитата(Golikov A. @ Jan 10 2014, 22:09)  а сколько времени между падающим и восходящим? прерывание имеет же некоторую плавающую задержку, может наплывает одно на другое?
и не лучше ли это капчем таймера делать? Наплывать при частоте "30 Гц."
|
|
|
|
|
Jan 10 2014, 21:09
|
Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jan 11 2014, 16:14
|
Гуру
     
Группа: Свой
Сообщений: 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, а потом работать уже с переменными в регистрах, а не читать многократно с портов... Чтобы чудес меньше было...  Цитата(evgen2 @ Jan 10 2014, 23:43)  if(tln == 1000) tln = 0; Уж не из-за этого-ли случается периодическая фигня При переходе индекса массива через 1000 у вас записывается просто ti, а иначе - разница между ti и предыдущим.
|
|
|
|
|
Jan 11 2014, 16:22
|
Местный
  
Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688

|
Цитата(jcxz @ Jan 11 2014, 20:14)  А где у вас чтение IOIntStatus для квитирования прерывания? Чего-чего? Цитата(jcxz @ Jan 11 2014, 20:14)  Зачем два раза одну и ту-же операцию делать? И вообще лучше однократно считать IO0IntStatR и IO0IntStatF в начале ISR, а потом работать уже с переменными в регистрах, а не читать многократно с портов... Чтобы чудес меньше было...  Уж не из-за этого-ли случается периодическая фигня При переходе индекса массива через 1000 у вас записывается просто ti, а иначе - разница между ti и предыдущим. написано ж - и тест, и времени - попой ешь
|
|
|
|
|
Jan 11 2014, 16:38
|
Местный
  
Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688

|
Цитата(jcxz @ Jan 11 2014, 20:14)  Уж не из-за этого-ли случается периодическая фигня При переходе индекса массива через 1000 у вас записывается просто ti, а иначе - разница между ti и предыдущим. Ага, при переходе индекса массива внезапно выпрыгивает прерывание Эта фигня встречается через примерно от 12 до 100 прерываний, так что там дальше не сильно влияет на размышления  Цитата(jcxz @ Jan 11 2014, 20:25)  UM откройте. и что это даст ? Не чтение UM, а чтение информации о возможном наличии pending interrupt внутри прерывания для понимания причины появления одновременно Rizing и Falling прерывания ?
Сообщение отредактировал IgorKossak - Jan 11 2014, 16:44
|
|
|
|
|
Jan 11 2014, 17:42
|
Местный
  
Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688

|
Цитата(jcxz @ Jan 11 2014, 21:13)  Я же уже сказал: чтение IOIntStatus - квитирование прерывания. квитирование - техн., комп. действие по значению гл. квитировать; подтверждение приёма-передачи структурной единицы информации ну и как это прерывание квитировать? IO0IntClr - это не квитирование?
|
|
|
|
|
Jan 11 2014, 19:31
|
Местный
  
Группа: Участник
Сообщений: 236
Регистрация: 1-04-06
Пользователь №: 15 688

|
Цитата(jcxz @ Jan 11 2014, 22:10)  Просто прочитать этот регистр. Чтение его - это и есть подтверждение модулю GpioInt. У меня были проблемы на LPC17x когда использовал GpioInt и не читал IOIntStatus в ISR. Спасибо, попробую. В понедельник. В UM про это ничего не написано, в нарытых примерах для GPIO прерываний в LPC17xx тоже нет.
|
|
|
|
|
Jan 13 2014, 16:26
|
Местный
  
Группа: Участник
Сообщений: 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 не появляется... Хрень какая-то, завтра попробуем с осциллографом посмотреть что меняется после инициализации иваси.
|
|
|
|
|
Jan 22 2014, 13:26
|
Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|