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

Thread: Teensy 3+ Port Pin Register Help (New User)

  1. #1
    Junior Member
    Join Date
    Sep 2018
    Posts
    2

    Teensy 3+ Port Pin Register Help (New User)

    Hello everyone, :)

    I am currently a college student working on a flight controller for a project of mine. I have however run into an issue because I am a new user on the teensy.

    Currently, I am having trouble with finding the pin registers to see if a pin is high/low without using a "read" function. I have PWM signals coming in from a receiver for a RC Airplane, and I need to be able to check if a pin has gone high/low in order to determine the length of the PWM. This, of course is done in an interrupt as to not disable the other code running gyros/accels/filters/etc. Currently this is my code for just the question I am having problems with.

    Code:
    unsigned long pwm_timer[7];
    byte last_channel[7];
    int pilot_cmd[7];
    
    void setup() 
    {
    Serial.begin(115200);
    attachInterrupt(digitalPinToInterrupt(7), ISR, CHANGE);
    attachInterrupt(digitalPinToInterrupt(8), ISR, CHANGE);
    }
    
    void loop() 
    {
      Serial.print(pilot_cmd[0]);
      Serial.print(" - ");
      Serial.println(pilot_cmd[1]);
      delay(100);
    }
    
    void ISR()
    {
      pwm_timer[0] = micros();
    
    //Channel 1
      if(last_channel[0] == 0 && PINB & B00000001) //B00000001 Corresponds to Pin 8 on teensy 3.6
      {
        last_channel[0] = 1;
        pwm_timer[1] = pwm_timer[0];
      }
      else if(last_channel[0] == 1 && !(PINB & B00000001))
      {
        last_channel[0] = 0;
        pilot_cmd[0] = pwm_timer[0] - pwm_timer[1];
      }
    
    //Channel 2
      if(last_channel[1] == 0 && PINB & B00000010)
      {
        last_channel[1] = 1;
        pwm_timer[2] = pwm_timer[0];
      }
      else if(last_channel[1] == 1 && !(PINB & B00000010))
      {
        last_channel[1] = 0;
        pilot_cmd[1] = pwm_timer[0] - pwm_timer[2];
      }
    }
    SOOO, in the "void ISR" function, there are 2 "if" statements that contain "PINB & B00000001", and somehow, that is registered with pin 8 on the teensy 3.6 I have because I am getting values on the PWM signals from pin 8 when i connect it to the receiver (so my "pilot_cmd[0]" is displaying values)

    However, I cant seem to find any of the other "PINB & B00000001" for any of the other pins. So "PINB & B00000010" definitely doesnt work for pin 7 and so on...No matter what I try I cant seem to find the right register for the other pins. I am trying to hook this receiver up to pins 2,3,4,5,6,7,8 for 7 channel inputs but I need to know how to call the other pins. Also, I am very new to this level of coding, I've only used a little bit of arduino in the past. Also also, I have read this (and many other) posts linked below...

    https://forum.pjrc.com/threads/17532...ll=1#post21228

    ...but this says the address of pin 8 is D3, which is completely different then what seems to work in my code. Maybe its my lack of knowledge of binary and so on, but isnt "PINB" and "B00000001" referencing B1?

    Sorry for the confusion but I have been scratching my head over this for a good while now so any tips are much appreciated! Also, there are a lot of examples to do this on the arduino set-ups but not so much teensy, which is how I got to this point.

    Thanks!

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,769
    There are probably better solutions on Teensy to track the frequency.

    But to read a pin use :: digitalReadFast( CONST PIN# ) will map after compiling to a fast low level bit read if the pin # is a constant known at compile time - i.e. it looks like 7 or 8.

  3. #3
    Junior Member
    Join Date
    Sep 2018
    Posts
    2
    Thank you so much. That worked perfectly and thanks for the quick reply!

    If someone knows how to do them with the normal native pin register location that would be awesome too, but this solution works for the time being.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,769
    PJRC has optimized the code - digitalReadFast( CONST# ) devolves to minimal pin register location. You can see that in the core code installed with TeensyDuino - or by reading the PDF Manual appropriate for the MCU in your Teensy. In general there are Header files and #defines to 'name' all the ports to the pin level. Or to feel you did it yourself - the manual will show the needed port reference numbers that can be used.

    A quick code search shows this::
    Code:
    static inline uint8_t digitalReadFast(uint8_t pin)
    {
    // ...
    		} else if (pin == 7) {
    			return (CORE_PIN7_PINREG & CORE_PIN7_BITMASK) ? 1 : 0;
    		} else if (pin == 8) {
    			return (CORE_PIN8_PINREG & CORE_PIN8_BITMASK) ? 1 : 0;

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,153
    Quote Originally Posted by jamays3 View Post
    If someone knows how to do them with the normal native pin register location that would be awesome too, but this solution works for the time being.
    You'll get exactly the same compiled result, since digitalReadFast() is optimized by the compiler when the inputs are constants. But if you *really* want to hard-code registers into your program, here's a tutorial to get started.

    https://forum.pjrc.com/threads/17532...ll=1#post21228

Posting Permissions

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