首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ATMega AVR外部中断

ATMega AVR外部中断
EN

Stack Overflow用户
提问于 2017-11-11 07:50:07
回答 1查看 181关注 0票数 0

我有一个Arduino Mega应用程序,在不同的占空比周期中,我读取低频脉冲(约10赫兹)的定时。

我使用外部中断来捕获脉冲,将信号转换时间信息添加到一个16位array320中,在完成后读取该信息。

我将第一次向上变化的时间设置为时间0,从而使时间正常化。参见所附的简化代码段(使用Arduino Mega的工作测试,pin D2)。

问题:复位后的第一个完整周期按预期读取定时,而每个后续周期只有第一个脉冲正常,而所有下一个脉冲的定时都是随机移位的。

我已经测试和尝试了许多选项,包括易失性和只中断更改,但总是得到相同的结果:第一次运行是好的,下一次运行被转移。

任何想法都会受到高度赞赏。

代码语言:javascript
复制
    /*Program reads input pulses at D2 and builds timing array of the up and 
    down going signals, using change interrupts on pin D2 of Mega
    To run, send array size in hex.
    by Sam Tal sam@tadin.co.il  Nov 9, 2017
    */
    #define interruptPin 2
    unsigned int dataArraySize;
    unsigned int timeData[320];
    volatile byte state = LOW;
    unsigned int counts = 0 ;      //Changes counter
    unsigned long startTime;       //The first up going interrupt time.
    //==========================================================
    void setup()
    {
      Serial.begin(115200);
      pinMode(interruptPin, INPUT);
    }
    //=========================================================
    void loop()
    {
      if (Serial.available())
      {
        dataArraySize = Serial.read();
        StartCycle();
      }
    }
    //========================================================
    void StartCycle(void)
    {
      Serial.println("Starting cycle...");
      //Reset the time array;
      memset ( timeData, 0, dataArraySize);
      counts = 0 ;
      state = LOW;
      attachInterrupt(digitalPinToInterrupt(interruptPin), Step, RISING);
    }

    //========================================================
    void Step()
    {
      detachInterrupt (digitalPinToInterrupt (interruptPin));
      if (counts == 0)
      {
        startTime = millis();    // Start time of the first rising change.
      }
      if (counts < dataArraySize)
      {
        timeData[counts] = millis() - startTime ;
        counts++;
        attachInterrupt(digitalPinToInterrupt(interruptPin), Step, CHANGE);
      }
      else
      {
        detachInterrupt (digitalPinToInterrupt (interruptPin));
        SendData(timeData, dataArraySize);
      }
    }
     //===========================================================
   void SendData(unsigned int data[] , unsigned int arraysize)
    {
      int f;
      for (f = 0; f < arraysize  ; f++)
      {
        Serial.print(f);
        Serial.print(",") ;
        Serial.println(data[f]);
      }
    }
EN

回答 1

Stack Overflow用户

发布于 2017-11-11 14:55:15

memset()调用处理字节,但您给了它两个字节整数的计数。所以,它没有清除整个缓冲区。通常我们会做这样的事情:

代码语言:javascript
复制
   memset(buf, 0, sizeof(buf));

我还害怕中断处理程序中的Serial.print()。可能会在那里设置一个标志,然后调用Send() from循环()。

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

https://stackoverflow.com/questions/47235684

复制
相关文章

相似问题

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