Артём__ 0 13 октября, 2011 Опубликовано 13 октября, 2011 · Жалоба Пытаюсь заставить 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)) {...} программа не попадает. Подскажите, что делаю не так? Если не те регистры опрашиваю, то какие нужно? Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex19 0 14 октября, 2011 Опубликовано 14 октября, 2011 · Жалоба У Вас тактирование портов не включено - необходимо в main перед настройкой реакции на фронт добавить - GPIOInit( ); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 14 октября, 2011 Опубликовано 14 октября, 2011 · Жалоба У Вас тактирование портов не включено - необходимо в main перед настройкой реакции на фронт добавить - GPIOInit( ); Да, про тактирование забыл. Но всё равно нет реакции. Или не там смотрю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adventurer 0 14 октября, 2011 Опубликовано 14 октября, 2011 · Жалоба Макрос CONFIG_GPIO_DEFAULT_PIOINT1_IRQHANDLER == 1 ? Функция NVIC_EnableIRQ(EINT1_IRQn); должна обязательно вызываться в коде инициализации, разрешает прерывания от порта 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 14 октября, 2011 Опубликовано 14 октября, 2011 · Жалоба Макрос CONFIG_GPIO_DEFAULT_PIOINT1_IRQHANDLER == 1 ? Функция NVIC_EnableIRQ(EINT1_IRQn); должна обязательно вызываться в коде инициализации, разрешает прерывания от порта 1 C прерываниями вроде понятно как сделать(но правда ещё не пробовал), а как без прерываний? То есть не нужно уходить в прерывание, а достаточно флага, сообщающего о возникновении заданного перепада. В отладчике менял уровень на входе с 0 на 1 и наоборот. Увидел изменения в LPC_GPIO1->RIS и на фронт и на срез и в LPC_GPIO1->DATA. Другие регистры порта не меняются. Или без прерывания никак? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex19 0 15 октября, 2011 Опубликовано 15 октября, 2011 · Жалоба Без прерывания - 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); должна быть закоментирована. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 15 октября, 2011 Опубликовано 15 октября, 2011 · Жалоба Без прерывания - 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 того же порта устанавливал флаг изменения без перехода на функцию прерывания? Или нельзя? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться