历史上的今天
返回首页

历史上的今天

今天是:2025年08月05日(星期二)

正在发生

2019年08月05日 | HAL库-STM32F4 HAL_GPIO_Init()

2019-08-05 来源:eefocus

以下使用ST的HAL_GPIO_Init()函数举例。


在ST官方库中,我们可以找到对于某个GPIO初始化的函数 HAL_GPIO_Init()


void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)

{

  uint32_t position;

  uint32_t ioposition = 0x00;

  uint32_t iocurrent = 0x00;

  uint32_t temp = 0x00;

 

  /* Check the parameters */

  assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));

  assert_param(IS_GPIO_PIN(GPIO_Init->Pin));

  assert_param(IS_GPIO_MODE(GPIO_Init->Mode));

  assert_param(IS_GPIO_PULL(GPIO_Init->Pull));

 

  /* Configure the port pins */

  for(position = 0; position < GPIO_NUMBER; position++)

  {

    /* Get the IO position */

    ioposition = ((uint32_t)0x01) << position;

    /* Get the current IO position */

    iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;

 

    if(iocurrent == ioposition)

    {

...



这段代码的主要目的是根据GPIO_InitTypeDef结构体中的Pin来找到对应的要操作的针脚位置

而Pin中储存的值为下列HEX值中的一种或者组合得来


#define GPIO_Pin_0                 ((uint16_t)0x0001)  

#define GPIO_Pin_1                 ((uint16_t)0x0002)  

#define GPIO_Pin_2                 ((uint16_t)0x0004)  

#define GPIO_Pin_3                 ((uint16_t)0x0008)  

#define GPIO_Pin_4                 ((uint16_t)0x0010)  

#define GPIO_Pin_5                 ((uint16_t)0x0020)  

#define GPIO_Pin_6                 ((uint16_t)0x0040)  

#define GPIO_Pin_7                 ((uint16_t)0x0080)  

#define GPIO_Pin_8                 ((uint16_t)0x0100)  

#define GPIO_Pin_9                 ((uint16_t)0x0200) 

#define GPIO_Pin_10                ((uint16_t)0x0400)  

#define GPIO_Pin_11                ((uint16_t)0x0800)  

#define GPIO_Pin_12                ((uint16_t)0x1000)  

#define GPIO_Pin_13                ((uint16_t)0x2000)  

#define GPIO_Pin_14                ((uint16_t)0x4000)  

#define GPIO_Pin_15                ((uint16_t)0x8000)  

#define GPIO_Pin_All               ((uint16_t)0xFFFF)



例如:0x0200 的对应二进制值为 0000 0010 0000 0000 ,从右向左数的第9位(第一位计“0”)被置1。这代表着选择了某个GPIO的第9个针脚 。




那么,为什么要这样一直从第一位枚举到最大位来对比哪个某个针脚被选中,然后进行操作,而不是一开始就直接用位与0x0001然后右移位的方式来直接查找到需要的针脚是哪一个呢?


我们来看一下官方程序的思想:


1.查看第一位是否被选择,如果被选择,进行初始化操作


2.查看第二位是否被选择,如果被选择,进行初始化操作


。。。




到这里不难看出,官方程序的目的是逐个判断传入该函数的GPIO_Init中,Pin值对应的哪些针脚被选择。


这样其实就带来了便利,比如我们要对GPIOA的0、3、5脚使用相同的方法初始化:


如果不使用官方的方法,而是如前所述的先找到从低位开始向高位数的第一个被置1的对应针脚



...

GPIO_InitTypeDef GPIO_InitStructure;

...

GPIO_InitStructure.Pin = GPIO_PIN_0;

HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

...

GPIO_InitStructure.Pin = GPIO_PIN_3;

HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

...

GPIO_InitStructure.Pin = GPIO_PIN_5;

HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

...


而使用官方的方法,我们可以这样

...

GPIO_InitTypeDef GPIO_InitStructure;

...

GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_3 | GPIO_PIN_5;

HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);


参照上文,

GPIO_PIN_0 | GPIO_PIN_3 | GPIO_PIN_5;

则相当于 0000 0000 0010 1001


于是在循环中,程序检测到第0位被选择,于是对第0位对应的针脚初始化。然后检测到第3位被选择,于是对第3位对应的针脚初始化······


推荐阅读

史海拾趣

First Switchtech公司的发展小趣事

为了应对原材料成本上涨和市场竞争加剧的挑战,First Switchtech公司(或类似公司)实施了供应链优化策略。公司通过与上游供应商建立长期合作关系,实现了原材料的稳定供应和成本的有效控制。同时,公司还引入了先进的生产管理系统,提高了生产效率和产品质量。这些措施不仅降低了产品的生产成本,还增强了公司的市场竞争力。

Hitano Enterprise Corp公司的发展小趣事

面对日益激烈的全球竞争,First Switchtech公司(或类似公司)制定了积极的国际化战略。公司首先在欧洲市场设立了分支机构,通过深入了解当地市场需求和文化背景,成功推出了符合欧洲标准的电子开关产品。随后,公司进一步拓展北美、亚洲等市场,通过本地化生产和营销策略,实现了全球市场的覆盖。这一过程中,公司不仅提升了品牌知名度,还积累了丰富的国际市场运营经验。

Applied Engineering Products (AEP)公司的发展小趣事

随着国内市场的饱和,AEP公司开始寻求海外市场的拓展。公司通过与国外知名企业建立合作关系,共同研发新产品,成功打开了国际市场的大门。同时,AEP公司还积极参加国际电子展会和技术交流会,与全球同行交流学习,不断提升自身技术水平。在国际合作的过程中,AEP公司的品牌影响力逐渐增强,成为了电子行业中备受瞩目的企业之一。

协顺电子(Finecables)公司的发展小趣事

经过多年的发展,协顺电子已经成为中国电子连接器行业的领军企业之一。展望未来,公司将继续坚持“以顾客为中心”的经营理念,不断提升产品质量和技术水平;同时,公司也将积极探索新的业务领域和市场机会,推动公司的持续发展。此外,协顺电子还将加强与国际知名企业的合作与交流,共同推动电子行业的发展和进步。

请注意,以上故事框架仅供参考,具体的故事内容需要根据协顺电子(Finecables)公司的实际情况和发展历程进行创作和补充。

High Voltage Semiconductor Inc公司的发展小趣事

为了更好地服务全球客户,美高测积极寻求与国际知名企业的合作。通过与半导体制造巨头台积电、英特尔等公司的合作,美高测不仅获得了先进的制造技术和市场洞察能力,还成功将其高压测试产品打入了这些巨头的供应链体系。同时,公司还与多个国家的科研机构建立了长期合作关系,共同开展前沿技术的研发和应用,进一步提升了公司的国际影响力。

EXCELSEMI [ EXCEL SEMICONDUCTOR INC. ]公司的发展小趣事

为了满足不同客户的需求,EXCELSEMI公司不断扩展产品线。除了传统的半导体芯片产品外,公司还涉足了功率半导体、传感器、智能模块等领域。通过多元化的产品线布局,EXCELSEMI能够为客户提供一站式解决方案,增强了市场竞争力。

问答坊 | AI 解惑

万用表的使用方法

万用表万用表具有用途多,量程广,使用方便等优点,是电子测量中最常用的工具。它可以用来测量电阻,交直流电压和直流电压。有的万用表还可以测量晶体管的主要参数及电容器的电容量等。掌握万用表的使用方是电子技术的一项基本技能。   常见的多 ...…

查看全部问答>

基于AT89S52单片机的LED点阵显示屏控制系统的设计.PDF

基于AT89S52单片机的LED点阵显示屏控制系统的设计.PDF…

查看全部问答>

学习AD0809,所以做一个数字电压表!

想学习一下AD,打算仿真做一个数字电压表,测量0~5V输出0~255,通过数码管显示,AD用的0809,模拟输入采用一个1K滑动变阻器连接到IN0(不知道这种做法是否可行?)现在的问题是,改变滑动变阻器的值,数码管的值有变化,但是并不是有规律地增大或 ...…

查看全部问答>

钱库终端机的界面开发?

目前在广州地铁等安放的钱库终端,里面的界面是用什么来开发的呢?感觉操作挺好听美观的。 是网页?还是Application的胖客户端,还是flash?…

查看全部问答>

如何使用 CCS 建一个 M3 的工程

如何使用 CCS 建一个 M3 的工程,一直在用 MDK,最近不得不熟悉 CCS ,不知道 CCS 要怎么建工程呢? 找到一个 PDF ,按照里边的步骤还是能编译,而且很慢,这样的工具怎么用呢? [ 本帖最后由 Study_Stellaris 于 2011-12-5 16:00 编辑 ]…

查看全部问答>

编译出错

Building configuration: project - Debug Updating build tree... Linking Error[e16]: Segment CSTACK (size: 0x32 align: 0x1) is too long for segment definition. At least 0x19 more bytes needed. The problem occurred while proces ...…

查看全部问答>

如何入手M3

各位大虾,小弟准备开始学习ARM,用TI的流明入手(9B96),板子已买好,求建议。(51和430的基础比较扎实)…

查看全部问答>

Altium+Designer+原理图和PCB多通道设计方法介绍

本帖最后由 qq849682862 于 2014-9-10 22:19 编辑 设计原理图和PCB的过程中,你是否遇到过多幅一模一样的电路,但是不得不重复设 计?原理图显得繁复,可读性差。而特别是在设计PCB,不得不重复布局,重复布线,不仅 枯燥乏味而且也容易出错、 ...…

查看全部问答>

小调查--你所知道的电路设计软件有那些?

本帖最后由 tiankai001 于 2015-1-20 22:29 编辑 EEWORLD下载中心马上要推出开发工具/软件专项栏目了。这个栏目将向大家推荐各种嵌入式系统的开发软件!我们争取给大家提供最全面、最多样的嵌入式系统开发软件!        ...…

查看全部问答>

ADC中的one-shot模式是什么意思?

大家好!看ADC的手册看到one-shot模式,看不大懂究竟是干什么的?没有用过这个功能。。能不能简单描述一下这个模式的功能呢? …

查看全部问答>