Playing with Arduino
A page to record my playing with Arduino
digitalPinToBitMask()

Abstract

The digitalPinToBitMask() is a macro that returns the bitmask of a specified pin.

Source Code

The digitalPinToBitMask() is defined in hardware/arduino/avr/cores/arduino/Arduino.h as below.

1
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )

The input is P. The macro calls pgm_read_byte() with an argument digital_pin_to_bit_mask_PGM + (P).

The digital_pin_to_bit_mask_PGM is defined in hardware/arduino/variants/standard/pins_arduino.h(in case of Arduino Uno). It is an array shown below. As this array is declared as PROGMEM, it is placed on flash memory rather than SRAM.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
        _BV(0), /* 0, port D */
        _BV(1),
        _BV(2),
        _BV(3),
        _BV(4),
        _BV(5),
        _BV(6),
        _BV(7),
        _BV(0), /* 8, port B */
        _BV(1),
        _BV(2),
        _BV(3),
        _BV(4),
        _BV(5),
        _BV(0), /* 14, port C */
        _BV(1),
        _BV(2),
        _BV(3),
        _BV(4),
        _BV(5),
};

As the digital_pin_to_bit_mask_PGM is an array, adding (P) to the digital_pin_to_bit_mask_PGM means the (P+1)th element of the array. In C++ language, the element of array x[i] can be accessed by *(x + i). For example, if the P is 13, the forteenth element(note that the elements begins with 0) of the array, that is _BV(5), is returned.

The _BV() is a macro defined in hardware/tools/avr/avr/include/avr/sfr_defs.h. It returns the value that shifts 1 to left by the argument. _BV(5) is 0b00100000.

The pgm_read_byte() is a macro to read a valiable maked as PROGMEM and is defined in hardware/tools/avr/avr/include/avr/pgmspace.h.

As a result digitalPinToBitMask() returns the (P+1)th element of digital_pin_to_bit_mask_PGM which is placed on the flash memory.

The relation of pin, port and bit is shown below. For example, D0(digital pin number 0) is mapped to the 0th bit of the PORTD. Reading digitalPinToPort() would help to understand.

PORTB(PB) PORTC(PC) PORTD(PD)
D0 0
D1 1
D2 2
D3 3
D4 4
D5 5
D6 6
D7 7
D8 0
D9 1
D10 2
D11 3
D12 4
D13 5
A0 0
A1 1
A2 2
A3 3
A4 4
A5 5

Versionn

Arduino 1.8.13

Last Update

June 19, 2020

inserted by FC2 system