Berechnen Sie die Betriebszeit von LPC1768

Ich möchte die Betriebszeit von LPC 1768 ab dem Beginn der Ausführung berechnen. zum Beispiel eine Funktion wie millis(); im Arduino.

Antworten (2)

Ich schlage vor, dass Sie einen Hardware-Timer einrichten, der jede Millisekunde einen Zähler erhöht. Indem Sie diesen Wert ablesen, kennen Sie Ihre Betriebszeit.

"Sie werden Ihre Betriebszeit kennen" ... natürlich modulo der Größe des Zählers. Ein Millisekundenzähler zum Beispiel läuft schon nach ein paar Monaten über, wenn er nur 32 Bit unsigned ist...
Natürlich. Aber Sie können den Zählerüberlauf in einem Interrupt behandeln und eine Variable mit "hohen Bits" erhöhen. Ein Überlauf dieser Variablen würde Jahrtausende erfordern, wenn es sich um u_int32 handelt ...

Ich verwende den folgenden Code, der das RIT-Peripheriegerät (Repetitive Interrupt Timer) verwendet. Dies ist ein sehr einfaches Timer-Peripheriegerät. Auf diese Weise können Sie die voll ausgestatteten Timer und den Tick-Timer des ARM-Systems für andere Zwecke verwenden:

volatile uint32_t rit_high = 0;

static void rit_irq_handler()
/////////////////////////////
{
  // Clear interrupt pending flag:
  LPC_RIT->RICTRL = (1<<0) |  // clear interrupt flag
                    (1<<1) |  // clear counter on overflow
                    (1<<3);   // timer enable

  // increase high counter:
  rit_high++;

  // memory barrier. Makes sure that the interrupt pending flag
  // gets written before we exit the ISR
  __DMB();  
}



void stopwatch_start (void)
///////////////////////////
{
  NVIC_DisableIRQ(RIT_IRQn);

  rit_high = 0;

  // configure and set handler to highestpriority:
  NVIC_SetVector(RIT_IRQn, (uint32_t)rit_irq_handler);
  NVIC_SetPriority(RIT_IRQn, 0);

  // power on the Repeative Interrupt Timer:
  LPC_SC->PCONP     |= (1<<16);

  // init timer with defaults:
  LPC_RIT->RICOUNTER = 0;
  LPC_RIT->RICOMPVAL = ~0;
  LPC_RIT->RIMASK    = 0;

  LPC_RIT->RICTRL    = (1<<0) |  // clear interrupt flag
                       (1<<1) |  // clear counter on overflow
                       (1<<3);   // timer enable

  NVIC_EnableIRQ(RIT_IRQn);
}


void stopwatch_stop (void)
//////////////////////////
{
  NVIC_DisableIRQ(RIT_IRQn);

  LPC_RIT->RICTRL = (1<<0) |  // clear interrupt flag
                    (1<<1) |  // clear counter on overflow
                    (0<<3);   // timer disable
}

static uint64_t stopwatch_getval (void)
//////////////////////////////////////
{
  return (uint64_t(rit_high)<<32) | LPC_RIT->RICOUNTER;
}


uint64_t stopwatch_getclk (void)
////////////////////////////////
{
  uint64_t a,b;
  a = stopwatch_getval();
  while (1)
  {
    b = stopwatch_getval();
    if (b>=a) return b;
    a = b;
  }
}


uint32_t stopwatch_getms (void)
///////////////////////////////
{
  return stopwatch_getclk() / (CORE_FREQ/1000);
}


uint64_t stopwatch_getus (void)
///////////////////////////////
{
  return stopwatch_getclk() / (CORE_FREQ/1000000);
}

Stellen Sie CORE_FREQdie Geschwindigkeit des RIT-Peripheriegeräts ein, standardmäßig ist dies Ihre CPU-Frequenz geteilt durch 4. Wenn Sie möchten, dass der Timer mit voller CPU-Geschwindigkeit läuft, können Sie dies tun, indem Sie das Register wie folgt neu programmieren PCLKSEL1:

  // RIT: Set perpheral clock divider to 1:
  LPC_SC->PCLKSEL1 = (LPC_SC->PCLKSEL1 & ~(3<<26)) | (1<<26);

Sie möchten dies tun, bevor Sie PLL0 aktivieren (der Grund dafür ist im LPC1768-Errata-Dokument), daher sollte dieser Code in Ihren Systemstart eingefügt werden. Das ist wahrscheinlich die Datei system_LPC17xx.c.