Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как организовать прерывание по уровню на MSP?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > MSP430
Alex2172
Портирую код с ATmega на MSP430. Нужно прерывание по уровню, которого на MSP нет (по крайней мере на MSP430F149).
Можно ли как-нибудь программно на MSP организовать прерывание по уровню?
Alex2172
Можно ли например организовать прерывание по уровню следующим образом...
На примере прерывания по уровню high на линии P1.0:

//==============================================
#define INT0_LINE 0x1

#define INT0_INIT() do {\
P1SEL &= ~INT0_LINE;/*alt. func*/ \
P1DIR &= ~INT0_LINE;/*as input*/\
P1IES &= ~INT0_LINE;/*rising edge */\
P1IFG &= ~INT0_LINE;/*clear pending int*/\
} while (0)

#define INT0_ENABLE() do{ \
P1IE |= INT0_LINE;\
P1IFG |= (INT0_LINE & P1IN);/*!!!!!!!!!!!!!*/\
}while(0)

#define INT0_DISABLE() do{ \
P1IE &= ~INT0_LINE;\
}while(0)

#define INT0_CLEAR() do{ \
P1IFG &= ~INT0_LINE;/* clear interrupt flag*/\
}while(0)
//==============================================
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_INT(void)
{
__disable_interrupt();
if (P1IFG & INT0_LINE){ // if rising edge occured
INT0_DISABLE();

//... do something

INT0_CLEAR();
INT0_ENABLE();
}
}
//==============================================

Фишка в том, что когда делаем прерывание доступным - INT0_ENABLE(), то проверяем уровень линии и, если уровень-high, то вызываем прерывание. Если же уровень определен как low, то прерывание вызывается когда возникает rising edge.
Monstrer
Добрый день. Всех с наступающим на нас праздником.
cheers.gif
Как вариант предлагаю оппробовать продублировать прерыванием от таймера если есть какой то извесный интервал ожидания событий и проверять в этом прерывании ногу.
Если нет извесного интервала, то постараться минимизировать запрет прерывания и построить очередь прерываний складывать их в циклический буфер - этот вариант пробовал с USB контроллером - помогло значительно.
До этого контроллер висс из-за необработаных прерыаний.
Надеюсь поможет.
smile3046.gif
NoName
Если не можеш отрабатывать по фронту, наверное у тебя на линии дребезг: проверять линию на уровень через определенный интревал времени нормально, но данная методика более потребляющаяя. Например: ты отрабатываеш нажатие клавиатуры, в таком случае будут приемлемо не опрос по интервалу а запуск таймера:
Код
interrupt [ PORT2_VECTOR ] void PORT2(void){
if ( P2IFG&0x0E ) { TBCCR5 = TBR + 0x100;  TBCCTL5 = 0x0010;   }
   P2IFG = 0x0;
                                          } // interrupt [ PORT2_VECTOR ] void PORT2(void)
interrupt [ TIMERB1_VECTOR ] void TimerALL( void )  {
...
if ( TBCCTL5&0x10 ) if ( TBCCTL5&0x01 ) { TBCCTL5 = 0x0;  ... = P2IN;
....


но все естесвенно зависит от твоей задачи, и от формы твоего сигнала...
Alex2172
Цитата(NoName @ Mar 5 2005, 10:40)
Если не можеш отрабатывать по фронту, наверное у тебя на линии дребезг: проверять линию на уровень через определенный интревал времени нормально, но данная методика более потребляющаяя. Например: ты отрабатываеш нажатие клавиатуры, в таком случае будут приемлемо не опрос по интервалу а запуск таймера:
Код
interrupt [ PORT2_VECTOR ] void PORT2(void){
if ( P2IFG&0x0E ) { TBCCR5 = TBR + 0x100;  TBCCTL5 = 0x0010;   }
   P2IFG = 0x0;
                                          } // interrupt [ PORT2_VECTOR ] void PORT2(void)
interrupt [ TIMERB1_VECTOR ] void TimerALL( void )  {
...
if ( TBCCTL5&0x10 ) if ( TBCCTL5&0x01 ) { TBCCTL5 = 0x0;  ... = P2IN;
....


но все естесвенно зависит от твоей задачи, и от формы твоего сигнала...
*

Нет, по фронту все прекрасно отрабатывается. Теперь и по уровню тоже (см. то что я выше предложил) по крайней мере в моей задаче.
Спасибо всем, кто откликнулся.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.