Как определить подпрограмму обработки прерываний для lpc2138 в IAR EWARM 8.4? - PullRequest
0 голосов
/ 29 сентября 2019

Я разрабатываю проект с использованием lpc2138 в IAR для ARM 8.4. Я собирался использовать прерывание Timer0 для получения периода 1 мс, поэтому я написал код и смоделировал в протеусе 8.9. Но прерывание не происходит. Пожалуйста, исправьте мой код ошибки.

Внешний кварцевый генератор - 20 МГц

#include    <intrinsics.h>
#include    <nxp/iolpc2138.h>

#define TEST    IO0PIN_bit.P0_30

Прерывание по таймеру 0

// #pragma vector = IRQV  // no effect
__irq void irq_handler (void)
{
  void (*interrupt_function)();
  unsigned int vector;

  vector = VICVectAddr;                   
  interrupt_function = (void(*)())vector;
  (*interrupt_function)();  
  VICVectAddr = 0;        
}

void T0_ISR()
{
    uint8 regVal;
    regVal = T0IR; // read the current value in T0's Interrupt Register

    //if( T0IR_bit.MR0INT )
    //{
      TEST ^= 1;
    //}

    T0IR = regVal; // write back to clear the interrupt flag
    //VICVectAddr = 0; // Acknowledge that ISR has finished execution
}

инициализация оборудования

void initPort()
{
    IO0PIN = 0;
    IO0DIR = 0xF0000003;  // 2 led : out
}

void initClock()
{
    setupPLL();
    feedSeq(); //sequence for locking PLL to desired freq.
    connectPLL();
    feedSeq(); //sequence for connecting the PLL as system clock

    //SysClock is now ticking @ 60Mhz!
    VPBDIV = 0x01; // PCLK is same as CCLK i.e 60Mhz
}

//---------PLL Related Functions :---------------
void setupPLL()
{
  //Note : Assuming 20Mhz Xtal is connected to LPC2138.
  PLLCON = 0x01; // PLLE=1 & PLLC=0
  PLLCFG = 0x22; // set the multipler to 3 (i.e actually 2)
                 // i.e 20x3 = 60 Mhz (M - 1 = 2)!!!
                 // Set P=2 since we want FCCO in range!!!
                 // Assign PSEL = 01 in PLLCFG, then F_CCO = 240MHz!!!
}

void feedSeq()
{
  PLLFEED = 0xAA;
  PLLFEED = 0x55;
}

void connectPLL()
{
  while(PLLSTAT_bit.PLOCK == 0);

  // now enable(again) and connect
  PLLCON = 0x03;
}

void initTimer()
{
  /*----------------- Configure Timer0 --------------------*/
  T0TC = 0;       // Clear Timer Counter
  T0PC = 0;       // Clear Prescaler Counter
  T0TCR = 0x02;   // Reset TC and PR
  T0CTCR = 0x00;  // Timer mode, increment on every rising PCLK edge
  T0PR = 59;      // Load PreScalar with 59 (0 to 59 = 60), 1us 
  T0MR0 = 999;    // Load timer counter for 1ms delay, 1us*1000
  T0MCR = 0x0003; // Interrupt generate on match and reset timer

  /*-------------- Set Timer0 Interrupt ------------------*/
  VICVectAddr0 = (unsigned)T0_ISR;          /* T0 ISR Address */
  VICVectCntl0 = 0x00000020 | VIC_TIMER0;    /* Enable T0 IRQ slot */
  VICIntEnable |= (1<<VIC_TIMER0);           /* Enable T0 interrupt */
  VICIntSelect &= ~(1<<VIC_TIMER0);          /* T0 configured as IRQ */

  T0TCR = 0x01;   // Enable timer
}

main () функция

void main()
{
  initPort();
  initClock();
  initTimer();

  //__enable_irq();
  __enable_interrupt();

  while(1);
}
...