注意,本文的內容過於老舊,不建議實際使用,僅保留以作為參考用。
前言
在先前的[STM32學習記錄-3] 基本輸入與輸出教學-GPIO相關程式寫法中已經介紹過STM32設定GPIO的相關函式,但如果是常用Arduion的人一定不太習慣這種設定方式,畢竟每設定一個GPIO就要打4行程式,雖然可以複製貼上,但程式一多難免看起來混亂複雜,所以我自己寫了一些GPIO相關的函式,方便自己未來使用。
GPIO模式設定函式
程式如下:
/* Includes ------------------------------------------------------------------*/
#include "GPIO_mapping.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
// Pin Mode and Speed
#define OUT (0) // Output
#define IN (1) // Input
#define GPPP (0) // General purpose Push-Pull (Output)
#define GPOD (1) // General purpose Open-Drain (Output)
#define AFPP (2) // Alternate function Push-Pull (Output)
#define AFOD (3) // Alternate function Open-Drain (Output)
#define FL (0) // Floating (Input)
#define AN (1) // Analog (Input)
#define PD (2) // Pull-Down (Input)
#define PU (3) // Pull-Up (Input)
#define S2M (2) // 2MHz
#define S10M (10) // 10MHz
#define S50M (50) // 50MHz
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Config a pin mode and speed.
* @param PortPin: select a pin to set.
* This parameter should be: 0 ~ 79
* 0~15:PA0~PA15; 16~31:PB0~PB15; 32~47:PC0~PC15;
* 48~63:PD0~PD15; 64~79:PE0~PE15
* @param INout: Input or Output.
* This parameter should be: 0(Output) or 1(Input).
* @param Mode: Pin mode.
* This parameter should be: 0~3.
* 0: GPPP or FL.
* 1: GPOD or AN.
* 2: AFPP or PD.
* 3: AFOD or PU.
* @param Speed: Pin speed.
* This parameter should be: 2, 10 or 50.
* 2: 2MHz.
* 10: 10MHz.
* 50: 50MHz.
* @retval None
*/
void Pin_Mod(u8 PortPin, u8 INout, u8 Mode, u8 Speed)
{
/* Structure Declarations */
GPIO_InitTypeDef GPIO_InitStructure;
// GPIO_Speed
switch(Speed)
{
case S2M: // S2M:2
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
break;
case S10M: // S10M:10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
break;
case S50M: // S50M:50
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
break;
default:
break;
}
// GPIO_Mode
if(INout == OUT) // OUT:0
{
switch(Mode)
{
case GPPP: // GPPP:0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
break;
case GPOD: // GPOD:1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
break;
case AFPP: // AFPP:2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
break;
case AFOD: // AFOD:3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
break;
default:
break;
}
}
else if(INout == IN) // IN:1
{
switch(Mode)
{
case FL: // FL:0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
break;
case AN: // AN:1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
break;
case PD: // PD:2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
break;
case PU: // PU:3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
break;
default:
break;
}
}
// GPIO_Pin & GPIO_Init() function.
if(PortPin <= 15) // Port-A: 0~15
{
GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << PortPin));
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
else if(PortPin <= 31) // Port-B: 16~31
{
GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << (PortPin - 16)));
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
else if(PortPin <= 47) // Port-C: 32~47
{
GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << (PortPin - 32)));
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
else if(PortPin <= 63) // Port-D: 48~63
{
GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << (PortPin - 48)));
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
else if(PortPin <= 79) // Port-E: 64~79
{
GPIO_InitStructure.GPIO_Pin = ((uint16_t)(0x0001 << (PortPin - 64)));
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
else /* Null */; // Out of range(0~79)
}
#undef OUT
#undef IN
#undef GPPP
#undef GPOD
#undef AFPP
#undef AFOD
#undef FL
#undef AN
#undef PD
#undef PU
#undef S2M
#undef S10M
#undef S50M
可以看到裡面就是增加了“void Pin_Mod(u8 PortPin, u8 INout, u8 Mode, u8 Speed)”此一函式。其用法如下:
/* STM32 Nucleo-64 board */
Pin_Mod(PA5, OUT, GPPP, S2M); // PA5: LED-user
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
//GPIO_Init(GPIOA, &GPIO_InitStructure);
Pin_Mod(PC13, IN, FL, S2M); // PC13: Button-user
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
//GPIO_Init(GPIOC, &GPIO_InitStructure);
/* USART */
Pin_Mod(PA2, OUT, AFPP, S50M); // PA2: USART2_TX
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIO_Init(GPIOA, &GPIO_InitStructure);
Pin_Mod(PA3, IN, FL, S50M); // PA3: USART2_RX
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//GPIO_Init(GPIOA, &GPIO_InitStructure);
這樣的話就可以更簡單方便地設定GPIO了。
至於其引入的“GPIO_mapping.h”內容如下:(只適用於STM32F103RB,請依照自己的MCU腳位更改)
/**
******************************************************************************
* @file GPIO_mapping.h
* @author ZiTe
* @version V1.0.0
* @date 08-October-2019
* @brief Header for GPIO_Function.c module for STM32F103RB
******************************************************************************
* @attention
*
* This file is used ONLY for STM32F103RB(STM32 Nucleo-64 board).
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __GPIO_MAPPING_H
#define __GPIO_MAPPING_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* STM32 Pin(Morpho) */
/*
* Default=Alternate functions Default
* MA=Main function(after reset)
* Remap=Alternate functions Remap
*/
// Port-A
#define PA0 (0) // WKUP/USART2_CTS/ADC12_IN0/TIM2_CH1_ETR
#define PA1 (1) // USART2_RTS/ADC12_IN1/TIM2_CH2
#define PA2 (2) // USART2_TX/ADC12_IN2/TIM2_CH3
#define PA3 (3) // USART2_RX/ADC12_IN3/TIM2_CH4
#define PA4 (4) // SPI1_NSS/USART2_CK/ADC12_IN4
#define PA5 (5) // SPI1_SCK/ADC12_IN5
#define PA6 (6) // SPI1_MISO/ADC12_IN6/TIM3_CH1;Remap:TIM1_BKIN
#define PA7 (7) // SPI1_MOSI/ADC12_IN7/TIM3_CH2;Remap:TIM1_CH1N
#define PA8 (8) // USART1_CK/TIM1_CH1/MCO
#define PA9 (9) // USART1_TX/TIM1_CH2
#define PA10 (10) // USART1_RX/TIM1_CH3
#define PA11 (11) // USART1_CTS/CANRX/USBDM/TIM1_CH4
#define PA12 (12) // USART1_RTS/CANTX/USBDP/TIM1_ETR
#define PA13 (13) // MA:JTMS/SWDIO;Remap:PA13
#define PA14 (14) // MA:JTCK/SWCLK;Remap:PA14
#define PA15 (15) // MA:JTDI;Remap:TIM2_CH1_ETR/ PA15/SPI1_NSS
// Port-B
#define PB0 (16) // ADC12_IN8/TIM3_CH3;Remap:TIM1_CH2N
#define PB1 (17) // ADC12_IN9/TIM3_CH4;Remap:TIM1_CH3N
#define PB2 (18) // MA:PB2/BOOT1
#define PB3 (19) // MA:JTDO;Remap:TIM2_CH2/PB3/TRACESWO/SPI1_SCK
#define PB4 (20) // MA:JNTRST;Remap:TIM3_CH1/PB4/SPI1_MISO
#define PB5 (21) // I2C1_SMBAl;Remap:TIM3_CH2/SPI1_MOSI
#define PB6 (22) // I2C1_SCL/TIM4_CH1;Remap:USART1_TX
#define PB7 (23) // I2C1_SDA/TIM4_CH2;Remap:USART1_RX
#define PB8 (24) // TIM4_CH3;Remap:I2C1_SCL/CANRX
#define PB9 (25) // TIM4_CH4;Remap:I2C1_SDA/CANTX
#define PB10 (26) // I2C2_SCL/USART3_TX;Remap:TIM2_CH3
#define PB11 (27) // I2C2_SDA/USART3_RX;Remap:TIM2_CH4
#define PB12 (28) // SPI2_NSS/I2C2_SMBAl/USART3_CK/TIM1_BKIN
#define PB13 (29) // SPI2_SCK/USART3_CTS/TIM1_CH1N
#define PB14 (30) // SPI2_MISO/USART3_RTS/TIM1_CH2N
#define PB15 (31) // SPI2_MOSI/TIM1_CH3N
// Port-C
#define PC0 (32) //
#define PC1 (33) //
#define PC2 (34) //
#define PC3 (35) //
#define PC4 (36) //
#define PC5 (37) //
#define PC6 (38) //
#define PC7 (39) //
#define PC8 (40) //
#define PC9 (41) //
#define PC10 (42) //
#define PC11 (43) //
#define PC12 (44) //
#define PC13 (45) //
#define PC14 (46) //
#define PC15 (47) //
// Port-D
#define PD0 (48) //
#define PD1 (49) //
#define PD2 (50) //
#define PD3 (51) //
#define PD4 (52) //
#define PD5 (53) //
#define PD6 (54) //
#define PD7 (55) //
#define PD8 (56) //
#define PD9 (57) //
#define PD10 (58) //
#define PD11 (59) //
#define PD12 (60) //
#define PD13 (61) //
#define PD14 (62) //
#define PD15 (63) //
// Port-E
#define PE0 (64) //
#define PE1 (65) //
#define PE2 (66) //
#define PE3 (67) //
#define PE4 (68) //
#define PE5 (69) //
#define PE6 (70) //
#define PE7 (71) //
#define PE8 (72) //
#define PE9 (73) //
#define PE10 (74) //
#define PE11 (75) //
#define PE12 (76) //
#define PE13 (77) //
#define PE14 (78) //
#define PE15 (79) //
/* Arduino Pin */
// Analog(CN8)
#define A0 (0) // PA0
#define A1 (1) // PA1
#define A2 (4) // PA4
#define A3 (16) // PB0
#define A4 (33) // PC1(or PB9,change by solder bridges)
#define A5 (32) // PC0(or PB8,change by solder bridges)
// Digital(CN9)
#define D0 (3) // PA3(USART2_RX)
#define D1 (2) // PA2(USART2_TX)
#define D2 (10) // PA10
#define D3 (19) // PB3(PWM)
#define D4 (21) // PB5
#define D5 (20) // PB4(PWM)
#define D6 (26) // PB10(PWM)
#define D7 (8) // PA8
// Digital(CN5)
#define D8 (9) // PA9
#define D9 (39) // PC7(PWM)
#define D10 (22) // PB6(PWM/CS)
#define D11 (7) // PA7(PWM/MOSI)
#define D12 (6) // PA6(MISO)
#define D13 (5) // PA5(SCK)
#define D14 (25) // PB9(SDA)
#define D15 (24) // PB8(SCL)
/* STM32 Nucleo-64 board */
#define Button_User (45) // PC13. B1. When push the button, the I/O is LOW value.
#define B1 (45)
#define LED_User (5) // PA5. LD2. When the I/O is HIGH value, the LED is on.
#define LD2 (5)
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __GPIO_MAPPING_H */
/********************************END OF FILE***********************************/
結語
這次簡單地分享了自己打的程式,不敢說自己的程式很完善、漂亮,但希望它有幫助到你。 如有問題或錯誤也歡迎提出討論!
注意,本文的內容過於老舊,不建議實際使用,僅保留以作為參考用。
留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)