-
Notifications
You must be signed in to change notification settings - Fork 5
GPIO
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.
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");
}
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
...
Teensy is a PJRC trademark. Notes here are for reference and will typically refer to the ARM variants unless noted.