Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

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

  1. #1
    Junior Member
    Join Date
    Aug 2019
    Posts
    11

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

    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:
    Click image for larger version. 

Name:	Untitled.png 
Views:	5 
Size:	27.9 KB 
ID:	18581

    Am I not disabling/resetting the interrupt properly?

  2. #2
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    329
    I can tell you that on an unconnected T4, the interrupt (correctly) never happens. What ADC chip are you using?

    I'd review this https://forum.pjrc.com/threads/57654...rrupt-problems and try the asm("dsb").

    Consider not using interrupts and just polling.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •