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

 
 
 
Reply to this topicStart new topic
> Вопрос по LPC11xx, реагирование на изменения уровня на входе
_Артём_
сообщение Oct 13 2011, 23:19
Сообщение #1


Гуру
******

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



Пытаюсь заставить LPC1114 реагировать на измение состояния на входе (на фронт).
Вот код:
Код
#include "driver_config.h"
#include "target_config.h"


volatile unsigned short LedTimer;
void SysTick_Handler(void)
{
    if (LPC_GPIO[0]->DATA&(1<<7)) {
        if (++LedTimer>=100) {
            LPC_GPIO[0]->DATA&=~(1<<7);
        }
    }
}


void GPIOInit( void )
{
  /* Enable AHB clock to the GPIO domain. */
  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

#ifdef __JTAG_DISABLED  
  LPC_IOCON->R_PIO1_1  &= ~0x07;
  LPC_IOCON->R_PIO1_1  |= 0x01;
#endif

  /* Set up NVIC when I/O pins are configured as external interrupts. */
#if CONFIG_GPIO_DEFAULT_PIOINT0_IRQHANDLER==1
  NVIC_EnableIRQ(EINT0_IRQn);
#endif
#if CONFIG_GPIO_DEFAULT_PIOINT1_IRQHANDLER==1
  NVIC_EnableIRQ(EINT1_IRQn);
#endif
#if CONFIG_GPIO_DEFAULT_PIOINT2_IRQHANDLER==1
  NVIC_EnableIRQ(EINT2_IRQn);
#endif
#if CONFIG_GPIO_DEFAULT_PIOINT3_IRQHANDLER==1
  NVIC_EnableIRQ(EINT3_IRQn);
#endif
  return;
}

/*****************************************************************************
** Function name:        GPIOSetInterrupt
**
** Descriptions:        Set interrupt sense, event, etc.
**                        edge or level, 0 is edge, 1 is level
**                        single or double edge, 0 is single, 1 is double
**                        active high or low, etc.
**
** parameters:            port num, bit position, sense, single/doube, polarity
** Returned value:        None
**
*****************************************************************************/
void GPIOSetInterrupt( uint32_t portNum, uint32_t bitPosi, uint32_t sense,
            uint32_t single, uint32_t event )
{
  switch ( portNum )
  {
    case PORT0:
      if ( sense == 0 )
      {
        LPC_GPIO0->IS &= ~(0x1<<bitPosi);
        /* single or double only applies when sense is 0(edge trigger). */
        if ( single == 0 )
          LPC_GPIO0->IBE &= ~(0x1<<bitPosi);
        else
          LPC_GPIO0->IBE |= (0x1<<bitPosi);
      }
      else
          LPC_GPIO0->IS |= (0x1<<bitPosi);
      if ( event == 0 )
        LPC_GPIO0->IEV &= ~(0x1<<bitPosi);
      else
        LPC_GPIO0->IEV |= (0x1<<bitPosi);
    break;
    case PORT1:
      if ( sense == 0 )
      {
        LPC_GPIO1->IS &= ~(0x1<<bitPosi);
        /* single or double only applies when sense is 0(edge trigger). */
        if ( single == 0 )
          LPC_GPIO1->IBE &= ~(0x1<<bitPosi);
        else
          LPC_GPIO1->IBE |= (0x1<<bitPosi);
      }
      else
          LPC_GPIO1->IS |= (0x1<<bitPosi);
      if ( event == 0 )
        LPC_GPIO1->IEV &= ~(0x1<<bitPosi);
      else
        LPC_GPIO1->IEV |= (0x1<<bitPosi);  
    break;
    case PORT2:
      if ( sense == 0 )
      {
        LPC_GPIO2->IS &= ~(0x1<<bitPosi);
        /* single or double only applies when sense is 0(edge trigger). */
        if ( single == 0 )
          LPC_GPIO2->IBE &= ~(0x1<<bitPosi);
        else
          LPC_GPIO2->IBE |= (0x1<<bitPosi);
      }
      else
          LPC_GPIO2->IS |= (0x1<<bitPosi);
      if ( event == 0 )
        LPC_GPIO2->IEV &= ~(0x1<<bitPosi);
      else
        LPC_GPIO2->IEV |= (0x1<<bitPosi);  
    break;
    case PORT3:
      if ( sense == 0 )
      {
        LPC_GPIO3->IS &= ~(0x1<<bitPosi);
        /* single or double only applies when sense is 0(edge trigger). */
        if ( single == 0 )
          LPC_GPIO3->IBE &= ~(0x1<<bitPosi);
        else
          LPC_GPIO3->IBE |= (0x1<<bitPosi);
      }
      else
          LPC_GPIO3->IS |= (0x1<<bitPosi);
      if ( event == 0 )
        LPC_GPIO3->IEV &= ~(0x1<<bitPosi);
      else
        LPC_GPIO3->IEV |= (0x1<<bitPosi);      
    break;
    default:
      break;
  }
  return;
}

uint32_t GPIOIntStatus( uint32_t portNum, uint32_t bitPosi )
{
  uint32_t regVal = 0;

  switch ( portNum )
  {
    case PORT0:
      if ( LPC_GPIO0->MIS & (0x1<<bitPosi) )
        regVal = 1;
    break;
    case PORT1:
      if ( LPC_GPIO1->MIS & (0x1<<bitPosi) )
        regVal = 1;    
    break;
    case PORT2:
      if ( LPC_GPIO2->MIS & (0x1<<bitPosi) )
        regVal = 1;            
    break;
    case PORT3:
      if ( LPC_GPIO3->MIS & (0x1<<bitPosi) )
        regVal = 1;            
    break;
    default:
      break;
  }
  return ( regVal );
}

void GPIOIntClear( uint32_t portNum, uint32_t bitPosi )
{
  switch ( portNum )
  {
    case PORT0:
      LPC_GPIO0->IC |= (0x1<<bitPosi);
    break;
    case PORT1:
      LPC_GPIO1->IC |= (0x1<<bitPosi);    
    break;
    case PORT2:
      LPC_GPIO2->IC |= (0x1<<bitPosi);        
    break;
    case PORT3:
      LPC_GPIO3->IC |= (0x1<<bitPosi);        
    break;
    default:
      break;
  }
  return;
}

int main (void)
{
    // настройка реакции на фронт
    GPIOSetInterrupt(PORT1, 6, 0, 0, 1);
    SysTick_Config( SystemCoreClock/1000);
    while( 1 ) {
        if (GPIOIntStatus(PORT1, 6)) {
            GPIOIntClear(PORT1, 6);
            LedTimer=100;
            LPC_GPIO[0]->DATA|=(1<<7);
        }
    }
}

/********************************************************************************
*
**                            End Of File
********************************************************************************
*/


Сигнал на входе меняется от кнопки (также видно по значению LPC_GPIO[0]->DATA), но в
внутрь if (GPIOIntStatus(PORT1, 6)) {...} программа не попадает.
Подскажите, что делаю не так?
Если не те регистры опрашиваю, то какие нужно?
Спасибо.

Go to the top of the page
 
+Quote Post
Alex19
сообщение Oct 14 2011, 04:15
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 14-05-09
Из: Тула
Пользователь №: 49 063



У Вас тактирование портов не включено - необходимо в main перед настройкой реакции на фронт добавить - GPIOInit( );
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Oct 14 2011, 19:01
Сообщение #3


Гуру
******

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



Цитата(Alex19 @ Oct 14 2011, 07:15) *
У Вас тактирование портов не включено - необходимо в main перед настройкой реакции на фронт добавить - GPIOInit( );

Да, про тактирование забыл.
Но всё равно нет реакции.
Или не там смотрю.
Go to the top of the page
 
+Quote Post
adventurer
сообщение Oct 14 2011, 19:56
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 14-12-08
Пользователь №: 42 458



Макрос CONFIG_GPIO_DEFAULT_PIOINT1_IRQHANDLER == 1 ?
Функция NVIC_EnableIRQ(EINT1_IRQn); должна обязательно вызываться в коде инициализации, разрешает прерывания от порта 1
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Oct 14 2011, 20:48
Сообщение #5


Гуру
******

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



Цитата(adventurer @ Oct 14 2011, 22:56) *
Макрос CONFIG_GPIO_DEFAULT_PIOINT1_IRQHANDLER == 1 ?
Функция NVIC_EnableIRQ(EINT1_IRQn); должна обязательно вызываться в коде инициализации, разрешает прерывания от порта 1

C прерываниями вроде понятно как сделать(но правда ещё не пробовал), а как без прерываний? То есть не нужно уходить в прерывание, а достаточно флага, сообщающего о возникновении заданного перепада.
В отладчике менял уровень на входе с 0 на 1 и наоборот. Увидел изменения в LPC_GPIO1->RIS и на фронт и на срез и в LPC_GPIO1->DATA. Другие регистры порта не меняются.

Или без прерывания никак?
Go to the top of the page
 
+Quote Post
Alex19
сообщение Oct 15 2011, 08:36
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 14-05-09
Из: Тула
Пользователь №: 49 063



Без прерывания -

void GPIOIntEnable( uint32_t portNum, uint32_t bitPosi )
{
switch ( portNum )
{
case PORT0:
LPC_GPIO0->IE |= (0x1<<bitPosi);
break;
case PORT1:
LPC_GPIO1->IE |= (0x1<<bitPosi);
break;
case PORT2:
LPC_GPIO2->IE |= (0x1<<bitPosi);
break;
case PORT3:
LPC_GPIO3->IE |= (0x1<<bitPosi);
break;
default:
break;
}
return;
}

и добавить - GPIOIntEnable(PORT1, 6);
Если функция прерывания не описана, то строчка - NVIC_EnableIRQ(EINT1_IRQn); должна быть закоментирована.


Go to the top of the page
 
+Quote Post
_Артём_
сообщение Oct 15 2011, 13:20
Сообщение #7


Гуру
******

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



Цитата(Alex19 @ Oct 15 2011, 11:36) *
Без прерывания -

void GPIOIntEnable( uint32_t portNum, uint32_t bitPosi )
{
switch ( portNum )
{
case PORT0:
LPC_GPIO0->IE |= (0x1<<bitPosi);
break;
case PORT1:
LPC_GPIO1->IE |= (0x1<<bitPosi);
break;
case PORT2:
LPC_GPIO2->IE |= (0x1<<bitPosi);
break;
case PORT3:
LPC_GPIO3->IE |= (0x1<<bitPosi);
break;
default:
break;
}
return;
}

и добавить - GPIOIntEnable(PORT1, 6);
Если функция прерывания не описана, то строчка - NVIC_EnableIRQ(EINT1_IRQn); должна быть закоментирована.


То есть получается, что установленный бит в регистре IE разрешает реагирование на перепад/уровень, если функция прерывания не описана и разрешает также прерывание, если функция прерывания описана и вызывалась NVIC_EnableIRQ(EINT1_IRQn);.
Можно ли сделать так, чтобы например перепад на входе 1 порта 1 вызывал прерывание, а вход 2 того же порта устанавливал флаг изменения без перехода на функцию прерывания?
Или нельзя?
Go to the top of the page
 
+Quote Post

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

 


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


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