遥测终端机MCU IO操作;MCU GPIO驱动,STM32H7 GPIO驱动

网站导航

开发相关(SCJ)

当前位置: 首页 > 开发相关(SCJ)
STM32H7 IO操作(STM32H743 GPIO驱动)
时间:2025-03-31 13:17:56 点击次数:

STM32H7 IO操作(STM32H743 GPIO驱动)


STM32H743的GPIO根据数据手册中列出的每个 I/O 端口的特性,可通过软件将通用 I/O (GPIO) 端口的各个端口
位分别配置为多种模式:
输入浮空
输入上拉
输入下拉
模拟
具有上拉或下拉功能的开漏输出
具有上拉或下拉功能的推挽输出
具有上拉或下拉功能的复用功能推挽
具有上拉或下拉功能的复用功能开漏


image.png

image.png

image.png


首先定义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--

XML地图

QQ在线咨询
销售(微信同号)
18571629282
技术(微信同号)
13871206075