Перейти к содержанию
    

исходные данные:

плата 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 должен мигнуть.

 

но этого не происходит ... в чем проблема - понять не могу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

i.dmitry, с lpc не работал. может причина в том что вы не разрешили прерывания в мэйне после инициализации периферии?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

i.dmitry, с lpc не работал. может причина в том что вы не разрешили прерывания в мэйне после инициализации периферии?

вроде бы разрешил:

VICIntEnable = TIMER0_INT;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ужас-ужас :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->

и ничего мигать (заметно) не будет.

 

Просто инвертируйте вывод диода в прерывании, без всяких задержек.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ужас-ужас :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  
}

но он не подает признаков жизни в этом случае, значит наверное не происходит входа в функции обработчик прерывания

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но он не подает признаков жизни в этом случае, значит наверное не происходит входа в функции обработчик прерывания

1. Вас уже спрашивали, а FIQ-то разрешили контроллеру обрабатывать - ответ был неверный.

2. Ну кто у Вас обработчик-то вызывает? startup правили?

3. Стек-то инициализировали?

4. Eсли компилятор подддерживает,то лучше _fiq.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но он не подает признаков жизни в этом случае, значит наверное не происходит входа в функции обработчик прерывания

Или грохается при входе. FIQ точно разрешено? С вектором все в порядке?

Попробуйте перенести мигание в основной цикл и посмотреть, не зависает ли процессор при получении прерывания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Народ, подскажите а чё в ЛПС нету регистра статуса с битиком разрешения глобального прерывания.

Автору, в прерываниях большие задержки ставить глупо, лучше ивертировать состояние, тогда светодиод должен мигать раз в четыре секунды.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Народ, подскажите а чё в ЛПС нету регистра статуса с битиком разрешения глобального прерывания.

В ARM7 вообще и в LPC в частности - целых два.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В ARM7 вообще и в LPC в частности - целых два.

Подскажите, где автор разрешил глобально прерывание?

не глобальное а глобально, спасибо aaarrr, Вы и так поняли.

Изменено пользователем sKWO

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите, где автор разрешил глобальное прерывание?

В стартапе (если разрешил, конечно).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а почему неверный?

Потому, что не о том. Перечитайте неcколько предыдущих постов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а почему неверный?

что тогда делает следующая строчка:

VICIntEnable = TIMER0_INT;

как я понял это Interrupt Enable Register.

Да, VIC'а. А есть еще разрешение прерываний у ядра.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...