目录

常用的就是这几个:
1 初始化端口
5 读取端口的输出数据
7,8 给端口写1,0
14 选择中断线

——————————————————————————————————————

位带操作可以参考这篇文章
https://blog.csdn.net/oshan2012/article/details/95938302

———————————————————————————————————————

1.GPIO设置函数(端口号,对端口的设置)

/*** @brief  Initializes the GPIOx peripheral according to the specified*         parameters in the GPIO_InitStruct.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that*         contains the configuration information for the specified GPIO peripheral.* @retval None*/
假设使用a口
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;/* Check the parameters */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 Mode Configuration -----------------------*/currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);//这个大有玄机/*
typedef enum
{ GPIO_Mode_AIN = 0x0,GPIO_Mode_IN_FLOATING = 0x04,//0100GPIO_Mode_IPD = 0x28, //1000GPIO_Mode_IPU = 0x48,GPIO_Mode_Out_OD = 0x14,//0100GPIO_Mode_Out_PP = 0x10,GPIO_Mode_AF_OD = 0x1C,//1100GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;
这便是GPIOmode里边的东西。我们可以发现,他所有的参数最低两位都是0.这里记住,后边要考
而且高4位的最低位,也就是左边的数字是0x1*开头的都是输出模式,比如0x14。开头不是0x1的就是输入模式。4输入4输出。
所以上边那句0x0f与他的低位,就是把判断输入还是输出剔除了。就留下低四位,用来判断她是哪种类型的。
*/if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)//这句话判断的是她是否是输出模式。因为输出模式是0x1*。{ /* Check the parameters */assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));/* Output mode */currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
/*typedef enum
{ GPIO_Speed_10MHz = 1,GPIO_Speed_2MHz, GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
分别是1,2,3.枚举类型。也就是0001,0010,0011
上面说到,GPIOmode的最低两位都是0,所以
currentmode 或上这三个 ,不会影响*/}
/*---------------------------- GPIO CRL Configuration ------------------------*//* Configure the eight low port pins */if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)//低8位{tmpreg = GPIOx->CRL;/*这些就是每个引脚的定义。GPIOA叫端口port,pin0叫引脚。每个端口16个引脚
#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */
*/for (pinpos = 0x00; pinpos < 0x08; pinpos++)//8个引脚{pos = ((uint32_t)0x01) << pinpos;//选择对应的引脚 第2次0x01 ,0001 左移1位,0010/* Get the port pins position *///pinpos = 0x01 ; pos  = 0x02; currentpin  = 0010currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;//再次确认if (currentpin == pos){pos = pinpos << 2;//0100,4/* Clear the corresponding low control register bits */pinmask = ((uint32_t)0x0F) << pos;//11110000tmpreg &= ~pinmask; //GPIOx->CRL;//00001111/* Write the mode configuration in the corresponding bits */tmpreg |= (currentmode << pos);//0010<<4=0010 0000/* Reset the corresponding ODR bit */if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD){GPIOx->BRR = (((uint32_t)0x01) << pinpos);}else{/* Set the corresponding ODR bit */if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU){GPIOx->BSRR = (((uint32_t)0x01) << pinpos);}}}}GPIOx->CRL = tmpreg;}
/*---------------------------- GPIO CRH Configuration ------------------------*//* 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;}
}

都注释在里边了。


2.GPIO初始化结构体函数()

把对端口的设置结构体初始化。比如GPIO_Pin_All,就是全置一,让人一看就知道,这是初始化完的。

/*** @brief  Fills each GPIO_InitStruct member with its default value.* @param  GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will*         be initialized.* @retval None*/
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
{/* Reset GPIO init structure parameters values */GPIO_InitStruct->GPIO_Pin  = GPIO_Pin_All;GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING;
}

——————————————————————————————————

3.读取某个端口的某个引脚的输入值(端口,引脚)

/*** @brief  Reads the specified input port pin.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  GPIO_Pin:  specifies the port bit to read.*   This parameter can be GPIO_Pin_x where x can be (0..15).* @retval The input port pin value.*/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{uint8_t bitstatus = 0x00;/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)//为什么这样判断呢?因为gpio_pin的定义是0x0001,0x0002,0x0004,0x0008这种样子定义的//所以idr与对应的引脚后,要判断1在哪一位很复杂,不如直接判断是不是不等于0,只要不等于0,那就说明//这一位肯定是1.非常巧妙{bitstatus = (uint8_t)Bit_SET;}else{bitstatus = (uint8_t)Bit_RESET;}return bitstatus;
}

—————————————————————————

4.读取某个端口的所有引脚输入数据

对应的IDR寄存器是只读的。


/*** @brief  Reads the specified GPIO input data port.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @retval GPIO input data port value.*/
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
{/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));return ((uint16_t)GPIOx->IDR);
}

——————————————————

5.读取某个端口的某个引脚的输出数据

ODR寄存器是可读可写的。所以读取方法和上边一样

/*** @brief  Reads the specified output data port bit.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  GPIO_Pin:  specifies the port bit to read.*   This parameter can be GPIO_Pin_x where x can be (0..15).* @retval The output port pin value.*/
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{uint8_t bitstatus = 0x00;/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GET_GPIO_PIN(GPIO_Pin)); if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET){bitstatus = (uint8_t)Bit_SET;}else{bitstatus = (uint8_t)Bit_RESET;}return bitstatus;
}

————————————————————————————

6.读取某个端口的所有引脚输出数据

和上边输入是一样的

/*** @brief  Reads the specified GPIO output data port.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @retval GPIO output data port value.*/
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
{/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));return ((uint16_t)GPIOx->ODR);
}

——————————————————————————————

7.给某个端口的某个引脚写1

/*** @brief  Sets the selected data port bits.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  GPIO_Pin: specifies the port bits to be written.*   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).* @retval None*/
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GPIO_PIN(GPIO_Pin));GPIOx->BSRR = GPIO_Pin;
}

——————————————————————————

8.给某个端口的某个引脚写0

BSRR可1可0
BRR只能置0


/*** @brief  Clears the selected data port bits.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  GPIO_Pin: specifies the port bits to be written.*   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).* @retval None*/
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GPIO_PIN(GPIO_Pin));GPIOx->BRR = GPIO_Pin;
}

——————————————————————

9.既可以给某个引脚写1,又可以写0

评语:脱裤子放屁——多此一举


/*** @brief  Sets or clears the selected data port bit.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  GPIO_Pin: specifies the port bit to be written.*   This parameter can be one of GPIO_Pin_x where x can be (0..15).* @param  BitVal: specifies the value to be written to the selected bit.*   This parameter can be one of the BitAction enum values:*     @arg Bit_RESET: to clear the port pin*     @arg Bit_SET: to set the port pin* @retval None*/
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
{/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GET_GPIO_PIN(GPIO_Pin));assert_param(IS_GPIO_BIT_ACTION(BitVal)); if (BitVal != Bit_RESET){GPIOx->BSRR = GPIO_Pin;}else{GPIOx->BRR = GPIO_Pin;}
}

————————————————————————

10.直接给整个端口写


/*** @brief  Writes data to the specified GPIO data port.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  PortVal: specifies the value to be written to the port output data register.* @retval None*/
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
{/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));GPIOx->ODR = PortVal;
}

——————————————————————————————————————————————

11.锁定端口的配置

每个位对应CRH或CRL中的4个位。因为CRL、H中每4个位配置一个引脚


/*** @brief  Locks GPIO Pins configuration registers.* @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.* @param  GPIO_Pin: specifies the port bit to be written.*   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).* @retval None*/
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{uint32_t tmp = 0x00010000;/* Check the parameters */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GPIO_PIN(GPIO_Pin));tmp |= GPIO_Pin;/* Set LCKK bit */GPIOx->LCKR = tmp;/* Reset LCKK bit */GPIOx->LCKR =  GPIO_Pin;/* Set LCKK bit */GPIOx->LCKR = tmp;/* Read LCKK bit*/tmp = GPIOx->LCKR;/* Read LCKK bit*/tmp = GPIOx->LCKR;
}

很简单要锁哪个就用哪个pin
但是16位置一,或上pin口,得到一个变量
不停操作这个变量和pin口来达到图中锁定配置需要的时序

——————————————————————————

12.选择用作事件输出的GPIO引脚


/*** @brief  Selects the GPIO pin used as Event output.* @param  GPIO_PortSource: selects the GPIO port to be used as source*   for Event output.*   This parameter can be GPIO_PortSourceGPIOx where x can be (A..E).* @param  GPIO_PinSource: specifies the pin for the Event output.*   This parameter can be GPIO_PinSourcex where x can be (0..15).* @retval None*/
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{uint32_t tmpreg = 0x00;/* Check the parameters */assert_param(IS_GPIO_EVENTOUT_PORT_SOURCE(GPIO_PortSource));assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));tmpreg = AFIO->EVCR;/* Clear the PORT[6:4] and PIN[3:0] bits */tmpreg &= EVCR_PORTPINCONFIG_MASK;tmpreg |= (uint32_t)GPIO_PortSource << 0x04;tmpreg |= GPIO_PinSource;AFIO->EVCR = tmpreg;
}

就是这个寄存器

————————————————————————————————

13.启用或禁用事件输出


/*** @brief  Enables or disables the Event Output.* @param  NewState: new state of the Event output.*   This parameter can be: ENABLE or DISABLE.* @retval None*/
void GPIO_EventOutputCmd(FunctionalState NewState)
{/* Check the parameters */assert_param(IS_FUNCTIONAL_STATE(NewState));*(__IO uint32_t *) EVCR_EVOE_BB = (uint32_t)NewState;
}

位带操作,控制这1位
置一后事件就会指导设置好的pin口上

——————————————————————————————

14.选择用作外部中断线的GPIO引脚


/*** @brief  Selects the GPIO pin used as EXTI Line.* @param  GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.*   This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).* @param  GPIO_PinSource: specifies the EXTI line to be configured.*   This parameter can be GPIO_PinSourcex where x can be (0..15).* @retval None*/
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{uint32_t tmp = 0x00;/* Check the parameters */assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
}

STM32从零开始(四)详解GPIO库函数相关推荐

  1. STM32启动文件详解-比较清晰的一篇

    STM32启动文件详解 启动文件使用的 ARM 汇编指令汇总 启动程序源码注释(点此下载) 1. Stack-栈 Stack_Size EQU 0x00000400AREA STACK, NOINIT ...

  2. STM32 CAN通信协议详解—小白入门(二)

    文章目录 (一)CAN通信协议简介 (二)CAN物理层 2.1.闭环总线网络2.2.开环总线网络2.3.通信节点2.4.差分信号2.5.CAN协议的差分信号 (三)协议层 3.1.CAN的波特率及位同 ...

  3. STM32串口通信详解以及通信异常或者卡死常见问题分析

    STM32串口通信详解以及通信异常或者卡死常见问题分析 目录 STM32串口通信详解以及通信异常或者卡死常见问题分析 一.常见的异常问题 二.STM32的串口简介 1.串口的通讯方式 ①按数据传输方向 ...

  4. stm32 DMA使用详解

    转自:http://www.cnblogs.com/121792730applllo/p/3154447.html STM32 DMA使用详解 DMA部分我用到的相对简单,当然,可能这是新东西,我暂时 ...

  5. STM32 HAL库详解 及 手动移植

    源: STM32 HAL库详解 及 手动移植

  6. STM32最小系统详解

    STM32最小系统详解 1. 电源电路 2. 晶振电路 3. 复位电路 4. 下载电路(串口下载) 本文章将以普中的STM32F103系列的开发板为载体,任何一款STM32开发板都是在其最小系统基础上 ...

  7. STM32的定时器详解(嵌入式学习)

    STM32的定时器详解 0. 前言 1. Systick定时器 概念 工作原理 时钟基准 Systick练习 2. HAL_Delay函数分析 3. 定时器 基本概念 定时器分类 定时器组成 计数器 ...

  8. STM32 HAL库详解

    STM32 HAL库整体总结 STM32 之二 HAL库详解 及 手动移植 本篇博客是对以上参考资源的一个二次总结与整理. 1. HAL库文件结构 对于开发人员而言,首先要清楚 HAL 库的文件结构. ...

  9. STM32开发 -- 串口详解

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/80708964 讲完GPIO,接下来看一下串口. 串口通信,已经讲了很多次了. ...

最新文章

  1. MongoDB数据库(一:基本操作)
  2. [转]构建基于WCF Restful Service的服务
  3. 7、计算机图形学——图形管线渲染与纹理映射
  4. MaxCompute Next
  5. u大师u盘装系统win7_优盘如何装系统 u盘装系统的步骤
  6. 使用maven导入任意jar包
  7. 55种数据可视化开源工具_8种出色的开源数据可视化工具
  8. fastjson 判断value是对象还是数组
  9. understanding the Euler Lagrange equation
  10. VC之CString,wchar_t,int,string,char*之间的转换
  11. MFC中获取各种类指针的方法 (转)
  12. 在 RAID 磁盘上面架构 LVM 系统
  13. 项目汇报模板—再也不怕撕逼了
  14. 图灵计算机模型意义,图灵机有什么意义_学习图灵机模型中遇到的问题 - 人工智能 - 电子发烧友网...
  15. 华为手机隐藏指令的5个代码
  16. 彻底关闭win10的自动更新
  17. openwrt源码下载地址及下载失败问题
  18. @Zabbix报表系统ZbxTable
  19. Eclipse4.6(neno)配置Tomcat插件的两种方式
  20. 红烧茄子做法--小黄讲解

热门文章

  1. 解决latex图片浮动体过多的报错:Output loop---100 consecutive dead cycles和Too many unprocessed floats
  2. Android内核模式下对当前进程的cred结构的获取方式
  3. 《PHP程序员面试笔试宝典》——如何克服面试中紧张的情绪?
  4. 按了锁定计算机怎么办,笔记本电脑键盘锁定了怎么办有什么方法解锁
  5. 医疗大数据的发展现状与应用
  6. oracle ebs 请求 待定,EBS 并发请求 计划 fnd_conc_release_classes(示例代码)
  7. 怎么重置windows7系统网络设置使用cmd命令行实现
  8. 《谁动了我的奶酪》书评
  9. 见缝插针小游戏制作详细步骤
  10. 什么软件可以给视频加字幕?这些软件值得收藏