STM32H743的GPIO根据数据手册中列出的每个 I/O 端口的特性,可通过软件将通用 I/O (GPIO) 端口的各个端口
位分别配置为多种模式:
输入浮空
输入上拉
输入下拉
模拟
具有上拉或下拉功能的开漏输出
具有上拉或下拉功能的推挽输出
具有上拉或下拉功能的复用功能推挽
具有上拉或下拉功能的复用功能开漏
首先定义GPIO模式
//GPIO模式定义
typedef enum
{
OUT_PP = 0x010000, //推挽输出
OUT_PP_OPU = 0x010001, //上拉推挽输出
OUT_PP_OPD = 0x010002, //下拉推挽输出
OUT_OD = 0x010100, //开漏输出
OUT_OD_OPU = 0x010101, //上拉开漏输出
OUT_OD_OPD = 0x010102, //下拉开漏输出
IN_FLOATING = 0x000000, //浮空输入
IN_IPU = 0x000001, //上拉输入
IN_IPD = 0x000002, //下拉输入
IN_AIN = 0x030000, //模拟输入
}SYS_GPIO_MODE;
//GPIO输出速度定义
typedef enum
{
IN_NONE = 0x00, //输入模式,保留
SPEED_2M = 0x00, //2MHZ
SPEED_25M = 0x01, //25MHZ
SPEED_50M = 0x02, //50MHZ
SPEED_100M = 0x03, //100MHZ 30 pF 时为 100 MHz(高速)(15 pF 时为 80 MHz 输出(最大速度))
}SYS_GPIO_SPEED;
//具体IO驱动代码如下,主要完成GPIO的初始化以及复用功能设置,IO初始化后会默认关闭复用功能,需要单独再次设置复用功能。
/*************************************************************************************************************************
* 函数 : void SYS_GPIOx_Init(GPIO_TypeDef *GPIOx, u16 io_bit, SYS_GPIO_MODE mode, SYS_GPIO_SPEED speed)
* 功能 : GPIO初始化(可同时初始化多个IO)
* 参数 : GPIOx:GPIO选择,从GPIOA~GPIOI;io_bit:bit0~bit15,多个IO进行或;mode:IO模式,见SYS_GPIO_MODE;speed:IO速度,见SYS_GPIO_SPEED
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : www.scj-water.com
* 时间 : 2025-02-09
* 最后修改时间 : 2025-02-09
* 说明 : 多个IO可以直接或,最多设置16个IO,输出速度只针对输出模式有效
设置单个IO时可能效率会很低
注意:必须先初始化IO时钟才能进行设置,否则设置无效
*************************************************************************************************************************/
void SYS_GPIOx_Init(GPIO_TypeDef* GPIOx, u16 io_bit, SYS_GPIO_MODE mode, SYS_GPIO_SPEED speed)
{
u32 moder = (mode >> 16) & 0x03;
u32 otyper = (mode >> 8) & 0x01;
u32 pupdr = mode & 0x03;
u32 speedr = speed & 0x03;
u8 i;
for (i = 0; i < 16; i++)
{
if (io_bit & (1 << i)) //需要设置对应IO
{
GPIOx->MODER &= ~(0x03 << (i * 2)); //先清除端口模式寄存器
GPIOx->MODER |= moder << (i * 2); //设置端口模式寄存器
GPIOx->OTYPER &= ~(1 << i); //先清除输出类型寄存器
GPIOx->OTYPER |= otyper; //设置输出类型寄存器
GPIOx->PUPDR &= ~(0x03 << (i * 2)); //先清除端口上拉/下拉寄存器
GPIOx->PUPDR |= pupdr << (i * 2); //设置端口上拉/下拉寄存器
//设置端口速度寄存器,只针对输出端口有效
GPIOx->OSPEEDR &= ~(0x03 << (i * 2)); //先清除端口输出速度寄存器
GPIOx->OSPEEDR |= speedr << (i * 2); //设置端口输出速度寄存器
}
}
}
/*************************************************************************************************************************
* 函数 : void SYS_GPIOx_OneInit(GPIO_TypeDef *GPIOx, u8 io_num, SYS_GPIO_MODE mode, SYS_GPIO_SPEED speed)
* 功能 : 单个GPIO初始化
* 参数 : GPIOx:GPIO选择,从GPIOA~GPIOI;io_num:0-15;mode:IO模式,见SYS_GPIO_MODE;speed:IO速度,见SYS_GPIO_SPEED
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : www.scj-water.com
* 时间 : 2025-02-09
* 最后修改时间 : 2025-02-09
* 说明 : 输出速度只针对输出模式有效
只能设置单个IO,单个IO设置效率较多个IO同时设置高
注意:必须先初始化IO时钟才能进行设置,否则设置无效
2025-03-15:默认会关闭复用功能
*************************************************************************************************************************/
void SYS_GPIOx_OneInit(GPIO_TypeDef* GPIOx, u8 io_num, SYS_GPIO_MODE mode, SYS_GPIO_SPEED speed)
{
u32 moder = (mode >> 16) & 0x03;
u32 otyper = (mode >> 8) & 0x01;
u32 pupdr = mode & 0x03;
u32 speedr = speed & 0x03;
if (io_num > 15) return; //无效的IO
GPIOx->MODER &= ~(0x03 << (io_num * 2)); //先清除端口模式寄存器
GPIOx->MODER |= moder << (io_num * 2); //设置端口模式寄存器
GPIOx->OTYPER &= ~(1 << io_num); //先清除输出类型寄存器
GPIOx->OTYPER |= otyper; //设置输出类型寄存器
GPIOx->PUPDR &= ~(0x03 << (io_num * 2)); //先清除端口上拉/下拉寄存器
GPIOx->PUPDR |= pupdr << (io_num * 2); //设置端口上拉/下拉寄存器
//设置端口速度寄存器,只针对输出端口有效
GPIOx->OSPEEDR &= ~(0x03 << (io_num * 2));//先清除端口输出速度寄存器
GPIOx->OSPEEDR |= speedr << (io_num * 2); //设置端口输出速度寄存器
}
/*************************************************************************************************************************
* 函数 : void SYS_GPIOx_SetAF(GPIO_TypeDef *GPIOx, u8 io_num, SYS_GPIO_AF af_mode)
* 功能 : 单个GPIO AF复用模式设置
* 参数 : GPIOx:GPIO选择,从GPIOA~GPIOI;io_num:0-15;af_mode:AF模式,SYS_GPIO_AF
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : www.scj-water.com
* 时间 : 2025-02-09
* 最后修改时间 : 2025-02-09
* 说明 : 单个IO复用模式设置
注意:必须先初始化IO时钟才能进行设置,否则设置无效,会设置使能复用模式
*************************************************************************************************************************/
void SYS_GPIOx_SetAF(GPIO_TypeDef* GPIOx, u8 io_num, SYS_GPIO_AF af_mode)
{
if (af_mode > 15) return;
if (io_num > 15) return;//无效的IO
if (io_num > 7) //高8位
{
GPIOx->AFR[1] &= ~(0XF << ((io_num - 8) * 4)); //清空设置
GPIOx->AFR[1] |= (af_mode & 0XF) << ((io_num - 8) * 4); //设置复用
}
else //低8位
{
GPIOx->AFR[0] &= ~(0XF << ((io_num - 0) * 4)); //清空设置
GPIOx->AFR[0] |= (af_mode & 0XF) << ((io_num - 0) * 4); //设置复用
}
GPIOx->MODER &= ~(0x03 << (io_num * 2)); //先清除端口模式寄存器
GPIOx->MODER |= 2 << (io_num * 2); //设置端口模式寄存器-复用模式
}
使用STM32最常用的IO操作,就是位带,比较方便。
//IO 位操作
typedef struct
{
uint32_t _BIT0 : 1;
uint32_t _BIT1 : 1;
uint32_t _BIT2 : 1;
uint32_t _BIT3 : 1;
uint32_t _BIT4 : 1;
uint32_t _BIT5 : 1;
uint32_t _BIT6 : 1;
uint32_t _BIT7 : 1;
uint32_t _BIT8 : 1;
uint32_t _BIT9 : 1;
uint32_t _BIT10 : 1;
uint32_t _BIT11 : 1;
uint32_t _BIT12 : 1;
uint32_t _BIT13 : 1;
uint32_t _BIT14 : 1;
uint32_t _BIT15 : 1;
uint32_t _BIT16 : 1;
uint32_t _BIT17 : 1;
uint32_t _BIT18 : 1;
uint32_t _BIT19 : 1;
uint32_t _BIT20 : 1;
uint32_t _BIT21 : 1;
uint32_t _BIT22 : 1;
uint32_t _BIT23 : 1;
uint32_t _BIT24 : 1;
uint32_t _BIT25 : 1;
uint32_t _BIT26 : 1;
uint32_t _BIT27 : 1;
uint32_t _BIT28 : 1;
uint32_t _BIT29 : 1;
uint32_t _BIT30 : 1;
uint32_t _BIT31 : 1;
}Bit_Type;
//输出寄存器
#define PAout(pin) (*(Bit_Type *)&GPIOA->ODR)._BIT ## pin
#define PBout(pin) (*(Bit_Type *)&GPIOB->ODR)._BIT ## pin
#define PCout(pin) (*(Bit_Type *)&GPIOC->ODR)._BIT ## pin
#define PDout(pin) (*(Bit_Type *)&GPIOD->ODR)._BIT ## pin
#define PEout(pin) (*(Bit_Type *)&GPIOE->ODR)._BIT ## pin
#define PFout(pin) (*(Bit_Type *)&GPIOF->ODR)._BIT ## pin
#define PGout(pin) (*(Bit_Type *)&GPIOG->ODR)._BIT ## pin
#define PHout(pin) (*(Bit_Type *)&GPIOH->ODR)._BIT ## pin
#define PIout(pin) (*(Bit_Type *)&GPIOI->ODR)._BIT ## pin
#define PJout(pin) (*(Bit_Type *)&GPIOJ->ODR)._BIT ## pin
#define PKout(pin) (*(Bit_Type *)&GPIOK->ODR)._BIT ## pin
//输入寄存器
#define PAin(pin) (*(Bit_Type *)&GPIOA->IDR)._BIT ## pin
#define PBin(pin) (*(Bit_Type *)&GPIOB->IDR)._BIT ## pin
#define PCin(pin) (*(Bit_Type *)&GPIOC->IDR)._BIT ## pin
#define PDin(pin) (*(Bit_Type *)&GPIOD->IDR)._BIT ## pin
#define PEin(pin) (*(Bit_Type *)&GPIOE->IDR)._BIT ## pin
#define PFin(pin) (*(Bit_Type *)&GPIOF->IDR)._BIT ## pin
#define PGin(pin) (*(Bit_Type *)&GPIOG->IDR)._BIT ## pin
#define PHin(pin) (*(Bit_Type *)&GPIOH->IDR)._BIT ## pin
#define PIin(pin) (*(Bit_Type *)&GPIOI->IDR)._BIT ## pin
#define PJin(pin) (*(Bit_Type *)&GPIOJ->IDR)._BIT ## pin
#define PKin(pin) (*(Bit_Type *)&GPIOK->IDR)._BIT ## pin
//测试代码如下
SYS_DeviceClockEnable(DEV_GPIOB, TRUE); //使能GPIOB时钟
SYS_GPIOx_OneInit(GPIOB, 0, OUT_PP, SPEED_50M);
SYS_GPIOx_OneInit(GPIOB, 1, OUT_PP, SPEED_50M);
PBout(0) = 0;
PBout(1) = 0;
如果您有任何问题,请跟我们联系!
欢迎来电:18571629282
Copyright © 2024 武汉水测家科技有限公司 版权所有 鄂ICP备2022002065号-1 --WTRExpert English website--