i.dmitry 0 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба исходные данные: плата Olimex LPC-P2148 cpu: lpc2148 хочу: мигать светодиодом каждые 2 секунды по прерыванию от таймера 0 результат: вообще ничего не происходит (не мигает) код задержки void Soft_Delay (DWORD N) { volatile DWORD i; for (i=0; i<N; i++) { ; } return; } код main: //****************************************************************************** // GLOBAL DEFINITIONS //****************************************************************************** #define TIMER0_INT 0x00000010 #define LED 0x00000400 // P0.10 pin #define PRESCALE_VAL 0x0001869F // TC increments on every 100000 PCLK #define MATCH_VAL 0x00000078 // Match on 120 value (decimal) #define MATCH_CONFIG 0x0003 // Interrupt on MR0; Reset on MR0 //****************************************************************************** // FUNCTION PROTOTYPE //****************************************************************************** __irq void FIQ_Handler (void); //****************************************************************************** // CODE //****************************************************************************** int main() { //Fosc = 12 MHz Init_PLL(0x42, 0x00); // CCLK = 2*Fosc = 24 MHz; PCLK = CCLK / 4 = 6 MHz IO0DIR=LED; // Set P0.10 as output IO0SET=LED; // initially turn OFF LED Init_Timer(PRESCALE_VAL, MATCH_VAL, MATCH_CONFIG); Enable_Timer(0x00); // Timer 0 enable VICIntSelect = TIMER0_INT; //assign TIMER0 intterupt to FIQ category VICIntEnable = TIMER0_INT; //Enable TIMER0 interrupt while(1) { ; } } //interupt handler function __irq void FIQ_Handler (void) { IO0CLR=LED; // turn ON LED Soft_Delay(10000000); // delay IO0SET=LED; // turn OFF LED T0IR = 0x00; // Clear the interrupt flag } код PLL_Init void Init_PLL (BYTE MP_Mask, BYTE PCLK_Mask) { //set multiplier and divider of the PLL0 PLL0CFG = MP_Mask; //enable PLL0 PLL0CON = 0x1; //provide feed sequence PLL0FEED = 0xAA; PLL0FEED = 0x55; //wait until PLL0 is locked while (!(PLL0STAT & PLL0_LOCKED)) { ; } //connect PLL0 PLL0CON = 0x3; //provide feed sequence PLL0FEED = 0xAA; PLL0FEED = 0x55; //set peripheral clock VPBDIV = PCLK_Mask; return; } Init_timer: void Init_Timer(DWORD Prescale_Val, DWORD Match_Val, WORD Match_Config) { T0PR = Prescale_Val; T0MR0 = Match_Val; T0MCR = Match_Config; return; } void Enable_Timer(BYTE Timer_Num) { if (Timer_Num==0) { T0TCR = 0x01; } else { T1TCR = 0x01; } return; } PCLK настроил на 6 МГц (VPBDIV=0 --> pclk=0.25*cclk), в таймере Prescale настроил на 100000 чтобы счетчик считал с частотой 60 Герц (6MHz/100000), в MR записал 120 (120/60 = 2 сек), т.е. каждые 2 секнды должно быть прерывание по таймеру 0 и LED должен мигнуть. но этого не происходит ... в чем проблема - понять не могу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sKWO 0 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба i.dmitry, с lpc не работал. может причина в том что вы не разрешили прерывания в мэйне после инициализации периферии? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
i.dmitry 0 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба i.dmitry, с lpc не работал. может причина в том что вы не разрешили прерывания в мэйне после инициализации периферии? вроде бы разрешил: VICIntEnable = TIMER0_INT; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба Ужас-ужас :07: //interupt handler function __irq void FIQ_Handler (void) { IO0CLR=LED; // turn ON LED Soft_Delay(10000000); // delay IO0SET=LED; // turn OFF LED T0IR = 0x00; // Clear the interrupt flag } Soft_Delay(10000000) у Вас сколько по времени выполняется? Я уж не говорю о том, что использовать такие конструкции в прерывании вообще некорректно, но Вы просто можете получить такую картину: LED_SET->LED_CLR->Soft_Delay(очень много)->LED_SET->LED_CLR-> и ничего мигать (заметно) не будет. Просто инвертируйте вывод диода в прерывании, без всяких задержек. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
i.dmitry 0 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба Ужас-ужас :07: //interupt handler function __irq void FIQ_Handler (void) { IO0CLR=LED; // turn ON LED Soft_Delay(10000000); // delay IO0SET=LED; // turn OFF LED T0IR = 0x00; // Clear the interrupt flag } Soft_Delay(10000000) у Вас сколько по времени выполняется? Я уж не говорю о том, что использовать такие конструкции в прерывании вообще некорректно, но Вы просто можете получить такую картину: LED_SET->LED_CLR->Soft_Delay(очень много)->LED_SET->LED_CLR-> и ничего мигать (заметно) не будет. Просто инвертируйте вывод диода в прерывании, без всяких задержек. я скопировал эту часть кода пару раз в начало программы до бесконечного цикла. светодиод мигнул пару раз примерно на 1.5 сек. так что задержка вполне нормальная. IO0CLR=LED; // turn ON LED Soft_Delay(10000000); // delay IO0SET=LED; // turn OFF LED далее я изменил функции следующим образом, чтобы как только произошло прерывание, он в нем и остался и диод горел бы: //interupt handler function __irq void FIQ_Handler (void) { IO0CLR=LED; // turn ON LED // Soft_Delay(10000000); // delay // IO0SET=LED; // turn OFF LED // T0IR = 0x00; // Clear the interrupt flag } но он не подает признаков жизни в этом случае, значит наверное не происходит входа в функции обработчик прерывания Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба но он не подает признаков жизни в этом случае, значит наверное не происходит входа в функции обработчик прерывания 1. Вас уже спрашивали, а FIQ-то разрешили контроллеру обрабатывать - ответ был неверный. 2. Ну кто у Вас обработчик-то вызывает? startup правили? 3. Стек-то инициализировали? 4. Eсли компилятор подддерживает,то лучше _fiq. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба но он не подает признаков жизни в этом случае, значит наверное не происходит входа в функции обработчик прерывания Или грохается при входе. FIQ точно разрешено? С вектором все в порядке? Попробуйте перенести мигание в основной цикл и посмотреть, не зависает ли процессор при получении прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sKWO 0 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба Народ, подскажите а чё в ЛПС нету регистра статуса с битиком разрешения глобального прерывания. Автору, в прерываниях большие задержки ставить глупо, лучше ивертировать состояние, тогда светодиод должен мигать раз в четыре секунды. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба Народ, подскажите а чё в ЛПС нету регистра статуса с битиком разрешения глобального прерывания. В ARM7 вообще и в LPC в частности - целых два. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sKWO 0 28 августа, 2008 Опубликовано 28 августа, 2008 (изменено) · Жалоба В ARM7 вообще и в LPC в частности - целых два. Подскажите, где автор разрешил глобально прерывание? не глобальное а глобально, спасибо aaarrr, Вы и так поняли. Изменено 28 августа, 2008 пользователем sKWO Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба Подскажите, где автор разрешил глобальное прерывание? В стартапе (если разрешил, конечно). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
i.dmitry 0 28 августа, 2008 Опубликовано 28 августа, 2008 (изменено) · Жалоба 1. Вас уже спрашивали, а FIQ-то разрешили контроллеру обрабатывать - ответ был неверный. а почему неверный? что тогда делает следующая строчка: VICIntEnable = TIMER0_INT; как я понял это Interrupt Enable Register. startup я взял готовый из сборки code.bundle.lpc213x.lpc214x.uvision.zip готовых примеров. судя по тому, что там написано, то все должно быть правильно наверное. я со стартапом столкнулся в первый раз, если что-то не так, то скажите, пожалуйсто, где нужно прочитать об этом // Pre-defined interrupt handlers that may be directly // overwritten by C interrupt functions EXTERN CODE32 (Undef_Handler?A) EXTERN CODE32 (SWI_Handler?A) EXTERN CODE32 (PAbt_Handler?A) EXTERN CODE32 (DAbt_Handler?A) EXTERN CODE32 (IRQ_Handler?A) EXTERN CODE32 (FIQ_Handler?A) // Exception Vectors // Mapped to Address 0. // Absolute addressing mode must be used. Vectors: LDR PC,Reset_Addr LDR PC,Undef_Addr LDR PC,SWI_Addr LDR PC,PAbt_Addr LDR PC,DAbt_Addr NOP /* Reserved Vector */ ; LDR PC,IRQ_Addr LDR PC,[PC, #-0x0FF0] /* Vector from VicVectAddr */ LDR PC,FIQ_Addr Reset_Addr: DD Reset_Handler Undef_Addr: DD Undef_Handler?A SWI_Addr: DD SWI_Handler?A PAbt_Addr: DD PAbt_Handler?A DAbt_Addr: DD DAbt_Handler?A DD 0 /* Reserved Address */ IRQ_Addr: DD IRQ_Handler?A FIQ_Addr: DD FIQ_Handler?A насколько я понял это, то что мне надо... LDR PC,FIQ_Addr FIQ_Addr: DD FIQ_Handler?A Изменено 28 августа, 2008 пользователем i.dmitry Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба а почему неверный? Потому, что не о том. Перечитайте неcколько предыдущих постов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 64 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба а почему неверный? что тогда делает следующая строчка: VICIntEnable = TIMER0_INT; как я понял это Interrupt Enable Register. Да, VIC'а. А есть еще разрешение прерываний у ядра. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 28 августа, 2008 Опубликовано 28 августа, 2008 · Жалоба насколько я понял это, то что мне надо... Сгодится... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться