一、几个重要的IO口操作函数
- HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init); // GPIO初始化
- HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState); // 输出高低电平
- GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // 读IO口电平
- void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); // 电平取反
复制代码
二、几个重要的结构
- // GPIO口 GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF,GPIOG,GPIOH,GPIOI
- typedef struct
- {
- __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */
- __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
- __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */
- __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */
- __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */
- __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */
- __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */
- __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */
- __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */
- } GPIO_TypeDef;
复制代码- // GPIO引脚,模式,上下拉,速度,复用等
- typedef struct
- {
- uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
- This parameter can be any value of @ref GPIO_pins_define */
- uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
- This parameter can be a value of @ref GPIO_mode_define */
- uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
- This parameter can be a value of @ref GPIO_pull_define */
- uint32_t Speed; /*!< Specifies the speed for the selected pins.
- This parameter can be a value of @ref GPIO_speed_define */
- uint32_t Alternate; /*!< Peripheral to be connected to the selected pins.
- This parameter can be a value of @ref GPIO_Alternate_function_selection */
- }GPIO_InitTypeDef;
复制代码- // GPIO引脚
- #define GPIO_PIN_0 ((uint16_t)0x0001U) /* Pin 0 selected */
- #define GPIO_PIN_1 ((uint16_t)0x0002U) /* Pin 1 selected */
- #define GPIO_PIN_2 ((uint16_t)0x0004U) /* Pin 2 selected */
- #define GPIO_PIN_3 ((uint16_t)0x0008U) /* Pin 3 selected */
- #define GPIO_PIN_4 ((uint16_t)0x0010U) /* Pin 4 selected */
- #define GPIO_PIN_5 ((uint16_t)0x0020U) /* Pin 5 selected */
- #define GPIO_PIN_6 ((uint16_t)0x0040U) /* Pin 6 selected */
- #define GPIO_PIN_7 ((uint16_t)0x0080U) /* Pin 7 selected */
- #define GPIO_PIN_8 ((uint16_t)0x0100U) /* Pin 8 selected */
- #define GPIO_PIN_9 ((uint16_t)0x0200U) /* Pin 9 selected */
- #define GPIO_PIN_10 ((uint16_t)0x0400U) /* Pin 10 selected */
- #define GPIO_PIN_11 ((uint16_t)0x0800U) /* Pin 11 selected */
- #define GPIO_PIN_12 ((uint16_t)0x1000U) /* Pin 12 selected */
- #define GPIO_PIN_13 ((uint16_t)0x2000U) /* Pin 13 selected */
- #define GPIO_PIN_14 ((uint16_t)0x4000U) /* Pin 14 selected */
- #define GPIO_PIN_15 ((uint16_t)0x8000U) /* Pin 15 selected */
复制代码- // GPIO模式 输入 推挽输出 开漏输出 推挽复用 开漏复用
- #define GPIO_MODE_INPUT ((uint32_t)0x00000000U) /*!< Input Floating Mode */
- #define GPIO_MODE_OUTPUT_PP ((uint32_t)0x00000001U) /*!< Output Push Pull Mode */
- #define GPIO_MODE_OUTPUT_OD ((uint32_t)0x00000011U) /*!< Output Open Drain Mode */
- #define GPIO_MODE_AF_PP ((uint32_t)0x00000002U) /*!< Alternate Function Push Pull Mode */
- #define GPIO_MODE_AF_OD ((uint32_t)0x00000012U) /*!< Alternate Function Open Drain Mode */
复制代码- // GPIO速度 低速 中速 高速 极速
- #define GPIO_SPEED_FREQ_LOW ((uint32_t)0x00000000U) /*!< Low speed */
- #define GPIO_SPEED_FREQ_MEDIUM ((uint32_t)0x00000001U) /*!< Medium speed */
- #define GPIO_SPEED_FREQ_HIGH ((uint32_t)0x00000002U) /*!< Fast speed */
- #define GPIO_SPEED_FREQ_VERY_HIGH ((uint32_t)0x00000003U) /*!< High speed */
复制代码- // GPIO上下拉 无上下拉 上拉 下拉
- #define GPIO_NOPULL ((uint32_t)0x00000000U) /*!< No Pull-up or Pull-down activation */
- #define GPIO_PULLUP ((uint32_t)0x00000001U) /*!< Pull-up activation */
- #define GPIO_PULLDOWN ((uint32_t)0x00000002U) /*!< Pull-down activation */
复制代码- // GPIO引脚高低电平
- typedef enum
- {
- GPIO_PIN_RESET = 0,
- GPIO_PIN_SET
- }GPIO_PinState;
复制代码
三、封装两个GPIO初始化函数(普通GPIO,复用GPIO)
- // 这里只贴出代码片段,封装两个接口,一个普通GPIO初始化,一个带复用功能。
- #define GPIO_CLK_ENABLE() do{ \
- __HAL_RCC_GPIOA_CLK_ENABLE(); \
- __HAL_RCC_GPIOB_CLK_ENABLE(); \
- __HAL_RCC_GPIOC_CLK_ENABLE(); \
- __HAL_RCC_GPIOD_CLK_ENABLE(); \
- __HAL_RCC_GPIOE_CLK_ENABLE(); \
- __HAL_RCC_GPIOF_CLK_ENABLE(); \
- __HAL_RCC_GPIOG_CLK_ENABLE(); \
- __HAL_RCC_GPIOH_CLK_ENABLE(); \
- __HAL_RCC_GPIOI_CLK_ENABLE(); \
- } while(0);
- void GPIOConfig(GPIO_TypeDef *gpio, uint32_t pin, uint32_t mode, uint32_t pull)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_CLK_ENABLE();
- GPIO_InitStructure.Pin = pin;
- GPIO_InitStructure.Mode = mode;
- GPIO_InitStructure.Pull = pull;
- GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
- HAL_GPIO_Init(gpio, &GPIO_InitStructure);
- }
- void GPIOConfigExt(GPIO_TypeDef *gpio, uint32_t pin, uint32_t mode, uint32_t pull, uint32_t alternate)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_CLK_ENABLE();
- GPIO_InitStructure.Pin = pin;
- GPIO_InitStructure.Mode = mode;
- GPIO_InitStructure.Pull = pull;
- GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
- GPIO_InitStructure.Alternate = alternate;
- HAL_GPIO_Init(gpio, &GPIO_InitStructure);
- }
复制代码
四、输出接口设计
为了灵活使用,我们将输出的有效电平设置成可配置。
- // 配置的有效电平 初始 低电平有效 高电平有效
- typedef enum
- {
- OUTPUT_INIT_IS_ACTIVE = 0,
- OUTPUT_LOW_IS_ACTIVE = 1,
- OUTPUT_HIGH_IS_ACTIVE = 2,
- } output_active_t;
- #define OUTX_CONFIG(gpio, pin) GPIOConfig(gpio, pin, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL)
- #define OUTX_READ(gpio, pin) HAL_GPIO_ReadPin(gpio, pin)
- #define OUTX_ACTIVE(gpio, pin, tag) do{ \
- if(OUTPUT_LOW_IS_ACTIVE == tag) \
- { \
- HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_RESET); \
- } \
- else \
- { \
- HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_SET); \
- } \
- } while(0);
- #define OUTX_NEGATIVE(gpio, pin, tag) do{ \
- if(OUTPUT_LOW_IS_ACTIVE == tag) \
- { \
- HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_SET); \
- } \
- else \
- { \
- HAL_GPIO_WritePin(gpio, pin, GPIO_PIN_RESET); \
- } \
- } while(0);
- #define OUT1_PORT GPIOA
- #define OUT1_PIN GPIO_PIN_0
- #define OUT2_PORT GPIOA
- #define OUT2_PIN GPIO_PIN_1
- #define OUT3_PORT GPIOA
- #define OUT3_PIN GPIO_PIN_2
复制代码- // demo代码 只传递思想
- // 封装出对外的四个接口 初始化 输出有效 输出无效 输出取反
- // 以列表的形式封装 方便增加和删除
- static void output_config(GPIO_TypeDef *gpio, uint16_t pin)
- {
- OUTX_CONFIG(gpio, pin);
- }
- static uint8_t output_is_enable(uint8_t index)
- {
- // 输出通道可用 这里也可以变成可配置 可以配置本IO口有效和无效
- return 1;
- }
- static void output_active(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
- {
- OUTX_ACTIVE(gpio, pin, tag);
- }
- static void output_negative(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
- {
- OUTX_NEGATIVE(gpio, pin, tag);
- }
- static void output_toggle(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag)
- {
- // 这里可以不用这么麻烦,使用HAL_GPIO_TogglePin
- if(OUTX_READ(gpio, pin) == 0)
- {
- OUTX_ACTIVE(gpio, pin, tag);
- }
- else
- {
- OUTX_NEGATIVE(gpio, pin, tag);
- }
- }
- typedef struct
- {
- GPIO_TypeDef *gpio;
- uint16_t pin;
- void (* output_config_cb)(GPIO_TypeDef *gpio, uint16_t pin);
- uint8_t (* output_is_enable_cb)(uint8_t index);
- void (* output_active_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
- void (* output_negative_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
- void (* output_toggle_cb)(GPIO_TypeDef *gpio, uint16_t pin, uint8_t tag);
- } output_port_t;
- static output_port_t output_items[] =
- {
- {OUT1_PORT, OUT1_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
- {OUT2_PORT, OUT2_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
- {OUT3_PORT, OUT3_PIN, output_config, output_is_enable, output_active, output_negative, output_toggle},
- };
- static void output_init(uint32_t value)
- {
- uint32_t i, mask = 1;
- for(i = 0; i < ARRAY_SIZE(output_items); ++i)
- {
- if(value & mask)
- {
- #if(CONFIG_OUTPUT_TEST == 1)
- config.output.total_switch = OUTPUT_MODE_OPEN;
- config.output.sub_switch<i> = OUTPUT_MODE_OPEN;
- </i> config.output.active_tag = OUTPUT_HIGH_IS_ACTIVE;
- #endif
- output_items.output_config_cb(output_items.gpio, output_items.pin);
- output_items.output_negative_cb(output_items.gpio, output_items.pin, config.output.active_tag);
- }
- mask <<= 1;
- }
- }
- void OutputHigh(uint32_t value)
- {
- uint32_t i, mask = 1;
- for(i = 0; i < ARRAY_SIZE(output_items); ++i)
- {
- if(value & mask)
- {
- if(output_items.output_is_enable_cb(i))
- {
- output_items.output_active_cb(output_items.gpio, output_items.pin, config.output.active_tag);
- }
- }
- mask <<= 1;
- }
- }
- void OutputLow(uint32_t value)
- {
- uint32_t i, mask = 1;
- for(i = 0; i < ARRAY_SIZE(output_items); ++i)
- {
- if(value & mask)
- {
- if(output_items.output_is_enable_cb(i))
- {
- output_items.output_negative_cb(output_items.gpio, output_items.pin, config.output.active_tag);
- }
- }
- mask <<= 1;
- }
- }
- void OutputToggle(uint32_t value)
- {
- uint32_t i, mask = 1;
- for(i = 0; i < ARRAY_SIZE(output_items); ++i)
- {
- if(value & mask)
- {
- if(output_items.output_is_enable_cb(i))
- {
- output_items.output_toggle_cb(output_items.gpio, output_items.pin, config.output.active_tag);
- }
- }
- mask <<= 1;
- }
- }
- void OutputInit(void)
- {
- output_init(0xFFFFFFFF);
- OutputLow(0xFFFFFFFF);
- }
复制代码
|