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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> повторные прерывания LPC17xx
evgen2
сообщение Jan 14 2014, 23:32
Сообщение #1


Местный
***

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



Вот похожая тема В прерываниях CM0/CM3 в конце нужен ClearPending?

Имеем такой простой до невозможности код
Код
/* таймер T2  25 МГц */
   LPC_TIM2->MR0 = 782/2;           // 782 = 32 кHz
   LPC_TIM2->MCR = 3;                
   LPC_TIM2->TCR=  0x01;
   NVIC_EnableIRQ(TIMER2_IRQn);

void TIMER2_IRQHandler(void)
{    static int raz=0;
     if(raz == 0)
     {  LPC_GPIO2->FIOSET = 0x1000;raz = 1;
     } else {
       LPC_GPIO2->FIOCLR = 0x1000; raz = 0;
   }
    LPC_TIM2->IR = 1; // Clear interrupt flag
}


смотрим осциилографом, что получается:

___|___|___|___

Или наоборот

— — |— — |— — |— —

Вместо ожидаемого — — |___|— — |___|— — |___

При этом, если поставить брякпойнт на FIOSET или FIOCLR, а потом убрать и продолжить, то картина меняется
если мерять время этого второго паразита, то это будет 12-14 клоков
Однако, если перенести IR = 1; в начало
Код
void TIMER2_IRQHandler(void)
{    static int raz=0;
      LPC_TIM2->IR = 1; // Clear interrupt flag
     if(raz == 0)
     {  LPC_GPIO2->FIOSET = 0x1000;raz = 1;
     } else {
       LPC_GPIO2->FIOCLR = 0x1000; raz = 0;
   }
}


То все налаживается....

Теперь смотрю на все остальные прервывания, в том числе GPI прерывания GPIO прерывания Rising/Falling edge приходят одновременно? (2 ноги * прерывания по фронту и спаду) - там тоже получается какое-то левое повторное прерывание.. однако манипуляции с выносом очистки прерывания как можно раньше не прокатывают и, кажется, наоборот, от выноса очистки в конец количество левых прерываний уменьшается

ЗЫ: а в эмуляторе это не вылазит

Сообщение отредактировал evgen2 - Jan 15 2014, 00:07
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jan 14 2014, 23:50
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(evgen2 @ Jan 15 2014, 01:32) *

Если память не изменяет - не нужен, но вот где это написано не помню (изменяет таки) а искать лень.

Цитата(evgen2 @ Jan 15 2014, 01:32) *
То все налаживается....
Может что такое добавить, хотя у вас не RTC...


Код
OS_INTERRUPT void OS::SystemTimer_ISR()
{
    /* Clear interrupt source */
    RTC->IFC=RTC_IFC_COMP0;
    /* Flushing instructions to make sure that the interrupt is not re-triggered*/
    /* This may be required when the peripheral clock is slower than the core */
    __DSB();
    {
    scmRTOS_ISRW_TYPE ISR;

#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1
        system_timer_user_hook();
#endif
        Kernel.system_timer();
    }

}
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 15 2014, 07:54
Сообщение #3


Гуру
******

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



Цитата(evgen2 @ Jan 15 2014, 01:32) *
То все налаживается....
Угу. Это влияние конвеера. Или сбрасывайте в начале, или вставляйте барьер синхронизации после сброса флага.


--------------------
На любой вопрос даю любой ответ
"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 15 2014, 09:41
Сообщение #4


Местный
***

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



Цитата(Сергей Борщ @ Jan 15 2014, 11:54) *
Угу. Это влияние конвеера. Или сбрасывайте в начале, или вставляйте барьер синхронизации после сброса флага.


"Барьер синхронизации" - это "заклинание" __DSB(); ? Непонятно, почему ни в мануалах, ни в примерах его нет
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 15 2014, 09:50
Сообщение #5


Гуру
******

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



Цитата(evgen2 @ Jan 15 2014, 11:41) *
"Барьер синхронизации" - это "заклинание" __DSB(); ?
Ну хотя бы по диагонали просмотрите начало документа по ссылке.
Цитата(evgen2 @ Jan 15 2014, 11:41) *
Непонятно, почему ни в мануалах, ни в примерах его нет
Я вам дал ссылку как раз на мануал с примером.


--------------------
На любой вопрос даю любой ответ
"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 15 2014, 18:33
Сообщение #6


Местный
***

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



Цитата(Сергей Борщ @ Jan 15 2014, 13:50) *
Ну хотя бы по диагонали просмотрите начало документа по ссылке.
Я вам дал ссылку как раз на мануал с примером.

да хоть по диагонали, хоть на принтере распечатать да на просвет посмотреть . Может оно и влияет, если засыпать-просыпаться, а без этого - никакой разницы
Go to the top of the page
 
+Quote Post
Aleksandr Barano...
сообщение Jan 15 2014, 22:32
Сообщение #7


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

Группа: Участник
Сообщений: 169
Регистрация: 31-08-05
Из: New York
Пользователь №: 8 118






Due to the processor pipeline, the Cortex-M processors can be entering the interrupt sequence
at the same time as writing to the NVIC to disable the interrupt. Therefore, it is possible that an
interrupt handler might be executed immediately after it is disabled at the NVIC.

http://infocenter.arm.com/help//topic/com....r_m_profile.pdf


--------------------
ASB
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 16 2014, 06:48
Сообщение #8


Гуру
******

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



Цитата(Aleksandr Baranov @ Jan 16 2014, 04:32) *
Due to the processor pipeline, the Cortex-M processors can be entering the interrupt sequence
at the same time as writing to the NVIC to disable the interrupt. Therefore, it is possible that an
interrupt handler might be executed immediately after it is disabled at the NVIC.

Мимо кассы. Так как у ТС нет запретов прерываний внутри ISR, и даже вообще обращений к NVIC внутри ISR.
Go to the top of the page
 
+Quote Post
swisst
сообщение Jan 16 2014, 09:55
Сообщение #9


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

Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425



Доброго дня ! на контроллере 1768 с MC0 и таймером проблем не имею.
Код
void TIMER0_IRQHandler(){
    uint32_t _interrupt_source = LPC_TIM0->IR;

    if(_interrupt_source & (1<<0)){
        LPC_TIM0->IR |= (1<<0);
                //дальше код - барьеров нет
    }
}


я бы для чистоты эксперимента объявил бы еще переменную как volatile
Код
static int raz=0;

или вовсе бы ушел от нее
Код
LPC_GPIO2->FIOPIN ^= 0x1000;
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 16 2014, 10:48
Сообщение #10


Гуру
******

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



1. Вот потому, что "дальше код", потому и не имеете rolleyes.gif
2. Операция if(_interrupt_source & (1<<0)){ бессмысленна, так как если у вас установлены ещё и другие флаги запросов в IF, то функция всё равно зациклится в непрерывных входах в ISR (ведь регистра маски прерываний в таймере вроде нету?).
3. Операция |= в LPC_TIM0->IR |= (1<<0); также бессмысленна, читайте UM.
4. volatile объявлять бессмысленно если переменная больше нигде не используется (а она больше нигде не используется).
5. Делать так: LPC_GPIO2->FIOPIN ^= 0x1000; крайне опасно, если учесть, что в основном коде (или другом ISR) могут быть операции с другими битами этого порта. Курите UM на предмет - зачем придуманы FIOSET и FIOCLR.

PS: И вообще - лучше молчать, чем давать такие "советы".
Лучше поучитесь хотя-бы у ТС как правильно реализовывать ISR-ы.
Go to the top of the page
 
+Quote Post
swisst
сообщение Jan 16 2014, 12:30
Сообщение #11


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

Группа: Свой
Сообщений: 163
Регистрация: 16-02-07
Из: Харьков
Пользователь №: 25 425



Цитата(jcxz @ Jan 16 2014, 12:48) *
1. Вот потому, что "дальше код", потому и не имеете rolleyes.gif


частота дерганья ножкой 40kHz. обработчик упростил
Код
void TIMER0_IRQHandler(){
    if(LPC_TIM0->IR & (1<<0)){

        LED3_TOG;      //LPC_GPIO2->FIOPIN ^= 0x1000;

    }

    LPC_TIM0->IR = (1<<0);
}

все работает, как и раньше. в UM ни слова о том, в каком месте сбрасывать флаг.


Цитата(jcxz @ Jan 16 2014, 12:48) *
2. Операция if(_interrupt_source & (1<<0)){ бессмысленна, так как если у вас установлены ещё и другие флаги запросов в IF, то функция всё равно зациклится в непрерывных входах в ISR (ведь регистра маски прерываний в таймере вроде нету?).
3. Операция |= в LPC_TIM0->IR |= (1<<0); также бессмысленна, читайте UM.

это не принципиально в конкретном примере. прерывания по MATCH и CAP маскируются.

Цитата(jcxz @ Jan 16 2014, 12:48) *
4. volatile объявлять бессмысленно если переменная больше нигде не используется (а она больше нигде не используется).
5. Делать так: LPC_GPIO2->FIOPIN ^= 0x1000; крайне опасно, если учесть, что в основном коде (или другом ISR) могут быть операции с другими битами этого порта. Курите UM на предмет - зачем придуманы FIOSET и FIOCLR.

я же написал - для чистоты эксперимента. иначе получается, что вы знаете о том, что переменная нигде не используется, но не знаете, что порт 2 пустой rolleyes.gif
Go to the top of the page
 
+Quote Post
sidy
сообщение Jan 16 2014, 16:13
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 280
Регистрация: 2-11-08
Пользователь №: 41 333



Допустим, у меня есть следующий обработчик прерываний:
Код
void TIM1_TRG_COM_TIM11_IRQHandler(void){
  if(TIM11->SR&TIM_SR_UIF){
      TIM11->SR&=~TIM_SR_UIF;
      __disable_irq();
      TIM4->CNT=(TIM11->CNT*5.25f/168.0f)
      TIM4->CR1|=TIM_CR1_CEN;              
      __enable_irq();                      
  }
}

нужно ли мне ставить после __enable_irq(); __ISB()?

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


Гуру
******

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



Цитата(sidy @ Jan 16 2014, 22:13) *
нужно ли мне ставить после __enable_irq(); __ISB()?

Скажем по-другому: вам скорее всего не нужно ставить __disable_irq()/__enable_irq().
Зачем они? У вас что - в другом, более приоритетном ISR осуществляется запись в эти регистры??? smile3046.gif

Цитата(swisst @ Jan 16 2014, 18:30) *
я же написал - для чистоты эксперимента. иначе получается, что вы знаете о том, что переменная нигде не используется, но не знаете, что порт 2 пустой rolleyes.gif

Что переменная нигде не используется я знаю из static int, а то что порт больше нигде - об этом ни слова.
К тому же переменных типа int в ОЗУ можно создать ГОРАЗДО больше чем обычно имеется портов в МК. Если вы так расточительно будете подходить к ногам, что на одну ногу будете тратить целый 32-битный порт, то далеко не уедете...
Go to the top of the page
 
+Quote Post
sidy
сообщение Jan 16 2014, 17:18
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 280
Регистрация: 2-11-08
Пользователь №: 41 333



Цитата(jcxz @ Jan 16 2014, 20:54) *
Скажем по-другому: вам скорее всего не нужно ставить __disable_irq()/__enable_irq().
Зачем они? У вас что - в другом, более приоритетном ISR осуществляется запись в эти регистры???

Например, если между записью в регистр CNT и пуском таймера TIM_CR1_CEN придет более приоритетное прерывание, то TIM11->CNT может сделать n-ое количество тактов и значение TIM4->CNT будет некорректным.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jan 16 2014, 18:24
Сообщение #15


Гуру
******

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



Как же можно ответить ответить на Ваш вопрос, если невозможно догадаться, что у вас за регистры такие SR и CNT?
В UM на LPC17xx таковых нету.
Ну если под CNT ещё можно предположить регистр TC, то с SR вообще теряюсь в догадках....
Подозреваю что у вас не LPC17x. А в таком случае нужно указывать какой CPU имеете в виду если вопрос касается периферии и желательно указывать как она у вас сконфигурена.
Go to the top of the page
 
+Quote Post

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

 


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


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