相当于Arduino millis()

时间:2017-07-25 14:26:25

标签: c arm

我目前正致力于整合" shunt"电子板上的传感器类型。我的选择是在线性(LTC2947),不幸的是它只有一个Arduino驱动程序。我必须在Linux下翻译C中的所有内容以与我的微处理器(APQ8009 ARM Cortex-A7)兼容。我对其中一个功能提出了一个小问题:

int16_t LTC2947_wake_up() //Wake up LTC2947 from shutdown mode and measure the wakeup time
{
   byte data[1];
   unsigned long wakeupStart = millis(), wakeupTime;
   LTC2947_WR_BYTE(LTC2947_REG_OPCTL, 0);
   do
   {
      delay(1);
      LTC2947_RD_BYTE(LTC2947_REG_OPCTL, data); 
      wakeupTime = millis() - wakeupStart;
      if (data[0] == 0) //! check if we are in idle mode
      {
         return wakeupTime;
      }
     if (wakeupTime > 200)
     {
  //! failed to wake up due to timeout, return -1
        return -1;
     }
   }
   while (true);
}

在找到usleep()作为delay()的等价物之后,我找不到它在C中的millis()。你能帮我翻译一下这个函数吗?

1 个答案:

答案 0 :(得分:1)

Arduino millis()基于一个定时器,它在非常接近1 KHz或1毫秒的时间内触发溢出中断。为了达到同样的目的,我建议你在ARM平台上设置一个计时器,并用计数器更新volatile unsigned long变量。这将相当于millis()。

以下是millis()在幕后所做的事情:

SIGNAL(TIMER0_OVF_vect)
{
    // copy these to local variables so they can be stored in registers
    // (volatile variables must be read from memory on every access)
    unsigned long m = timer0_millis;
    unsigned char f = timer0_fract;

    m += MILLIS_INC;
    f += FRACT_INC;
    if (f >= FRACT_MAX) {
        f -= FRACT_MAX;
        m += 1;
    }

    timer0_fract = f;
    timer0_millis = m;
    timer0_overflow_count++;
}

unsigned long millis()
{
    unsigned long m;
    uint8_t oldSREG = SREG;

    // disable interrupts while we read timer0_millis or we might get an
    // inconsistent value (e.g. in the middle of a write to timer0_millis)
    cli();
    m = timer0_millis;
    SREG = oldSREG;

    return m;
}

来自嵌入式世界,可以说在新平台上启动项目时应该做的第一件事就是建立时钟并以规定的速率获得定时器中断。这就是" Hello World"嵌入式系统;)如果您选择以1 KHz的速度执行此操作,则大部分时间都在那里。