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

 
 
> Таймер и прерывания, Хочу понять принцип работы
whiteTigr
сообщение Aug 15 2011, 12:21
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 25-07-11
Пользователь №: 66 407



Среда разработки: Keil.
Микроконтроллер: lpc2367.

Есть таймер, генерирующий прерывания. Таймер работает по принципу "Отсчитал до нужного MR, прервался и остановился".
Процедура, на которую он прыгает при прерывании переопределяемая.

Код
void InitTimer()
{
  /* Initialize Timer 2 */  
  PCONP |= PCTIM2;

  PCLKSEL1 &= ~(3 << PCLK_TIMER2_OFFSET);
  PCLKSEL1 |=  (1 << PCLK_TIMER2_OFFSET);

  T2PR = 63; // 1 mks  
  T2MR0 = 99; // 100 mks
  T2MCR = 7; // interupt, reset, stop  

  VICIntEnClr = INTTIM2;
  VICVectAddr26 = (unsigned long)Timer2Handler;
  VICVectPriority26 = 10;

  T2TCR = 0x01;

  VICIntEnable += INTTIM2;
}


Код
__irq void Timer2Handler()
{
  if (OnTimerInterupt)
    OnTimerInterupt();  
  
  T2IR = 0x01;
  VICVectAddr = 0;  
}


Код
typedef void (*CallBackFunction)(void);
CallBackFunction OnTimerInterupt = 0;


Допустим, я назначаю на прерывание функцию, которая выполняется около 1мс (пусть будет Func1).
При прерывании в этой функции запускаю этот же таймер, переопределяя OnTimerInterupt на функцию с небольшим временем выполнения (пусть будет Func2), и настраиваю таймер на срабатывание через 100 мкс.

Вопрос: как поведет себя выполняющаяся функция Func1, при следующем прерывании таймера (в котором вызовется Func2)?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sergeeff
сообщение Aug 16 2011, 10:00
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Как-то я с VIC'ом не работал, только с AIC'ом. При невложенных прерываниях, пока не отработает текущий обработчик, следующий не вызывается. Посему все обработчики пишем как можно короче и шустрее.
Go to the top of the page
 
+Quote Post
whiteTigr
сообщение Aug 16 2011, 10:26
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 25-07-11
Пользователь №: 66 407



Цитата(sergeeff @ Aug 16 2011, 14:00) *
Как-то я с VIC'ом не работал, только с AIC'ом. При невложенных прерываниях, пока не отработает текущий обработчик, следующий не вызывается. Посему все обработчики пишем как можно короче и шустрее.

И в главном цикле while(1) анализируем выставленные флаги в прерываниях...
Мне вот сказано, что я должен ответить по RS485 через 200мкс после окончания посылки ко мне. Т.е. делается прерывание на прием байта, по последнему байту пакета запускается таймер на 200мкс, по прерыванию от него посылается ответ.
Прерывание на прием набивает байты в пакет сразу же (нужно же определять конец пакета) - уже не сильно короткая получается, но и вынести из прерывания, по-моему, не получится.
Прерывание по таймеру должно затолкать подготовленный для отправки пакет в выходной буфер.
И получается что прерывание главного таймера (громко сказано "главного", приоритет у него наименьший) на обработку кнопок и дисплея мешает нормальной работе системы. Вот при сокращении главного таймера до Counter++ (и анализа Counter'a в while(1)) все заработало нормально.

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

P.S.: чувствую, что задаю настолько глупые вопросы, что стыдно становится. sad.gif

Сообщение отредактировал whiteTigr - Aug 16 2011, 10:37
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Aug 16 2011, 11:40
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(whiteTigr @ Aug 16 2011, 13:26) *
И в главном цикле while(1) анализируем выставленные флаги в прерываниях...
Мне вот сказано, что я должен ответить по RS485 через 200мкс после окончания посылки ко мне. Т.е. делается прерывание на прием байта, по последнему байту пакета запускается таймер на 200мкс, по прерыванию от него посылается ответ.


Ну и на кой выжидать 200 мкс после последнего байта, если у вас и так полно всякой работы? Кстати, у вас процессор на нормальной частоте работает? Какие-нибудь benchmark тесты не пробовали?

А про вложенные прерывания. Возьмите и попробуйте, примеров достаточно, как правильно организовать. На сайте, правда, полно критиков вложенных прерываний, но у вас же есть своя голова на плечах.
Go to the top of the page
 
+Quote Post
whiteTigr
сообщение Aug 16 2011, 11:49
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 25-07-11
Пользователь №: 66 407



Цитата(sergeeff @ Aug 16 2011, 15:40) *
Ну и на кой выжидать 200 мкс после последнего байта, если у вас и так полно всякой работы? Кстати, у вас процессор на нормальной частоте работает? Какие-нибудь benchmark тесты не пробовали?

200мкс по ТЗ указано. Идея была в том, что я запускаю таймер, по прерыванию которого отправлю подготовленную посылку. Ожидание, естественно не через "for (i = 0; i < ...; i++);" сделано.
Резонатор стоит на 16МГц. Судя по настройкам uart'a эта частота умножается на 4 где-то внутри.
Benchmark'и не пробовал (только сейчас узнал о них).

Цитата(sergeeff @ Aug 16 2011, 15:40) *
А про вложенные прерывания. Возьмите и попробуйте, примеров достаточно, как правильно организовать. На сайте, правда, полно критиков вложенных прерываний, но у вас же есть своя голова на плечах.

Хорошо, попробую поискать.
По этому форуму я уже предостаточно предостережений нашел. Чувствую, что не с пустого места такое возникает, и моё желание использовать вложеность - это мысли новичка, которые я должен искоренить.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Aug 16 2011, 16:22
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(whiteTigr @ Aug 16 2011, 15:49) *
200мкс по ТЗ указано. Идея была в том, что я запускаю таймер, по прерыванию которого отправлю подготовленную посылку.

ойой
может, флаг выставляете? по которому в основном теле что-то отправляется?
Go to the top of the page
 
+Quote Post
whiteTigr
сообщение Aug 17 2011, 05:04
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 25-07-11
Пользователь №: 66 407



Цитата(toweroff @ Aug 16 2011, 20:22) *
ойой
может, флаг выставляете? по которому в основном теле что-то отправляется?


Код
void StartResponseTimer()
{
  StopTimer();
  T2TC = 0;
  T2MR0 = 199; // 200 mks
  OnTimerInterupt = &OnResponse;
  StartTimer();
}

void OnResponse()
{
  int i;
  for (i = 0; i < OutBufP; i++)
  {
    RS485SendByte(OutBuf[i]);
  }
}

...

void RS485SendByte(char byte)
{
  TBuffer *buffer = &RS485.transmiteBuffer;  

  (*buffer).data[(*buffer).addrWrite] = byte;
  (*buffer).addrWrite = ((*buffer).addrWrite + 1) % BufferSize;
  (*buffer).count++;

  // Если ничего не отправляется, то инициируем отправку
  // Иначе байт отправится после отправки предыдущего
  if (DE_PIN() == 0)
  {
    RS485SendByte_lowlevel();
  }
}


Сильно криво?
В SendByte никаких ожиданий, просто заталкивание посылки в выходной буфер.

UPD:
Код
  (*buffer).addrWrite = ((*buffer).addrWrite + 1) % BufferSize;

После поста на форум эта строчка начала "резать глаз".
Переписал в виде:
Код
  buffer->addrWrite++;
  if (buffer->addrWrite >= BufferSize)
    buffer->addrWrite = 0;


Сообщение отредактировал whiteTigr - Aug 17 2011, 05:05
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- whiteTigr   Таймер и прерывания   Aug 15 2011, 12:21
- - whiteTigr   Сегодня дошло, что в первом сообщении глупость. В ...   Aug 16 2011, 07:28
|- - sergeeff   Цитата(whiteTigr @ Aug 16 2011, 10:28) Се...   Aug 16 2011, 07:46
|- - whiteTigr   Цитата(sergeeff @ Aug 16 2011, 11:46) А ч...   Aug 16 2011, 07:52
- - sergeeff   Вы же ARM'ами заняты? Там всего два прерывания...   Aug 16 2011, 08:50
|- - whiteTigr   Цитата(sergeeff @ Aug 16 2011, 12:50) Вы ...   Aug 16 2011, 09:50
- - sergeeff   Тогда уж напишите: Кодif (++buffer->addrW...   Aug 17 2011, 06:28
|- - whiteTigr   Цитата(sergeeff @ Aug 17 2011, 10:28) Тог...   Aug 17 2011, 07:09
- - toweroff   если размер буфера равен степени двойки, то вот та...   Aug 17 2011, 08:40
- - whiteTigr   Цитата(toweroff @ Aug 17 2011, 12:40) есл...   Aug 17 2011, 10:06
- - toweroff   Цитата(whiteTigr @ Aug 17 2011, 14:06) Мо...   Aug 17 2011, 10:08
- - whiteTigr   Цитата(toweroff @ Aug 17 2011, 14:08) да ...   Aug 17 2011, 10:43


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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 09:15
Рейтинг@Mail.ru


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