历史上的今天
今天是: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位对应的针脚初始化······
史海拾趣
|
想学习一下AD,打算仿真做一个数字电压表,测量0~5V输出0~255,通过数码管显示,AD用的0809,模拟输入采用一个1K滑动变阻器连接到IN0(不知道这种做法是否可行?)现在的问题是,改变滑动变阻器的值,数码管的值有变化,但是并不是有规律地增大或 ...… 查看全部问答> |
|
如何使用 CCS 建一个 M3 的工程,一直在用 MDK,最近不得不熟悉 CCS ,不知道 CCS 要怎么建工程呢? 找到一个 PDF ,按照里边的步骤还是能编译,而且很慢,这样的工具怎么用呢? [ 本帖最后由 Study_Stellaris 于 2011-12-5 16:00 编辑 ]… 查看全部问答> |
|
Altium+Designer+原理图和PCB多通道设计方法介绍 本帖最后由 qq849682862 于 2014-9-10 22:19 编辑 设计原理图和PCB的过程中,你是否遇到过多幅一模一样的电路,但是不得不重复设 计?原理图显得繁复,可读性差。而特别是在设计PCB,不得不重复布局,重复布线,不仅 枯燥乏味而且也容易出错、 ...… 查看全部问答> |
|
本帖最后由 tiankai001 于 2015-1-20 22:29 编辑 EEWORLD下载中心马上要推出开发工具/软件专项栏目了。这个栏目将向大家推荐各种嵌入式系统的开发软件!我们争取给大家提供最全面、最多样的嵌入式系统开发软件! ...… 查看全部问答> |




