logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ARM LPC2142 KEIL - Jak uruchomić przerwanie IRQ dla Timera?

Arobabajaro 22 Sie 2013 16:42 1416 2
REKLAMA
  • #1 12655980
    Arobabajaro
    Poziom 2  
    Posty: 2
    Witam,

    Probuje potestować przerwania IRQ dla TImera. Podbralem sobie przyklady Bryndzy
    i po malych przerobkach nie za bardzo o dziala.

    Po samych ustawianiach Timera wchodzac do petli while flaga T0IR jest ustawiana, czyli funkcjonalnie jako tak śmiaga. Ale niestety nie działa jeśli probuje czy zostalo to zhandlowane jako IRQ ( iniclajlizacja parametrow copy paste z przykladow )

    Ktos/cos ?

    #include "lpc214x.h"
    #include "armint.h"
    //#include "CLcdDisp.h"
    /**************************************************
    * Mikrokontrolery z rdzeniem ARM - pierwsze kroki*
    * Autor: Lucjan Bryndza *
    * Timer0 jako czasomierz systemowy *
    **************************************************/

    #define TIMER0_VIC (1<<4)
    #define TIMER0_VIC_BIT 4
    #define VIC_IRQSLOT_EN (1<<5)


    #define T0MCR_Interrupt_on_MR0 0x1U
    #define T0MCR_Reset_on_MR0 0x2U
    #define T0TCR_Counter_Reset 0x2U
    #define T0TCR_Counter_Enable 0x1U
    #define T0IR_MR0 0x1U

    //Przerwanie wektoryzowane IRQ
    void IrqTimerHandler(void) __attribute__ ((interrupt("IRQ")));

    static volatile unsigned int TimerCnt;

    void IrqTimerHandler(void)
    {
    //Zmien stan LEDOW na przeciwny
    TimerCnt++;
    //Kasuj zrodlo przerwania
    T0IR = T0IR_MR0;
    //Informacja dla VIC - koniec procedury przerwania
    VICVectAddr = 0;
    }


    //CLcdDisp cout;
    /* Funkcja glowna main */
    int main(void)
    {

    //Licznik zlicza impulsy z czestotliwoscia 15Hz
    T0PR = 3999999;
    //Gdy warunek spelniony zeruj Timer i zglaszaj przerwanie
    T0MCR |= T0MCR_Interrupt_on_MR0 | T0MCR_Reset_on_MR0;
    //Przeladowanie licznika co 1s
    T0MR0 = 15;
    //Zeruj licznik i preskaler
    T0TCR = T0TCR_Counter_Reset;
    //Zalacz licznik T0
    T0TCR = T0TCR_Counter_Enable;
    //Wektor 0
    VICVectAddr0 = (unsigned int)IrqTimerHandler;
    VICVectCntl0 = TIMER0_VIC_BIT | VIC_IRQSLOT_EN;
    //Zalaczenie przerwania
    VICIntEnable = TIMER0_VIC;
    //Zalacz IRQ
    //enable_irq();

    while(1)
    {
    // Sprawdzanie flagi dziala ale chce na IRQ
    /*
    if(1 == T0IR)
    {
    IrqTimerHandler();
    }
    */
    }
    return 0;
    }


    #ifndef ARMINT_H_
    #define ARMINT_H_

    typedef unsigned long cpu_t;
    #ifdef __cplusplus

    extern "C"
    {
    #endif /*__cplusplus*/

    cpu_t disable_irq(void);
    cpu_t enable_irq(void);
    cpu_t restore_irq(cpu_t old_cpsr);
    cpu_t disable_fiq(void);
    cpu_t enable_fiq(void);
    cpu_t restore_fiq(cpu_t old_cpsr);

    #ifdef __cplusplus
    }
    #endif /*__cplusplus*/


    #endif /*ARMINT_H_*/



    #include "armint.h"
    #include "lpc214x.h"

    #define IRQ_MASK 0x00000080
    #define FIQ_MASK 0x00000040
    #define INT_MASK (IRQ_MASK|FIQ_MASK)


    static cpu_t get_cpsr(void)
    {
    cpu_t my_cpsr;
    __asm
    {
    MRS my_cpsr, CPSR
    }
    return my_cpsr;
    }

    static void set_cpsr(cpu_t my_cpsr)
    {
    //asm volatile ("msr cpsr, %[val]\n" ::[val]"r"(val) );

    __asm
    {
    MSR CPSR_c, my_cpsr
    }
    }

    cpu_t disable_irq(void)
    {
    cpu_t cpsr;
    cpsr = get_cpsr();
    set_cpsr(cpsr | IRQ_MASK);
    return cpsr;
    }

    cpu_t enable_irq(void)
    {
    cpu_t cpsr;
    cpsr = get_cpsr();
    set_cpsr(cpsr & ~IRQ_MASK);
    return cpsr;
    }

    cpu_t restore_irq(cpu_t old_cpsr)
    {
    cpu_t cpsr;
    cpsr = get_cpsr();
    set_cpsr( (cpsr & ~IRQ_MASK) | (old_cpsr & IRQ_MASK) );
    return cpsr;
    }

    cpu_t disable_fiq(void)
    {
    cpu_t cpsr;
    cpsr = get_cpsr();
    set_cpsr(cpsr | FIQ_MASK);
    return cpsr;
    }

    cpu_t enable_fiq(void)
    {
    cpu_t cpsr;
    cpsr = get_cpsr();
    set_cpsr(cpsr & ~FIQ_MASK);
    return cpsr;
    }

    cpu_t restore_fiq(cpu_t old_cpsr)
    {
    cpu_t cpsr;
    cpsr = get_cpsr();
    set_cpsr( (cpsr & ~FIQ_MASK) | (old_cpsr & FIQ_MASK) );
    return cpsr;
    }
  • REKLAMA
  • #2 12656398
    Electix
    Poziom 21  
    Posty: 462
    Pomógł: 46
    Ocena: 6
    Wszystko zależy od tego, czym u Ciebie jest Keil.

    1. Środowisko programistyczne od A do Z i korzystasz z toolchain'a The ARM C/C++ Compiler (armcc)
    i w tym wypadku musisz zmodernizować ten kod ponieważ nie jest do końca zgodny z syntaktyką tego kompilatora.

    2. Używasz Keila tylko jako edytora, a Twoim toolchain'em jest ARM GCC. Wtedy możesz stosować tą syntaktykę, a błędu trzeba będzie szukać gdzie indziej.

    Podpowiem Ci, że w ARMCC funkcję obsługi przerwania deklaruje się / definiuje się tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #3 12656709
    Arobabajaro
    Poziom 2  
    Posty: 2
    Hi

    Dzieki za komentarze poszedlem w druga strone i teraz instaluje zgodnie z
    http://vsdev.me/notes/setting_up_arm_gcc_windows/

    Aha przywrocilem jeszcze z orginalnych przykladow

    static inline cpu_t get_cpsr(void)
    {
    cpu_t val;
    asm volatile ("mrs %[val], cpsr\n":[val]"=r"(val):);
    return val;
    }

    static inline void set_cpsr(cpu_t val)
    {
    asm volatile ("msr cpsr, %[val]\n" ::[val]"r"(val) );
    }

    Nastąpił armagedon, zwykly projekt UART symulator kompilowany ( opcja 1 Twojej wypowiedzi ) dziala ale po przestawieniu w Target > ManageComponents >Folders > Select ARM Development Tools z opcja use gcc zasypal bledami

    Rebuild target 'Target 1'
    assembling Startup.s...
    Startup.s: Assembler messages:
    Startup.s(37): error: bad instruction `standard definitions of Mode bits and Interrupt(I&F)flags in PSRs'
    Startup.s(39): error: bad instruction `mode_usr EQU 0x10'
    Startup.s(40): error: bad instruction `mode_fiq EQU 0x11'


    Na czystym projekcie z reszta to samo :/
REKLAMA