Skip to content
TeensyUser edited this page Mar 18, 2020 · 12 revisions

The digital pins are shown with gray numbers on the pinout cards. (Additional info about the pinouts can be found here). They can be accessed using digitalWriteFast and digititalReadFast. Of course, you can also use the slower digitalRead and digitalWrite functions but other than compatibility to Arduino code there is no advantage.

Internally, digital input or output is handled by the GPIO (general purpose input / output) module which is not identical but very similar between the various boards.

Setting pin modes

To setup the pins for one of the various input or output modes you can use the pinMode(pin, mode) function which takes the pin number (as given in the pinout card) as first and the mode as second parameter. The following modes are available:

Mode Description
OUTPUT Low impedance output mode. Pin can be set or cleared using digitalWriteFast
OUTPUT_OPENDRAIN Operate the pin in open drain mode. Please note this Teensy specific quirk of open-drain mode.
INPUT High impedance input mode. Pin can be read with digitalReadFast. This mode is set per default. Reading an open pin gives undefined values.
INPUT_PULLUP Adds a pull up resistor (~10k?) to the pin. Open pin reads HIGH
INPUT_PULLDOWN Adds a pull down resistor (~10k?) to the pin. Open pin reads LOW
INPUT_DISABLE Disables the pin

Here an example demonstrating how to read and write digital pins. It also shows the effect of PULLUP and PULLDOWN input modes. (Code for this section can be found here)

constexpr int inputPin = 0;

void setup()
{
    while (!Serial && millis() < 1000) {}

    pinMode(LED_BUILTIN, OUTPUT);

    pinMode(inputPin, INPUT_PULLUP);
    Serial.println("Using INPUT_PULLUP:");
    printDigitalVal(inputPin, digitalReadFast(inputPin));

    pinMode(inputPin, INPUT_PULLDOWN);
    Serial.println("\nUsing INPUT_PULLDOWN:");
    printDigitalVal(inputPin, digitalReadFast(inputPin));
}

void loop()
{
    digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN)); // toggle pin
    delay(150);
}

// Helpers ----------------------------------------------------------

void printDigitalVal(int pin, int val)
{
    Serial.printf("Pin %d value: %s\n", pin, val == 0 ? "LOW" : "HIGH");
}

Low Level access

WIP: Shortly explain Registers

The following sketch prints out the relationship between the pin number, the port and the bit number in the corresponding port. It uses the pins library to extract the required information. Data is stored in a standard c++ vector to store and sort the values.

The full code can be found here

#include <algorithm>
#include <vector>
#include "pins.h"
using namespace pins;

struct info_t
{
    unsigned pin;
    char port;
    unsigned bit;
};

void setup()
{
    while (!Serial && millis() < 1000) {}

    Serial.println("-----------------------------------------------------");
    Serial.println("Teensy LC");
    Serial.println("-----------------------------------------------------");
    display(T_LC);

    Serial.println("\n-----------------------------------------------------");
    Serial.println("Teensy 3.0, 3.1, 3.2");
    Serial.println("-----------------------------------------------------");
    display(T3_0_1_2);

    Serial.println("\n-----------------------------------------------------");
    Serial.println("Teensy 3.5, 3.6");
    Serial.println("-----------------------------------------------------");
    display(T3_5_6);

    return;
}

void loop()
{
    digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN)); // toggle pin
    delay(150);
}

// Helpers ----------------------------------------------------------

char PortName(portList port)
{
    if (port == portList::na) return 'X';
    return 'A' + port;
}

void display(boards board)
{
    constexpr unsigned pinCnt = sizeof(pinMap) / sizeof(pinMap[0]);
    std::vector<info_t> infosA, infosB;

    info_t info;
    for (unsigned i = 0; i < pinCnt; i++)
    {
        info.pin = i;
        info.port = PortName(pinMap[i][board].port);
        info.bit = pinMap[i][board].pin;
        if (info.port == 'X') break;

        infosA.push_back(info);
        infosB.push_back(info);
    }
    
    // sort infosA by pin number
    std::sort(infosA.begin(), infosA.end(), [](info_t a, info_t b){return a.pin < b.pin;});

    // sort infosB by port and bit 
    std::sort(infosB.begin(), infosB.end(), [](info_t a, info_t b) {
        if (a.port < b.port) return true;
        if (a.port > b.port) return false;
        if (a.bit < b.bit) return true;
        return false;
    });

    Serial.println("Sorted by pin number:     |   Sorted by Port and Bit");
    for (unsigned i = 0; i < infosA.size(); i++)
    {
        unsigned pinA = infosA[i].pin;
        unsigned bitA = infosA[i].bit;
        char portA = infosA[i].port;

        unsigned pinB = infosB[i].pin;
        unsigned bitB = infosB[i].bit;
        char portB = infosB[i].port;

        Serial.printf("Pin %2d  PORT_%c  Bit: %2d   |   PORT_%c  Bit %2d  Pin: %2d  \n", pinA, portA, bitA, portB, bitB, pinB);
    }
}

And here a part of the printout

-----------------------------------------------------
Teensy 3.0, 3.1, 3.2
-----------------------------------------------------
Sorted by pin number:     |   Sorted by Port and Bit
Pin  0  PORT_B  Bit: 16   |   PORT_A  Bit  4  Pin: 33  
Pin  1  PORT_B  Bit: 17   |   PORT_A  Bit  5  Pin: 24  
Pin  2  PORT_D  Bit:  0   |   PORT_A  Bit 12  Pin:  3  
Pin  3  PORT_A  Bit: 12   |   PORT_A  Bit 13  Pin:  4  
Pin  4  PORT_A  Bit: 13   |   PORT_B  Bit  0  Pin: 16  
Pin  5  PORT_D  Bit:  7   |   PORT_B  Bit  1  Pin: 17  
Pin  6  PORT_D  Bit:  4   |   PORT_B  Bit  2  Pin: 19  
Pin  7  PORT_D  Bit:  2   |   PORT_B  Bit  3  Pin: 18  
Pin  8  PORT_D  Bit:  3   |   PORT_B  Bit 16  Pin:  0  
Pin  9  PORT_C  Bit:  3   |   PORT_B  Bit 17  Pin:  1  
Pin 10  PORT_C  Bit:  4   |   PORT_B  Bit 18  Pin: 32  
Pin 11  PORT_C  Bit:  6   |   PORT_B  Bit 19  Pin: 25  
Pin 12  PORT_C  Bit:  7   |   PORT_C  Bit  0  Pin: 15  
Pin 13  PORT_C  Bit:  5   |   PORT_C  Bit  1  Pin: 22  
Pin 14  PORT_D  Bit:  1   |   PORT_C  Bit  2  Pin: 23  
...

Clone this wiki locally