历史上的今天
返回首页

历史上的今天

今天是:2024年12月09日(星期一)

正在发生

2020年12月09日 | STM32——GPIO(2)

2020-12-09 来源:eefocus


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

/* 初始化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;

  }

}


推荐阅读

史海拾趣

启珑(CHIPLON)公司的发展小趣事

一次性生成5个关于启珑(CHIPLON)公司在电子行业发展起来的相关故事可能内容过多,我可以先为您提供1个相关故事作为示例,如您满意,我可以继续提供。

启珑微电子推出创新DSP系列

近年来,随着数字技术的飞速发展,电子行业对高性能处理器的需求日益增长。在这一背景下,启珑微电子(CHIPLON)凭借其深厚的技术积累和敏锐的市场洞察力,成功推出了全新的CLM320F28335系列DSP(数字信号处理器)。

这款产品一经发布,就引起了行业内的广泛关注。CLM320F28335系列DSP以其高效的32位RISC-V CPU内核、高精度、低成本、低功耗、高性能以及外设集成度高等特点,迅速在市场中占据了一席之地。与传统的定点DSP相比,这款产品的优势显而易见,尤其是在数据处理和A/D转换方面表现更为出色。

值得一提的是,CLM320F28335系列DSP拥有150MHz的高速处理能力,并配备了32位浮点处理单元,这使其在处理复杂算法和大量数据时能够游刃有余。同时,它还具备6个DMA通道,支持ADC、McBSP和EMIF,以及多达18路的PWM输出,其中有6路为高精度PWM输出(HRPWM),这些特性使其在工业自动化、电机控制等领域具有广泛应用前景。

该产品设计的另一个亮点是,它能够直接PIN对PIN替代国际同类产品,这意味着用户在使用启珑的DSP时,无需更改原有的电路板设计或系统软件,即可实现完全的替代兼容,这一设计无疑大大降低了用户的替换成本和使用难度。

随着CLM320F28335系列DSP的成功推出,启珑微电子在电子行业的地位得到了进一步提升。这一产品的成功,不仅展示了启珑微电子强大的研发实力,也为其在激烈的市场竞争中赢得了更多的市场份额。

若您想要探索更多内容,随时可以继续输入。

冠西电子(COSMO)公司的发展小趣事

近年来,冠西电子积极布局全球市场,设立了多个分公司和办事处,以便更好地服务全球客户。同时,冠西电子还不断关注新兴技术和市场需求的变化,积极寻求新的发展机遇。展望未来,冠西电子将继续秉承“专业、创新、品质、服务”的理念,不断推动公司业务的发展和进步。

以上五个故事概要涵盖了冠西电子(COSMO)公司从创立到发展的主要阶段和事实。每个阶段都体现了冠西电子在技术、市场、品质、品牌等方面的努力和成就。

Anpec(茂达)公司的发展小趣事

为了适应全球化的市场趋势,茂达电子制定了全面的全球化战略。公司不仅加强了与国际市场的联系,还积极寻求与国际知名企业的合作机会。同时,茂达电子还加大了对海外市场的投入,通过设立海外分支机构、参加国际展会等方式,不断提升品牌知名度和市场影响力。

这五个故事只是Anpec(茂达电子)发展历程中的一部分,但它们充分展示了茂达电子在电子行业中的崛起和成就。作为一家具有创新精神和市场洞察力的企业,茂达电子将继续致力于为客户提供优质的产品和服务,推动电子行业的持续发展。

川晶科技公司的发展小趣事

川晶科技注重团队建设和人才培养。公司建立了完善的培训体系和发展机制,为员工提供丰富的培训机会和广阔的发展空间。通过引进高素质的人才和内部培养相结合的方式,川晶科技打造了一支高素质、专业化的团队。团队成员之间团结协作、互相支持,共同推动公司的持续成长和发展。同时,公司还建立了良好的激励机制和企业文化氛围,激发员工的工作积极性和创造力。

ABCO公司的发展小趣事

ABCO公司初创时,电子市场竞争激烈,众多企业争夺市场份额。面对这样的环境,ABCO公司创始人凭借对电子技术的深刻理解,以及敏锐的市场洞察力,选择了专注于某一细分领域——高精度传感器的研发与生产。通过不断优化产品设计,提升产品性能,ABCO公司的传感器逐渐在市场上获得认可,为公司的起步奠定了坚实基础。

GigPeak公司的发展小趣事

随着业务的不断扩展,GigPeak意识到国际化战略的重要性。在2015年,公司开始积极布局海外市场,先后在北美、欧洲和亚洲等地设立了研发中心和销售分支机构。通过深入了解当地市场需求和文化背景,GigPeak成功推出了一系列符合当地市场需求的定制化产品。这些举措不仅提升了GigPeak在全球市场的知名度和影响力,还为其带来了稳定的海外收入来源。

问答坊 | AI 解惑

如下代码为什么不能实现动态扫描

#include #include unsigned char LED_CODE[]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f}; void delay(void) { int k;   for(k=0;k…

查看全部问答>

求助:WINCE系统运行后,如何保存个人修改的设置?

WINCE系统起来之后,修改一些配置,比如换个桌面背景,调整背光时间等,掉电之后重新启动又回到没有修改的状态。 如何实现掉电之后能够保存好修改的设置,在上电启动后这些设置还存在??? 希望各位大侠们能够赐教!!!…

查看全部问答>

单片机音乐播放中歌曲的代码

单片机音乐播放中歌曲的代码怎样弄出来的? 我看了网上的一些教程。。一个个的算很麻烦。。而且我对音乐不熟悉。 这样效率很低。。有没有一些快点的方法? 先在这里谢了~…

查看全部问答>

新手请问如何显示对话框

我建了一个win32 application的工程,然后加了一个对话框资源,在对话框上又加了一个按钮,然后编译和模拟,发现对话框没有在屏幕上显示出来,请问怎样才能把对话框显示出来呢? …

查看全部问答>

我在wince中用

我在wince中用SendMessage(m_hCtlHtml, DTM_NAVIGATE, \"file://\\\\files\\\\a.htm\")方法显示了一个网页,但是其中的链接都不能点击,这是为什么?求大家帮帮我!谢谢~…

查看全部问答>

扩展串口芯片16550中断问题

请教各位:     我的串口芯片16550用了外部中断EINT3     在注册表中:我需要加     \"SysIntr\"=dword:3      串口4的中断为EINT3     \"MeMBase\"=dword:0x20000000  &nbs ...…

查看全部问答>

来长沙参加飞思卡尔智能车竞赛第四天。。。。

补上的,因为刚把相关的视频,相片都拷过来,而且整理了大半天,呵呵~ 希望大家谅解~ 我们是属于华南赛区的,7月23号决赛,也就是我来长沙的第四天~ 决赛是按进入决赛的队伍在预赛时的成绩排名,倒序跑的。 首先进行的是电磁组的,接着是 ...…

查看全部问答>

如何消除用三角波调制正弦波后产生的方波的过冲

本人做三角波调制正弦波时候,产生的调制信号的方波在上升沿和下降沿都有过冲现象,如何消除?…

查看全部问答>

DIY一个遥控电源插座

最近想DIY一个遥控电源插座,希望大家给个建议:收集了一些资料,但感觉不太满意,如下:PH303A×2红外脉冲发射电路如下图所示,调节RP1,使其振荡频率为12kHz.红外遥控接收电路:…

查看全部问答>