|
timer0 interrupt, led blinking |
|
|
|
Aug 28 2008, 18:28
|

Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-07-07
Пользователь №: 28 963

|
исходные данные: плата 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 должен мигнуть. но этого не происходит ... в чем проблема - понять не могу.
|
|
|
|
|
Aug 28 2008, 19:36
|

Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-07-07
Пользователь №: 28 963

|
Цитата(sKWO @ Aug 28 2008, 23:13)  i.dmitry, с lpc не работал. может причина в том что вы не разрешили прерывания в мэйне после инициализации периферии? вроде бы разрешил: VICIntEnable = TIMER0_INT;
|
|
|
|
|
Aug 28 2008, 19:39
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Ужас-ужас Код //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-> и ничего мигать (заметно) не будет. Просто инвертируйте вывод диода в прерывании, без всяких задержек.
|
|
|
|
|
Aug 28 2008, 20:01
|

Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-07-07
Пользователь №: 28 963

|
Цитата(aaarrr @ Aug 28 2008, 23:39)  Ужас-ужас Код //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 } но он не подает признаков жизни в этом случае, значит наверное не происходит входа в функции обработчик прерывания
|
|
|
|
|
Aug 28 2008, 20:11
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(i.dmitry @ Aug 28 2008, 22:01)  но он не подает признаков жизни в этом случае, значит наверное не происходит входа в функции обработчик прерывания 1. Вас уже спрашивали, а FIQ-то разрешили контроллеру обрабатывать - ответ был неверный. 2. Ну кто у Вас обработчик-то вызывает? startup правили? 3. Стек-то инициализировали? 4. Eсли компилятор подддерживает,то лучше _fiq.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Aug 28 2008, 20:19
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(aaarrr @ Aug 28 2008, 23:16)  В ARM7 вообще и в LPC в частности - целых два. Подскажите, где автор разрешил глобально прерывание? не глобальное а глобально, спасибо aaarrr, Вы и так поняли.
Сообщение отредактировал sKWO - Aug 28 2008, 20:31
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 28 2008, 20:25
|

Участник

Группа: Участник
Сообщений: 35
Регистрация: 8-07-07
Пользователь №: 28 963

|
Цитата(zltigo @ Aug 29 2008, 00:11)  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
Сообщение отредактировал i.dmitry - Aug 28 2008, 20:26
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|