Teensy 4.0 - falling edge interrupt keeps triggering when there is no falling edge

Status
Not open for further replies.

rt54321

Member
I am using the Teensy 4.0 - pin 5 as the "busy" edge detector for an external ADC. After a conversion start, the external ADC applies a "BUSY" pulse, and on the falling edge of this busy pulse, that means that the ADC data is ready to be read.

My problem is that the interrupt seems to be triggering erroneously. Right now, I have the pin 5 pin tied to ground, but my inerrupt counter is still counting up (it should only count when an interrupt has happened).

My code is here:
Code:
#define ADC_CONV_FREQ 10000  //ADC conversion frequency in Hz

/** ADC Pin defines are here:**/
#define CONV_START 4
#define ADC_IS_BUSY 5 
#define ADC_CS     6 
#define ADC_READ   9
///////////////////////
#define ADC_BIT0 2
#define ADC_BIT1 3
#define ADC_BIT2 14
#define ADC_BIT3 15
#define ADC_BIT4 16
#define ADC_BIT5 17
#define ADC_BIT6 18
#define ADC_BIT7 19
#define ADC_BIT8 20
#define ADC_BIT9 21
#define ADC_BIT10 22
#define ADC_BIT11 23
#define ADC_BIT12 24
#define ADC_BIT13 25
#define ADC_BIT14 26
#define ADC_BIT15 27

/*********************************/
//Global variables:
volatile int ADC_result_bits;
volatile int interrupt_counter;

volatile float ADC_Channel_A0;
volatile float ADC_Channel_A1;
volatile float ADC_Channel_B0;
volatile float ADC_Channel_B1;
volatile float ADC_Channel_C0;
volatile float ADC_Channel_C1;

/*********************************/
//Function prototypes:
void ADC_ready_intrpt(void);
float ADC_read(void);

void setup()
{  
  Serial.begin(9600);
  pinMode(CONV_START,OUTPUT);
  analogWriteFrequency(CONV_START, ADC_CONV_FREQ);  //Set ADC Conversion frequency
  
  pinMode(ADC_IS_BUSY, INPUT);  

  pinMode(ADC_CS, OUTPUT);
  pinMode(ADC_READ, OUTPUT);
  digitalWrite(ADC_CS, HIGH);
  digitalWrite(ADC_READ, HIGH);
  
  attachInterrupt(digitalPinToInterrupt(ADC_IS_BUSY), ADC_ready_intrpt, FALLING);
  
  /***********************************/
  pinMode(ADC_BIT0, INPUT);
  pinMode(ADC_BIT1, INPUT);
  pinMode(ADC_BIT2, INPUT);
  pinMode(ADC_BIT3, INPUT);
  pinMode(ADC_BIT4, INPUT);
  pinMode(ADC_BIT5, INPUT);
  pinMode(ADC_BIT6, INPUT);
  pinMode(ADC_BIT7, INPUT);
  pinMode(ADC_BIT8, INPUT);
  pinMode(ADC_BIT9, INPUT);
  pinMode(ADC_BIT10, INPUT);
  pinMode(ADC_BIT11, INPUT);
  pinMode(ADC_BIT12, INPUT);
  pinMode(ADC_BIT13, INPUT);
  pinMode(ADC_BIT14, INPUT);
  pinMode(ADC_BIT15, INPUT);
  /***********************************/
  analogWrite(CONV_START, 100);
  delay(1000);  
}

void loop()
{    
  for(volatile long i = 0; i < 100000000; i++)
  {//"do nothing" for loop        
  }
  Serial.print("Intrpt counter: ");
  Serial.println(interrupt_counter);
  Serial.print("C0: ");
  Serial.println(ADC_Channel_A0);
  Serial.print("C1: ");
  Serial.println(ADC_Channel_A1);
}



float ADC_read(void)
{
  ADC_result_bits = digitalReadFast(ADC_BIT0) | 
                    (digitalReadFast(ADC_BIT1) << 1) |
                    (digitalReadFast(ADC_BIT2) << 2) |                                   
                    (digitalReadFast(ADC_BIT3) << 3) |                                   
                    (digitalReadFast(ADC_BIT4) << 4) |
                    (digitalReadFast(ADC_BIT5) << 5) |                                   
                    (digitalReadFast(ADC_BIT6) << 6) |                                   
                    (digitalReadFast(ADC_BIT7) << 7) |
                    (digitalReadFast(ADC_BIT8) << 8) |                                   
                    (digitalReadFast(ADC_BIT9) << 9) |                                   
                    (digitalReadFast(ADC_BIT10) << 10) |
                    (digitalReadFast(ADC_BIT11) << 11) |                                   
                    (digitalReadFast(ADC_BIT12) << 12) |                                   
                    (digitalReadFast(ADC_BIT13) << 13) |
                    (digitalReadFast(ADC_BIT14) << 14) |                                   
                    (digitalReadFast(ADC_BIT15) << 15);                                    

  return (float)ADC_result_bits;
}

void ADC_ready_intrpt(void)
{
    noInterrupts(); //Disable interrupts    
    interrupt_counter++;
    
    digitalWrite(ADC_CS, LOW); //Keep chip select LOW for the entire data read process (all channels)
    
    digitalWrite(ADC_READ, LOW);
    digitalWrite(ADC_READ, HIGH);
    ADC_Channel_A0 = ADC_read();
        
    digitalWrite(ADC_READ, LOW);
    digitalWrite(ADC_READ, HIGH);
    ADC_Channel_A1 = ADC_read();

    digitalWrite(ADC_READ, LOW);
    digitalWrite(ADC_READ, HIGH);
    ADC_Channel_B0 = ADC_read();

    digitalWrite(ADC_READ, LOW);
    digitalWrite(ADC_READ, HIGH);
    ADC_Channel_B1 = ADC_read();

    digitalWrite(ADC_READ, LOW);
    digitalWrite(ADC_READ, HIGH);
    ADC_Channel_C0 = ADC_read();

    digitalWrite(ADC_READ, LOW);
    digitalWrite(ADC_READ, HIGH);
    ADC_Channel_C1 = ADC_read();
    
    
    digitalWrite(ADC_CS, HIGH);  //Now drive chip select high again
    interrupts(); //Enable interrupts
}

Here is a screenshot of the serial terminal, showing that the interrupt_counter variable keeps counting up, even when pin 5 is tied to ground:
Untitled.png

Am I not disabling/resetting the interrupt properly?
 
Status
Not open for further replies.
Back
Top