Arduino中引脚的数字与真实引脚的对应关系

本文详细解释了Arduino和STM32开发中如何处理数字引脚的IO控制,特别关注了数字13在不同开发板(如ESP8266、STM32)中的实际引脚对应,以及STM32中复杂系列和封装带来的引脚映射差异。
摘要由CSDN通过智能技术生成

我们使用arduino开发时,最长遇到的是对端口管脚的拉高拉低,代码如下


void setup() {
  pinMode(13,OUTPUT);
}

void loop() {
    digitalWrite(13,HIGH);
}

上面还最简单io控制代码,其中引脚我们使用了数字13,但是这个13对应着哪个引脚呢?我们一般会有开发板的示意图

上面的Dx就对应着引脚数字。这个还好理解。

但是当我们使用STM32开发板时候怎么对应呢?我们知道STM32不是简单的GPIO+数字的方式,而是还有ABCDE等,这样我们就不能简单的认为1对应GPIO1了。

下面我们根据源码分析一下这个数字是如何转为引脚地址的。

ESP8266

esp8266的简单

在3.1.2\cores\esp8266\core_esp8266_wiring_digital.cpp文件中有定义

volatile uint32_t* const esp8266_gpioToFn[16] PROGMEM = { &GPF0, &GPF1, &GPF2, &GPF3, &GPF4, &GPF5, &GPF6, &GPF7, &GPF8, &GPF9, &GPF10, &GPF11, &GPF12, &GPF13, &GPF14, &GPF15 };

这里的GPFx就是真正的引脚地址,非常规律的从0到15,就好像特意为arduino设计的一样。

STM32

stm32就是我说的无法一一对应的问题了,我们先来跟踪代码,在pinMode函数中有一个转换的函数

void pinMode(uint32_t ulPin, uint32_t ulMode)
{
  PinName p = digitalPinToPinName(ulPin);

这一行就是引脚转换的函数,继续跟踪到2.7.1\cores\arduino\pins_arduino.h文件

#define digitalPinToPinName(p)      ((((uint32_t)(p) & PNUM_MASK) < NUM_DIGITAL_PINS) ? \
            (PinName)(digitalPin[(uint32_t)(p) & PNUM_MASK] | ((p) & ALTX_MASK)) : NC)

这里实际上是将引脚的数字p当做了digitalPin数组的角标,那么我们就需要知道数组的内容就知道引脚数字和引脚地址的对应关系了。

这个数组有很多个,因为stm32有很多系列,每个系列的不同封装可能包含的引脚都不一样,所以对于每个系列的每个封装都要进行各自的定义。我们以F103R系列为例,看一下数组的定义

在文件2.7.1\variants\STM32F1xx\F103R(C-D-E)T\variant_generic.cpp

// Digital PinName array
const PinName digitalPin[] = {
  PA_0,   // D0/A0
  PA_1,   // D1/A1
  PA_2,   // D2/A2
  PA_3,   // D3/A3
  PA_4,   // D4/A4
  PA_5,   // D5/A5
  PA_6,   // D6/A6
  PA_7,   // D7/A7
  PA_8,   // D8
  PA_9,   // D9
  PA_10,  // D10
  PA_11,  // D11
  PA_12,  // D12
  PA_13,  // D13
  PA_14,  // D14
  PA_15,  // D15
  PB_0,   // D16/A8
  PB_1,   // D17/A9
  PB_2,   // D18
  PB_3,   // D19
  PB_4,   // D20
  PB_5,   // D21
  PB_6,   // D22
  PB_7,   // D23
  PB_8,   // D24
  PB_9,   // D25
  PB_10,  // D26
  PB_11,  // D27
  PB_12,  // D28
  PB_13,  // D29
  PB_14,  // D30
  PB_15,  // D31
  PC_0,   // D32/A10
  PC_1,   // D33/A11
  PC_2,   // D34/A12
  PC_3,   // D35/A13
  PC_4,   // D36/A14
  PC_5,   // D37/A15
  PC_6,   // D38
  PC_7,   // D39
  PC_8,   // D40
  PC_9,   // D41
  PC_10,  // D42
  PC_11,  // D43
  PC_12,  // D44
  PC_13,  // D45
  PC_14,  // D46
  PC_15,  // D47
  PD_0,   // D48
  PD_1,   // D49
  PD_2    // D50
};

如此可以看出每个引脚数字对应的引脚是什么了,例如我们使用digitalWrite(0,HIGH);实际上就是将GPIOA0引脚拉高了。

ESP32

在esp32中我们使用和ESP8266相似的方式

这里的GPIOx就对应这引脚数字。

我们同样在代码中找到相似的转换的地方,我们发现这个单片机设置引脚的方式已经被封装在了ESP-IDF(Espressif IoT Development Framework)中。引脚数字 pinNumber,然后将其转换为 gpio_num_t 类型的 GPIO 矩阵索引 gpioPin。最后,使用 gpio_config 函数来配置该引脚的模式。也就是说我们需要找到gpio_num_t 类型的定义,就可以找到引脚的对应关系。

在2.0.11\tools\sdk\esp32c3\include\hal\include\hal\gpio_types.h文件中

#if CONFIG_IDF_TARGET_ESP32
typedef enum {
    GPIO_NUM_NC = -1,    /*!< Use to signal not connected to S/W */
    GPIO_NUM_0 = 0,     /*!< GPIO0, input and output */
    GPIO_NUM_1 = 1,     /*!< GPIO1, input and output */
    GPIO_NUM_2 = 2,     /*!< GPIO2, input and output */
    GPIO_NUM_3 = 3,     /*!< GPIO3, input and output */
    GPIO_NUM_4 = 4,     /*!< GPIO4, input and output */
    GPIO_NUM_5 = 5,     /*!< GPIO5, input and output */
    GPIO_NUM_6 = 6,     /*!< GPIO6, input and output */
    GPIO_NUM_7 = 7,     /*!< GPIO7, input and output */
    GPIO_NUM_8 = 8,     /*!< GPIO8, input and output */
    GPIO_NUM_9 = 9,     /*!< GPIO9, input and output */
    GPIO_NUM_10 = 10,   /*!< GPIO10, input and output */
    GPIO_NUM_11 = 11,   /*!< GPIO11, input and output */
    GPIO_NUM_12 = 12,   /*!< GPIO12, input and output */
    GPIO_NUM_13 = 13,   /*!< GPIO13, input and output */
    GPIO_NUM_14 = 14,   /*!< GPIO14, input and output */
    GPIO_NUM_15 = 15,   /*!< GPIO15, input and output */
    GPIO_NUM_16 = 16,   /*!< GPIO16, input and output */
    GPIO_NUM_17 = 17,   /*!< GPIO17, input and output */
    GPIO_NUM_18 = 18,   /*!< GPIO18, input and output */
    GPIO_NUM_19 = 19,   /*!< GPIO19, input and output */
    GPIO_NUM_20 = 20,   /*!< GPIO20, input and output */
    GPIO_NUM_21 = 21,   /*!< GPIO21, input and output */
    GPIO_NUM_22 = 22,   /*!< GPIO22, input and output */
    GPIO_NUM_23 = 23,   /*!< GPIO23, input and output */
    GPIO_NUM_25 = 25,   /*!< GPIO25, input and output */
    GPIO_NUM_26 = 26,   /*!< GPIO26, input and output */
    GPIO_NUM_27 = 27,   /*!< GPIO27, input and output */
    GPIO_NUM_28 = 28,   /*!< GPIO28, input and output */
    GPIO_NUM_29 = 29,   /*!< GPIO29, input and output */
    GPIO_NUM_30 = 30,   /*!< GPIO30, input and output */
    GPIO_NUM_31 = 31,   /*!< GPIO31, input and output */
    GPIO_NUM_32 = 32,   /*!< GPIO32, input and output */
    GPIO_NUM_33 = 33,   /*!< GPIO33, input and output */
    GPIO_NUM_34 = 34,   /*!< GPIO34, input mode only */
    GPIO_NUM_35 = 35,   /*!< GPIO35, input mode only */
    GPIO_NUM_36 = 36,   /*!< GPIO36, input mode only */
    GPIO_NUM_37 = 37,   /*!< GPIO37, input mode only */
    GPIO_NUM_38 = 38,   /*!< GPIO38, input mode only */
    GPIO_NUM_39 = 39,   /*!< GPIO39, input mode only */
    GPIO_NUM_MAX,
/** @endcond */
} gpio_num_t;

如此一看,esp32更像是为了arduino的使用方式设计的了。

只有STM32需要去找到每个的对应关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值