|
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
|
|
|
|
|
Aug 28 2008, 20:41
|

Участник

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

|
Цитата(aaarrr @ Aug 29 2008, 00:21)  В стартапе (если разрешил, конечно). стартап я не менял, значит не разрешил скорее всего, потолму чот не знаю как. подскажите плиз где это нужно сделать в стартапе?
Сообщение отредактировал i.dmitry - Aug 28 2008, 21:04
|
|
|
|
|
Aug 29 2008, 17:00
|

Участник

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

|
Цитата(aaarrr @ Aug 29 2008, 00:13)  Попробуйте перенести мигание в основной цикл и посмотреть, не зависает ли процессор при получении прерывания. сделал, как вы советовали. нет, не зависает. нормально мигает. Цитата Автору, в прерываниях большие задержки ставить глупо, лучше ивертировать состояние, тогда светодиод должен мигать раз в четыре секунды. это как? вместо Код IO0CLR = LED; //turn on LED Soft_Delay(DELAY); //delay IO0SET = LED; //turn off LED Soft_Delay(DELAY); //delay сделать так: Код static DWORD tmp = LED; - объявить глобально а в обраб. прерывания: Код __irq void IRQ_Handler(void) { //Blink(); // LED Blink ~0.5 sec tmp = ~tmp; IO0CLR = tmp; IO0SET = ~tmp; T0IR = 0x00; // Clear the interrupt flag } Цитата Код а почему неверный? что тогда делает следующая строчка: VICIntEnable = TIMER0_INT; как я понял это Interrupt Enable Register. Да, VIC'а. А есть еще разрешение прерываний у ядра. это нужно разрешать в стартапе как я понял из предыдущих постов. может кто-нибудь ткнуть пальцем в мой стартап где это сделано? я постараюсь разобраться. я ошибся в предыдущем посте. в стартапе было написано Код FIQ_Addr DCD FIQ_Handler а у меня в коде IRQ_Handler. это изменил. далее в бесконечный цикл поставил мигание диода. запустил. диод начал мигать. дальше перестал. 2) я закоментировал прототип обработчика и саму функцию обработчика. результат - тот же. мигал, потом перестал. пото м я закоментировал еще и это Код VICIntSelect = TIMER0_INT; //assign TIMER0 intterupt to FIQ category VICIntEnable = TIMER0_INT; //Enable TIMER0 interrupt и он начал мигать без сбоев. что-от происходит при входе в прерыванеи навернео
Сообщение отредактировал i.dmitry - Aug 29 2008, 16:51
Прикрепленные файлы
led2.rar ( 40.36 килобайт )
Кол-во скачиваний: 29
|
|
|
|
|
Aug 29 2008, 17:26
|

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

|
Полное непонимание того, что пишите и железа. Этот код, конечно, можно залатать, дабы мигал, но дерьмом он так и останется. Начните с еще более простых вещей, и ... ну и с "C".... Залатанные файлы в приложении.
Прикрепленные файлы
L.rar ( 3.76 килобайт )
Кол-во скачиваний: 27
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|