[STM32學習記錄-5] 優化STM32 GPIO設定函式

系列:STM32學習記錄 Posted on 2020-04-02

注意,本文的內容過於老舊,不建議實際使用,僅保留以作爲參考用。

前言

在先前的[STM32學習記錄-3] 基本輸入與輸出教學-GPIO相關程式寫法中已經介紹過STM32設定GPIO的相關函式,但如果是常用Arduion的人一定不太習慣這種設定方式,畢竟每設定一個GPIO就要打4行程式,雖然可以複製貼上,但程式一多難免看起來混亂複雜,所以我自己寫了一些GPIO相關的函式,方便自己未來使用。

GPIO模式設定函式

程式如下:

  1/* Includes ------------------------------------------------------------------*/
  2#include "GPIO_mapping.h"
  3
  4/* Private typedef -----------------------------------------------------------*/
  5/* Private define ------------------------------------------------------------*/
  6// Pin Mode and Speed
  7#define OUT   (0)  // Output
  8#define IN    (1)  // Input
  9
 10#define GPPP  (0)  // General purpose Push-Pull (Output)
 11#define GPOD  (1)  // General purpose Open-Drain (Output)
 12#define AFPP  (2)  // Alternate function Push-Pull (Output)
 13#define AFOD  (3)  // Alternate function Open-Drain (Output)
 14
 15#define FL    (0)  // Floating (Input)
 16#define AN    (1)  // Analog (Input)
 17#define PD    (2)  // Pull-Down (Input)
 18#define PU    (3)  // Pull-Up (Input)
 19
 20#define S2M    (2)  // 2MHz
 21#define S10M  (10)  // 10MHz
 22#define S50M  (50)  // 50MHz
 23
 24/* Private macro -------------------------------------------------------------*/
 25/* Private variables ---------------------------------------------------------*/
 26/* Private function prototypes -----------------------------------------------*/
 27/* Private functions ---------------------------------------------------------*/
 28
 29/**
 30  * @brief  Config a pin mode and speed.
 31  * @param  PortPin: select a pin to set.
 32  *         This parameter should be: 0 ~ 79
 33  *         0~15:PA0~PA15; 16~31:PB0~PB15; 32~47:PC0~PC15;
 34  *         48~63:PD0~PD15; 64~79:PE0~PE15
 35  * @param  INout: Input or Output.
 36  *         This parameter should be: 0(Output) or 1(Input).
 37  * @param  Mode: Pin mode.
 38  *         This parameter should be: 0~3.
 39  *         0: GPPP or FL.
 40  *         1: GPOD or AN.
 41  *         2: AFPP or PD.
 42  *         3: AFOD or PU.
 43  * @param  Speed: Pin speed.
 44  *         This parameter should be: 2, 10 or 50.
 45  *          2:  2MHz.
 46  *         10: 10MHz.
 47  *         50: 50MHz.
 48  * @retval None
 49  */
 50void Pin_Mod(u8 PortPin, u8 INout, u8 Mode, u8 Speed)
 51{
 52  /* Structure Declarations */
 53  GPIO_InitTypeDef GPIO_InitStructure;
 54
 55  // GPIO_Speed
 56  switch(Speed)
 57  {
 58    case S2M:  // S2M:2
 59      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
 60      break;
 61    case S10M:  // S10M:10
 62      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
 63      break;
 64    case S50M:  // S50M:50
 65      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 66      break;
 67    default:
 68      break;
 69  }
 70
 71  // GPIO_Mode
 72  if(INout == OUT)  // OUT:0
 73  {
 74    switch(Mode)
 75    {
 76      case GPPP:  // GPPP:0
 77        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 78        break;
 79      case GPOD:  // GPOD:1
 80        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
 81        break;
 82      case AFPP:  // AFPP:2
 83        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 84        break;
 85      case AFOD:  // AFOD:3
 86        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
 87        break;
 88      default:
 89        break;
 90    }
 91  }
 92  else if(INout == IN)   // IN:1
 93  {
 94    switch(Mode)
 95    {
 96      case FL:  // FL:0
 97        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 98        break;
 99      case AN:  // AN:1
100        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
101        break;
102      case PD:  // PD:2
103        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
104        break;
105      case PU:  // PU:3
106        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
107        break;
108      default:
109        break;
110    }
111  }
112
113  // GPIO_Pin & GPIO_Init() function.
114  if(PortPin <= 15)    // Port-A:  0~15
115  {
116    GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << PortPin));
117    GPIO_Init(GPIOA, &GPIO_InitStructure);
118  }
119  else if(PortPin <= 31)  // Port-B: 16~31
120  {
121    GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << (PortPin - 16)));
122    GPIO_Init(GPIOB, &GPIO_InitStructure);
123  }
124  else if(PortPin <= 47)  // Port-C: 32~47
125  {
126    GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << (PortPin - 32)));
127    GPIO_Init(GPIOC, &GPIO_InitStructure);
128  }
129  else if(PortPin <= 63)  // Port-D: 48~63
130  {
131    GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << (PortPin - 48)));
132    GPIO_Init(GPIOD, &GPIO_InitStructure);
133  }
134  else if(PortPin <= 79)  // Port-E: 64~79
135  {
136    GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << (PortPin - 64)));
137    GPIO_Init(GPIOE, &GPIO_InitStructure);
138  }
139  else /* Null */;    // Out of range(0~79)
140}
141
142#undef OUT
143#undef IN
144
145#undef GPPP
146#undef GPOD
147#undef AFPP
148#undef AFOD
149
150#undef FL
151#undef AN
152#undef PD
153#undef PU
154
155#undef S2M
156#undef S10M
157#undef S50M

可以看到裡面就是增加了“void Pin_Mod(u8 PortPin, u8 INout, u8 Mode, u8 Speed)”此一函式。其用法如下:

 1/* STM32 Nucleo-64 board */
 2Pin_Mod(PA5, OUT, GPPP, S2M);  // PA5: LED-user
 3//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
 4//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 5//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
 6//GPIO_Init(GPIOA, &GPIO_InitStructure);
 7
 8Pin_Mod(PC13, IN, FL, S2M);  // PC13: Button-user
 9//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
10//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
11//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
12//GPIO_Init(GPIOC, &GPIO_InitStructure);
13
14/* USART */
15Pin_Mod(PA2, OUT, AFPP, S50M);  // PA2: USART2_TX
16//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
17//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
18//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
19//GPIO_Init(GPIOA, &GPIO_InitStructure);
20
21Pin_Mod(PA3, IN, FL, S50M);  // PA3: USART2_RX
22//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
23//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
24//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
25//GPIO_Init(GPIOA, &GPIO_InitStructure);

這樣的話就可以更簡單方便地設定GPIO了。

至於其引入的“GPIO_mapping.h”內容如下:(只適用於STM32F103RB,請依照自己的MCU腳位更改)

  1/**
  2 ******************************************************************************
  3 * @file      GPIO_mapping.h
  4 * @author    ZiTe
  5 * @version   V1.0.0
  6 * @date      08-October-2019
  7 * @brief     Header for GPIO_Function.c module for STM32F103RB
  8 ******************************************************************************
  9 * @attention
 10 *
 11 * This file is used ONLY for STM32F103RB(STM32 Nucleo-64 board).
 12 *
 13 ******************************************************************************
 14 */
 15
 16/* Define to prevent recursive inclusion -------------------------------------*/
 17#ifndef __GPIO_MAPPING_H
 18#define __GPIO_MAPPING_H
 19
 20/* Includes ------------------------------------------------------------------*/
 21/* Exported types ------------------------------------------------------------*/
 22/* Exported constants --------------------------------------------------------*/
 23
 24/* STM32 Pin(Morpho) */
 25/*
 26 * Default=Alternate functions Default
 27 * MA=Main function(after reset)
 28 * Remap=Alternate functions Remap
 29 */
 30
 31// Port-A
 32#define PA0    (0)  // WKUP/USART2_CTS/ADC12_IN0/TIM2_CH1_ETR
 33#define PA1    (1)  // USART2_RTS/ADC12_IN1/TIM2_CH2
 34#define PA2    (2)  // USART2_TX/ADC12_IN2/TIM2_CH3
 35#define PA3    (3)  // USART2_RX/ADC12_IN3/TIM2_CH4
 36#define PA4    (4)  // SPI1_NSS/USART2_CK/ADC12_IN4
 37#define PA5    (5)  // SPI1_SCK/ADC12_IN5
 38#define PA6    (6)  // SPI1_MISO/ADC12_IN6/TIM3_CH1;Remap:TIM1_BKIN
 39#define PA7    (7)  // SPI1_MOSI/ADC12_IN7/TIM3_CH2;Remap:TIM1_CH1N
 40#define PA8    (8)  // USART1_CK/TIM1_CH1/MCO
 41#define PA9    (9)  // USART1_TX/TIM1_CH2
 42#define PA10  (10)  // USART1_RX/TIM1_CH3
 43#define PA11  (11)  // USART1_CTS/CANRX/USBDM/TIM1_CH4
 44#define PA12  (12)  // USART1_RTS/CANTX/USBDP/TIM1_ETR
 45#define PA13  (13)  // MA:JTMS/SWDIO;Remap:PA13
 46#define PA14  (14)  // MA:JTCK/SWCLK;Remap:PA14
 47#define PA15  (15)  // MA:JTDI;Remap:TIM2_CH1_ETR/ PA15/SPI1_NSS
 48
 49// Port-B
 50#define PB0   (16)  // ADC12_IN8/TIM3_CH3;Remap:TIM1_CH2N
 51#define PB1   (17)  // ADC12_IN9/TIM3_CH4;Remap:TIM1_CH3N
 52#define PB2   (18)  // MA:PB2/BOOT1
 53#define PB3   (19)  // MA:JTDO;Remap:TIM2_CH2/PB3/TRACESWO/SPI1_SCK
 54#define PB4   (20)  // MA:JNTRST;Remap:TIM3_CH1/PB4/SPI1_MISO
 55#define PB5   (21)  // I2C1_SMBAl;Remap:TIM3_CH2/SPI1_MOSI
 56#define PB6   (22)  // I2C1_SCL/TIM4_CH1;Remap:USART1_TX
 57#define PB7   (23)  // I2C1_SDA/TIM4_CH2;Remap:USART1_RX
 58#define PB8   (24)  // TIM4_CH3;Remap:I2C1_SCL/CANRX
 59#define PB9   (25)  // TIM4_CH4;Remap:I2C1_SDA/CANTX
 60#define PB10  (26)  // I2C2_SCL/USART3_TX;Remap:TIM2_CH3
 61#define PB11  (27)  // I2C2_SDA/USART3_RX;Remap:TIM2_CH4
 62#define PB12  (28)  // SPI2_NSS/I2C2_SMBAl/USART3_CK/TIM1_BKIN
 63#define PB13  (29)  // SPI2_SCK/USART3_CTS/TIM1_CH1N
 64#define PB14  (30)  // SPI2_MISO/USART3_RTS/TIM1_CH2N
 65#define PB15  (31)  // SPI2_MOSI/TIM1_CH3N
 66
 67// Port-C
 68#define PC0   (32)  //
 69#define PC1   (33)  //
 70#define PC2   (34)  //
 71#define PC3   (35)  //
 72#define PC4   (36)  //
 73#define PC5   (37)  //
 74#define PC6   (38)  //
 75#define PC7   (39)  //
 76#define PC8   (40)  //
 77#define PC9   (41)  //
 78#define PC10  (42)  //
 79#define PC11  (43)  //
 80#define PC12  (44)  //
 81#define PC13  (45)  //
 82#define PC14  (46)  //
 83#define PC15  (47)  //
 84
 85// Port-D
 86#define PD0   (48)  //
 87#define PD1   (49)  //
 88#define PD2   (50)  //
 89#define PD3   (51)  //
 90#define PD4   (52)  //
 91#define PD5   (53)  //
 92#define PD6   (54)  //
 93#define PD7   (55)  //
 94#define PD8   (56)  //
 95#define PD9   (57)  //
 96#define PD10  (58)  //
 97#define PD11  (59)  //
 98#define PD12  (60)  //
 99#define PD13  (61)  //
100#define PD14  (62)  //
101#define PD15  (63)  //
102
103// Port-E
104#define PE0   (64)  //
105#define PE1   (65)  //
106#define PE2   (66)  //
107#define PE3   (67)  //
108#define PE4   (68)  //
109#define PE5   (69)  //
110#define PE6   (70)  //
111#define PE7   (71)  //
112#define PE8   (72)  //
113#define PE9   (73)  //
114#define PE10  (74)  //
115#define PE11  (75)  //
116#define PE12  (76)  //
117#define PE13  (77)  //
118#define PE14  (78)  //
119#define PE15  (79)  //
120
121/* Arduino Pin */
122// Analog(CN8)
123#define A0    (0)   // PA0
124#define A1    (1)   // PA1
125#define A2    (4)   // PA4
126#define A3    (16)  // PB0
127#define A4    (33)  // PC1(or PB9,change by solder bridges)
128#define A5    (32)  // PC0(or PB8,change by solder bridges)
129
130// Digital(CN9)
131#define D0    (3)   // PA3(USART2_RX)
132#define D1    (2)   // PA2(USART2_TX)
133#define D2    (10)  // PA10
134#define D3    (19)  // PB3(PWM)
135#define D4    (21)  // PB5
136#define D5    (20)  // PB4(PWM)
137#define D6    (26)  // PB10(PWM)
138#define D7    (8)   // PA8
139
140// Digital(CN5)
141#define D8    (9)   // PA9
142#define D9    (39)  // PC7(PWM)
143#define D10   (22)  // PB6(PWM/CS)
144#define D11   (7)   // PA7(PWM/MOSI)
145#define D12   (6)   // PA6(MISO)
146#define D13   (5)   // PA5(SCK)
147#define D14   (25)  // PB9(SDA)
148#define D15   (24)  // PB8(SCL)
149
150/* STM32 Nucleo-64 board */
151#define Button_User (45)  // PC13. B1. When push the button, the I/O is LOW value.
152#define B1          (45)
153#define LED_User    (5)   // PA5. LD2. When the I/O is HIGH value, the LED is on.
154#define LD2         (5)
155
156/* Exported macro ------------------------------------------------------------*/
157/* Exported functions ------------------------------------------------------- */
158
159#endif /* __GPIO_MAPPING_H */
160
161/********************************END OF FILE***********************************/

結語

這次簡單地分享了自己打的程式,不敢說自己的程式很完善、漂亮,但希望它有幫助到你。
如有問題或錯誤也歡迎提出討論!

注意,本文的內容過於老舊,不建議實際使用,僅保留以作爲參考用。



留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)

comments powered by Disqus