yuzhongzhen 发表于 2018-3-30 09:10:58

STM32——GPIO(2)

转载请注明出处:http://blog.csdn.net/wqx521
STM32——GPIO
宗旨:技术的学习是有限的,分享的精神是无限的。

view plain copy



[*]/* GPIO_InitTypeDef结构体 */
[*]typedef enum
[*]{
[*]GPIO_Speed_10MHz = 1,//枚举常量,值为 1,代表输出速率最高为 10MHz
[*]GPIO_Speed_2MHz,       //对不赋值的枚举变量,自动加 1,此常量值为 2
[*]GPIO_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;


view plain copy



[*]/* 初始化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;
[*]      /*判断,若 currentpin=pos,说明 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;
[*]}
[*]}
----------------------------------华丽的分界线-----------------------------北京万邦易嵌科技有限公司:专业提供单片机、M3/M4、linux、Android、QT技术服务、技术培训。详细咨询请加QQ:715493858



页: [1]
查看完整版本: STM32——GPIO(2)