stm32中的gpio-凯发旗舰

单片机 > 单片机程序设计 > 详情

stm32中的gpio_init()函数的分析

发布时间:2024-11-11 发布时间:
|

学习stm32时,首先要熟悉流水灯例程,在这里就来分析流水灯中的gpio_init()函数

例如:流水灯例程中使用的端口是macled1_gpio_port=gpiob,

     控制的引脚是gpio_pin_0,

     引脚的模式是 gpio_mode_out_pp(通用推挽输出),

     引脚的速率是gpio_speed_50mhz,

     用到的寄存器是crl

 


将上述的引脚、模式、速率换算成32位的16进制,分别是:

1)  控制的引脚是gpio_pin_0

     换算成32位的16进制是:0x0000 0001

2)  引脚的模式是 gpio_mode_out_pp(通用推挽输出)

     换算成32位的16进制是:0x0000 0010

3)  引脚的速率是gpio_speed_50mhz

     换算成32位的16进制是:0x0000 0003

 


然后调用库函数gpio_init(),初始化gpiob

gpio_init(macled1_gpio_port, &gpio_initstructure);

 


gpio_init()函数的定义如下:

 


  

gpio mode configuration

 

 currentmode=((uint32_t)gpio_initstruct->gpio_mode)&((uint32_t)0x0f);

  可以得出 currentmode=0x0000 0010 & 0x0000 000f

                     =0x0000 0000

 

  if ((((uint32_t)gpio_initstruct->gpio_mode) & ((uint32_t)0x10)) != 0x00)

   判断是否是输出模式,“是”,执行下面代码;“否”,不执行

   如:0x0000 0010 & 0x0000 00010 !=0x 0000 0000

   则执行下面语句

 

  {

    /* output mode */

currentmode |= (uint32_t)gpio_initstruct->gpio_speed;

可以得出currentmode=currentmode | 0x0000 0003=0x0000 0000

                   =0x0000 0003

  }

 

 

gpio crl configuration

 

  if(((uint32_t)gpio_initstruct->gpio_pin&((uint32_t)0x00ff)) != 0x00)

   判断是否是pin0~pin7引脚,“是”,执行下面代码;“否”,不执行

   如:0x0000 0001 & 0x 0000 00ff != 0x0000 0000

   则执行下面语句

 

  {

tmpreg = gpiox->crl;

备份原crl寄存器的值

则是:tmpreg=0x4444 4444

 

for (pinpos = 0x00; pinpos < 0x08; pinpos )

    {

      pos = ((uint32_t)0x01) << pinpos;

         pos是0x0000 0001左移 pinpos 位得到的

         如:pos =0x0000 0001 << 0x00

                = 0x0000 0001

         为后面的  if (currentpin == pos) 判断作准备

 

      /* get the port pins position */

      currentpin = (gpio_initstruct->gpio_pin) & pos;

        可得currentpin = 0x0000 0001 & 0x0000 0001

                      =0x0000 0001

        为后面的  if (currentpin == pos) 判断作准备

 

      if (currentpin == pos)

        由上面得出的pos = 0x0000 0001

                    currentpin = 0x0000 0001

        两者相等,则执行下面代码语句

 

      {

        pos = pinpos << 2;

        可得pos = 0x0000 0000 << 2

                =0x 0000 0000

 

        /* clear the corresponding low control register bits */

        pinmask = ((uint32_t)0x0f) << pos;

        可得pinmask=0x0000 000f << 0x0000 0000

                   = 0x0000 000f

 

        tmpreg &= ~pinmask;

          可得 tmpreg =  tmpreg  & ~pinmask

                     = 0x4444 4444 & 0xffff fff0

                     = 0x4444 4440

 

        /* write the mode configuration in the corresponding bits */

        tmpreg |= (currentmode << pos);

          首先,要知道currentmode << pos = 0x0000 0003 << 0x 0000 0000

                                       = 0x 0000 0003

          可得 tmpreg =  tmpreg  | 0x0000 0003

                     = 0x4444 4440 & 0x0000 0003

                     = 0x4444 4443

 

        /* 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;

把前面处理后的暂存值写入到crl寄存器之中

也就是gpiox->crl = 0x4444 4443

  }

 

 

最终,向gpiob组的crl寄存器写入一个值:

gpiox->crl = 0x4444 4443

转换为二进制是:(0100  0100  0100  0100  0100  0100  0100  0011)b

因此,pin0的控制值为(0011)b

 

 

下面是crl寄存器的说明

 

 

对比一下crl寄存器的说明,pin0的控制值正好可以把gpio设置为符合我们输入参数要求的状态,即最大速率为50mhz的通用推挽输出模式。


关键字:stm32 gpio_init()函数 

『本文转载自网络,凯发旗舰的版权归原作者所有,如有侵权请联系删除』

热门文章 更多
使用ni开发系统和amr系统实现自动化仪表读数系统的设计
网站地图