首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定时器中断从不用LPC1769 LPCXpresso命中LPC1769

定时器中断从不用LPC1769 LPCXpresso命中LPC1769
EN

Stack Overflow用户
提问于 2019-03-05 13:09:56
回答 1查看 664关注 0票数 0

我有LPC1769 LPCXpresso和Link 2进行调试.我的开发环境是IAR。

我想体验一个简单的LED闪烁使用计时器。网络上有许多示例代码。所以,我挑选了一个为MCB1700板制作的样品。我也读过一些关于计时器如何与LPC一起工作的文章。

代码编译后,我将程序下载到设备(LPC1769)。当定时器按给定的间隔调用处理程序时,我假设LED应该闪烁。

但是,这个程序从来没有访问过TIMER0_IRQHandler。

以下是我的main.c文件中的完整代码:

代码语言:javascript
复制
#include <lpc17xx.h>

void TIMER0_IRQHandler(void);

int main(void) 
{
  // (1) Timer 0 configuration (see page 490 of user manual)
  LPC_SC->PCONP |= 1 << 1; // Power up Timer 0 (see page 63 of user manual)
  LPC_SC->PCLKSEL0 |= 1 << 2; // Clock for timer = CCLK, i.e., CPU Clock (page 56 user manual)
  // MR0 is "Match Register 0". MR0 can be enabled through the MCR to reset
  // the Timer/Counter (TC), stop both the TC and PC, and/or generate an interrupt
  // every time MR0 matches the TC. (see page 492 and 496 of user manual)

  LPC_TIM0->MR0 = 500; //Toggle Time in mS
  //LPC_TIM0->MR0 = 1 << 23; // Give a value suitable for the LED blinking

  // frequency based on the clock frequency
  // MCR is "Match Control Register". The MCR is used to control if an
  // interrupt is generated and if the TC is reset when a Match occurs.
  // (see page 492 and 496 of user manual)
  LPC_TIM0->MCR |= 1 << 0; // Interrupt on Match 0 compare
  LPC_TIM0->MCR |= 1 << 1; // Reset timer on Match 0
  // TCR is "Timer Control Register". The TCR is used to control the Timer
  // Counter functions. The Timer Counter can be disabled or reset
  // through the TCR. (see page 492 and 494 of user manual)
  LPC_TIM0->TCR |= 1 << 1; // Manually Reset Timer 0 (forced);
  LPC_TIM0->TCR &= ~(1 << 1); // Stop resetting the timer
  // (2) Enable timer interrupt;
  // TIMER0_IRQn is 1, see lpc17xx.h and page 73 of user manual
  NVIC_EnableIRQ(TIMER0_IRQn); // see core_cm3.h header file
  // (3) Some more one-time set-up's;
  LPC_TIM0->TCR |= 1 << 0; // Start timer (see page 492 and 494 of user manual)
  LPC_SC->PCONP |= ( 1 << 15 ); // Power up GPIO (see lab1)
  LPC_GPIO1->FIODIR |= 1 << 29; // Put P1.29 into output mode. LED is connected to P1.29
  // (4) infinite loop;
  while (1) // Why do we need this?
  {
    //LPC_GPIO1->FIOPIN ^= 1 << 29; // Toggle the LED (see lab1)
  }
  return 0;
}


// Here, we describe what should be done when the interrupt on Timer 0 is handled;
// We do that by writing this function, whose address is “recorded” in the vector table
// from file startup_LPC17xx.s under the name TIMER0_IRQHandler;
void TIMER0_IRQHandler(void)
{
  // IR is "Interrupt Register". The IR can be written to clear interrupts. The IR
  // can be read to identify which of eight possible interrupt sources are
  // pending. (see page 492 and 493 of user manual)
  if ( (LPC_TIM0->IR & 0x01) == 0x01 ) // if MR0 interrupt (this is a sanity check);
  {
    LPC_TIM0->IR |= 1 << 0; // Clear MR0 interrupt flag (see page 492 and 493 of user manual)
    LPC_GPIO1->FIOPIN ^= 1 << 29; // Toggle the LED (see lab1)
  }
}

任何指针都将不胜感激。

编辑

供将来有类似问题的人参考,这是我的工作代码;

我用我从各地收集到的知识重写了一遍。现在它起作用了,所有处理程序都会被触发。这一次我想用多个计时器进行测试。下面是两个Timer-IRQSysTick的实现。

代码语言:javascript
复制
#include "LPC17xx.h"

#define SBIT_TIMER0  1
#define SBIT_TIMER1  2

#define SBIT_MR0I    0
#define SBIT_MR0R    1

#define SBIT_CNTEN   0

#define PCLK_TIMER0  2
#define PCLK_TIMER1  4    

#define LED1         0 // P2_0
#define LED2         1 // P2_1

#define MiliToMicroSec(x)  (x*1000)  /* ms is multiplied by 1000 to get us*/

extern unsigned int SystemCoreClock;
unsigned int getPrescalarForUs(uint8_t timerPclkBit);

static int data_main = 0;
static int data_systick = 0;

void Delay(uint32_t Dly)
{
   for(volatile uint32_t j = Dly; j; j--) { }
}

void SysTick_Handler(void)
{
   data_systick += 10;
}

int main (void) 
{
    SystemInit();

    LPC_SC->PCONP |= (1<<SBIT_TIMER0) | (1<<SBIT_TIMER1); /* Power ON Timer0,1 */

    LPC_TIM0->MCR  = (1<<SBIT_MR0I) | (1<<SBIT_MR0R);     /* Clear TC on MR0 match and Generate Interrupt*/
    LPC_TIM0->PR   = getPrescalarForUs(PCLK_TIMER0);      /* Prescalar for 1us */
    LPC_TIM0->MR0  = MiliToMicroSec(100);                 /* Load timer value to generate 100ms delay*/
    LPC_TIM0->TCR  = (1 <<SBIT_CNTEN);                    /* Start timer by setting the Counter Enable*/
    NVIC_EnableIRQ(TIMER0_IRQn);                          /* Enable Timer0 Interrupt */

    LPC_TIM1->MCR  = (1<<SBIT_MR0I) | (1<<SBIT_MR0R);     /* Clear TC on MR0 match and Generate Interrupt*/
    LPC_TIM1->PR   = getPrescalarForUs(PCLK_TIMER1);      /* Prescalar for 1us */
    LPC_TIM1->MR0  = MiliToMicroSec(500);                 /* Load timer value to generate 500ms delay*/
    LPC_TIM1->TCR  = (1 <<SBIT_CNTEN);                    /* Start timer by setting the Counter Enable*/
    NVIC_EnableIRQ(TIMER1_IRQn);                          /* Enable Timer1 Interrupt */

    LPC_GPIO2->FIODIR = (1<<LED1) | (1<<LED2);            /* Configure the LED pins(P2_0,P2_1) as outputs */

    SysTick_Config(900000);

    while(1)
    {
        data_main++;       
    }
}


void TIMER0_IRQHandler(void)
{
    unsigned int isrMask;

    isrMask = LPC_TIM0->IR; 
    LPC_TIM0->IR = isrMask;         /* Clear the Interrupt Bit */

    LPC_GPIO2->FIOPIN ^= (1<<LED1); /* Toggle the LED1 (P2_0) */
}


void TIMER1_IRQHandler(void)
{
    unsigned int isrMask;

    isrMask = LPC_TIM1->IR;
    LPC_TIM1->IR = isrMask;        /* Clear the Interrupt Bit */

    LPC_GPIO2->FIOPIN ^= (1<<LED2); /* Toggle the LED2 (P2_1) */
}


unsigned int getPrescalarForUs(uint8_t timerPclkBit)
{
    unsigned int pclk,prescalarForUs;
    pclk = (LPC_SC->PCLKSEL0 >> timerPclkBit) & 0x03;  /* get the pclk info for required timer */

    switch ( pclk )                                    /* Decode the bits to determine the pclk*/
    {
    case 0x00:
        pclk = SystemCoreClock/4;
        break;

    case 0x01:
        pclk = SystemCoreClock;
        break; 

    case 0x02:
        pclk = SystemCoreClock/2;
        break; 

    case 0x03:
        pclk = SystemCoreClock/8;
        break;

    default:
        pclk = SystemCoreClock/4;
        break;  
    }

    prescalarForUs =pclk/1000000 - 1;                    /* Prescalar for 1us (1000000Counts/sec) */

    return prescalarForUs;
}
EN

回答 1

Stack Overflow用户

发布于 2019-03-05 21:40:41

我运行了您的代码,我可以告诉您,TIMER0_IRQHandler确实正在执行,至少对我来说是这样。要证明这一点,请尝试运行IAR调试器并在行中设置一个“断点”:

代码语言:javascript
复制
void TIMER0_IRQHandler(void)

每次输入函数时,程序都会在此函数调用时暂停。

对于lpc1769的低级函数调用,我没有太多的经验,但是我可以看到,代码中的问题就在这里:

代码语言:javascript
复制
LPC_TIM0->MR0 = 500; //Toggle Time in mS
//LPC_TIM0->MR0 = 1 << 23; // Give a value suitable for the LED blinking

匹配寄存器MR0没有预售值,因此它不是每500 mS执行一次,而是每500 uS执行一次。这类似于创建一个PWM信号,这将使LED闪烁得如此之快,以至于肉眼看不到。您可以尝试更多地了解如何使用LPC_TIM0->PR设置预销售值,以将计时器/计数器的值增加到大于1U。在没有使用预售的情况下,我每1秒就可以通过设置:

代码语言:javascript
复制
LPC_TIM0->MR0 = 100000000;

此外,确保你有一个电阻在你的LED电路,所以你不油炸它。确保您设置的输出引脚P1.29连接到板上的正确位置(PAD 12?):LPC Xpresso Pinout

希望这能有所帮助!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55003631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档