学做投资网站,深圳外贸建站,江苏省高校品牌专业建设网站,网站建设相关岗位名称STM32——GPIO 宗旨#xff1a;技术的学习是有限的#xff0c;分享的精神是无限的。 /* GPIO_InitTypeDef结构体 */
typedef enum
{GPIO_Speed_10MHz 1, //枚举常量#xff0c;值为 1#xff0c;代表输出速率最高为 10MHzGPIO_Speed_2MHz, //对不赋值的枚举变量技术的学习是有限的分享的精神是无限的。 /* GPIO_InitTypeDef结构体 */
typedef enum
{GPIO_Speed_10MHz 1, //枚举常量值为 1代表输出速率最高为 10MHzGPIO_Speed_2MHz, //对不赋值的枚举变量自动加 1此常量值为 2GPIO_Speed_50MHz //常量值为 3
} GPIOSpeed_TypeDef;typedef enum
{GPIO_Mode_AIN 0x0, //模拟输入模式GPIO_Mode_IN_FLOATING 0x04, //浮空输入模式GPIO_Mode_IPD 0x28, //下拉输入模式GPIO_Mode_IPU 0x48, //上拉输入模式GPIO_Mode_Out_OD 0x14, //开漏输出模式GPIO_Mode_Out_PP 0x10, //通用推挽输出模式GPIO_Mode_AF_OD 0x1C, //复用功能开漏输出GPIO_Mode_AF_PP 0x18 //复用功能推挽输出
} GPIOMode_TypeDef;typedef struct
{uint16_t GPIO_Pin; /* 指定要配置的引脚 */GPIOSpeed_TypeDef GPIO_Speed; /* 指定GPIO引脚输出的最高频率 */GPIOMode_TypeDef GPIO_Mode; /* 指定GPIO引脚工作状态 */
} GPIO_InitTypeDef;/* 初始化GPIO -- GPIO_Init() */
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
{uint32_t currentmode 0x00, currentpin 0x00, pinpos 0x00, pos 0x00;uint32_t tmpreg 0x00, pinmask 0x00;/* 断言用于检查输入的参数是否正确 */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GPIO_MODE(GPIO_InitStruct-GPIO_Mode));assert_param(IS_GPIO_PIN(GPIO_InitStruct-GPIO_Pin));/*---------------------------- GPIO 的模式配置 -----------------------*//*把输入参数 GPIO_Mode 的低四位暂存在 currentmode*/currentmode ((uint32_t)GPIO_InitStruct - GPIO_Mode) ((uint32_t)0x0F);/*判断是否为输出模式输出模式可输入参数中输出模式的 bit4 位都是 1*/if ((((uint32_t)GPIO_InitStruct - GPIO_Mode) ((uint32_t)0x10)) ! 0x00){/* 检查输入参数 */assert_param(IS_GPIO_SPEED(GPIO_InitStruct-GPIO_Speed));/* 输出模式所以要配置 GPIO 的速率:00(输入模式) 01(10MHz) 10(2MHz) 11 */currentmode | (uint32_t)GPIO_InitStruct-GPIO_Speed;}/*----------------------------配置 GPIO 的 CRL 寄存器 ------------------------*//* 判断要配置的是否为 pin0 ~~ pin7 */if (((uint32_t)GPIO_InitStruct - GPIO_Pin ((uint32_t)0x00FF)) ! 0x00){/*备份原 CRL 寄存器的值*/tmpreg GPIOx-CRL;/*循环一个循环设置一个寄存器位*/for (pinpos 0x00; pinpos 0x08; pinpos){/*pos 的值为 1 左移 pinpos 位*/pos ((uint32_t)0x01) pinpos;/* 令 pos 与输入参数 GPIO_PIN 作位与运算为下面的判断作准备 */currentpin (GPIO_InitStruct-GPIO_Pin) pos;/*判断若 currentpinpos,说明 GPIO_PIN 参数中含的第 pos 个引脚需要配置*/if (currentpin pos){/*pos 的值左移两位乘以 4因为寄存器中 4 个寄存器位配置一个引脚*/pos pinpos 2;/*以下两个句子把控制这个引脚的 4 个寄存器位清零其它寄存器位不变*/pinmask ((uint32_t)0x0F) pos;tmpreg ~pinmask;/* 向寄存器写入将要配置的引脚的模式 */tmpreg | (currentmode pos);/* 复位 GPIO 引脚的输入输出默认值*//*判断是否为下拉输入模式*/if (GPIO_InitStruct-GPIO_Mode GPIO_Mode_IPD){/*下拉输入模式引脚默认置 0对 BRR 寄存器写 1 可对引脚置 0*/GPIOx-BRR (((uint32_t)0x01) pinpos);}else{/*判断是否为上拉输入模式*/if (GPIO_InitStruct-GPIO_Mode GPIO_Mode_IPU){/*上拉输入模式引脚默认值为 1对 BSRR 寄存器写 1 可对引脚置 1*/GPIOx-BSRR (((uint32_t)0x01) pinpos);}}}}/*把前面处理后的暂存值写入到 CRL 寄存器之中*/GPIOx-CRL tmpreg;}/*---------------------------- 以下部分是对 CRH 寄存器配置的 -------------------------当要配置的引脚为 pin8 ~~ pin15 的时候配置 CRH 寄存器 ------------------ -----这过程和配置 CRL 寄存器类似-------------------------------------------读者可自行分析看看自己是否了解了上述过程--^_^-----------*//* Configure the eight high port pins */if (GPIO_InitStruct-GPIO_Pin 0x00FF){tmpreg GPIOx-CRH;for (pinpos 0x00; pinpos 0x08; pinpos){pos (((uint32_t)0x01) (pinpos 0x08));/* Get the port pins position */currentpin ((GPIO_InitStruct-GPIO_Pin) pos);if (currentpin pos){pos pinpos 2;/* Clear the corresponding high control register bits */pinmask ((uint32_t)0x0F) pos;tmpreg ~pinmask;/* Write the mode configuration in the corresponding bits */tmpreg | (currentmode pos);/* Reset the corresponding ODR bit */if (GPIO_InitStruct-GPIO_Mode GPIO_Mode_IPD){GPIOx-BRR (((uint32_t)0x01) (pinpos 0x08));}/* Set the corresponding ODR bit */if (GPIO_InitStruct-GPIO_Mode GPIO_Mode_IPU){GPIOx-BSRR (((uint32_t)0x01) (pinpos 0x08));}}}GPIOx-CRH tmpreg;}
}