我正在为一个arduino项目编写的一些C代码遇到一些问题 . 目标是使用外部多路复用ADC将大量模拟信号数字化,然后将这些数字值加载到外部移位寄存器中,并使用SPI将它们移入Arduino . 为了测试我的代码,我只有一个ADC复用4个信号 .

中断引脚(20)连接到比较器电路,当电压为1V或更高时,该比较器电路查看原始模拟信号并将引脚拉高 . 当ISR被调用时,它将禁用全局中断“noInterrupts()”设置事件标志,从中断处理程序中分离引脚20,启用全局中断“interruptts()”并最终返回到它停止的位置 .

我面临一些问题,首先ISR被调用一次,第二次很好,但是在第二次ISR调用之后它再也没有被调用,这是我的秒数问题,中断引脚变低 . 根据AttachInterupt()函数,只有在引脚20为高电平时才应调用ISR . 这可以在我附上的第一张和第二张图片中看到 . 我注意到的另一件事是中断引脚为高电平的持续时间对是否调用第三个ISR没有影响 .

我不确定这是否是我对Arduino的中断处理的理解,或者代码搞砸导致堆栈溢出或类似的问题 .

// the sensor communicates using SPI, so include the library:
#include <SPI.h>

//Constants
#define RD 41               //pin 41 conneced to read pin
#define INT1 37             //pin 37 connecte to interrupt 1
#define CLK_INH  53         //pin 53 connected to clk inhibit
#define LD  40              //pin 40 connected to load pin
#define INPUT_MAX 3         //input selector limit (Zero Indexed)
#define SENSORS 3           //how many sensors are used (Zero Indexed)
#define DATA_DUMP 38        //pin 29 controlls the data dump deature
#define BYTE_LEN  1         //number of ADC used
#define DEBUG1 17
#define DEBUG2 16

//Controls
unsigned char selector = 0;     //ACD input selector
volatile byte eventFlag = LOW;         //Control Flag, set to True when event occurs
bool lastButtonState = true;

//Counters
unsigned int i = 0;             //eventLog[i]: event counter
unsigned int j = 0;             //eventLog[i].data[j]: data counter

//Function Delcarations
unsigned char inputSelector (unsigned char my_selector);
void lockAndPop ();
void dataDump ();
void debug (int pin);
bool fallingEdge (bool);          //check for a falling edge of a digital read

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  // put your setup code here, to run once:
  pinMode(RD, OUTPUT);          //Read pin, 0 = begin analog conversion     (ADC)
  pinMode(INT1, INPUT);         //Interrupt pin, 0 = conversion complete    (ADC)
  pinMode(CLK_INH, OUTPUT);      //Clock inhibit pin, 1= no change on output (ShiftRegister)
  pinMode(LD, OUTPUT);          //Shift/Load pin, 1 = data is shifted       (ShiftRegister)
  pinMode(DATA_DUMP, INPUT);
  pinMode(DEBUG1, OUTPUT);
  pinMode(DEBUG2, OUTPUT);

  DDRA = 0xFF;        //Set port A to ouput

  SPI.begin();
  //SPI.mode1 Clock idel low CLOP = 0, Data sampled on falling edge CPHA = 1
  SPI.beginTransaction(SPISettings(5000000, MSBFIRST, SPI_MODE1));  

  digitalWrite(RD, HIGH);       //Stop conversion
  digitalWrite(CLK_INH, HIGH);   //No change on the output
  digitalWrite(LD, LOW);        //Load the shift register
  digitalWrite(DEBUG1, LOW);
  digitalWrite(DEBUG2, LOW);  

  attachInterrupt(digitalPinToInterrupt(20), pin_ISR, HIGH);    //Call pin_ISR when pin20 goes high

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

typedef struct                //event structure, containts a timestamp element and an array of 18 data points
{
  unsigned long int timeStamp;
  unsigned char data[SENSORS];
} Event;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Event eventLog[200];        //an array of structures representing 200 events, once the 200 events have been filled the data will be printed

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {
  if(fallingEdge(digitalRead(DATA_DUMP))){      //If there is falling edge on the data dump button, call the dataDump function
    dataDump();
  }
  debug(DEBUG2);
  if(eventFlag)                                 //if the Event flag is set to true by ISR begin the conversion steps
  {
    debug(DEBUG1);
    digitalWrite(RD,LOW);         //Start conversion
    while(digitalRead(INT1)){}    //Wait for conversion to complete

    eventLog[i].timeStamp = micros();

    for (j=0; j<=SENSORS; j++) {
      lockAndPop();                         //lock digital value and reset conversion
      PORTA = inputSelector(selector);      //increment the selector pin
      digitalWrite(RD, LOW);                //Start new conversion

      digitalWrite(CLK_INH, LOW);                //Start the data transfer
      eventLog[i].data[j] = SPI.transfer(0);     //read a single byte from the SPI line
      digitalWrite(CLK_INH, HIGH);              //Inhibit clock
      digitalWrite(LD, LOW);
      while(digitalRead(INT1)){}                //wait for previous conversion to end            
      } 
    i++;
    digitalWrite(RD, HIGH);
    selector = 0;  
    if(i>=200){
      dataDump();                           //if the event log hits 200 before a data dump is request, dump the data
    }
    eventFlag = LOW;
    attachInterrupt(digitalPinToInterrupt(20), pin_ISR, HIGH);

  }

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void pin_ISR() {
  noInterrupts();
  detachInterrupt(digitalPinToInterrupt(20));
  eventFlag = HIGH;
  interrupts();
  return;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

unsigned char inputSelector (unsigned char my_selector){
  if(my_selector==INPUT_MAX){           //if the current selector is at the highest value reset to 0
    return 0;
  }
  return my_selector++;                  //increment the input selector by 1
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void lockAndPop (){
   digitalWrite(LD, HIGH);        //Lock in digital value
   digitalWrite(RD, HIGH);        //Reset conversion
   return;
}

void dataDump (){
  detachInterrupt(digitalPinToInterrupt(20));
  char buf[100], *pos = buf;    //create a buffer of 100 charaters, anda pointer to the begining of that buffer
  char *base = buf;             //create a base address to reset the buffer
  unsigned int eventCount = i;               //how many events occured before dump command was called
  unsigned int localCount;      
  unsigned int localData;
  Serial.begin(115200);
  Serial.println(i);
  for (localCount = 0; localCount<=eventCount; localCount++){
    pos += sprintf(pos, "%lu", eventLog[localCount].timeStamp);          //sprintf will append the data to the pointer "pos", and return the number of byte append.
    for (localData = 0; localData<=SENSORS; localData++){
       pos += sprintf(pos, " %d", (unsigned int)(eventLog[localCount].data[localData]));   
    }
    Serial.println(buf);
    pos = base;
  }
  i=0;
  j=0;
  Serial.end();
  attachInterrupt(digitalPinToInterrupt(20), pin_ISR, HIGH);
  return;
}

void debug(int pin){
  digitalWrite(pin, HIGH);
  digitalWrite(pin, LOW);
  return;
}

bool fallingEdge (bool currentButtonState){
  if(!currentButtonState&&lastButtonState){
    lastButtonState = currentButtonState;
    return 1;
  }
  lastButtonState = currentButtonState;
  return 0;
}

High to Low

Two events

ISR引脚上发生了一些噪声,但这并不重要,因为我在服务程序中禁用了该特定引脚,所以我不认为这是一个问题

Noisy ISR pin