Stm32 库函数 GPIO_Init() 的一些理解

以STM32F103为例,记录一下自己对STM32中GPIO初始化的理解:

 

1 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); 

功能描述: 根据GPIO_InitStruct中指定的参数初始化外设GPIOx寄存器

输入参数1:GPIOx          //GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设

输入参数2:GPIO_InitStruct      //GPIO_InitStruct:指向结构 GPIO_InitTypeDef 的指针,包含了外设 GPIO 的配置信息

                   如:管脚号,速度,模式等(GPIO_Pin,GPIO_Speed,GPIO_Mode)

                                  参阅 Section:GPIO_InitTypeDef 查阅更多该参数允许取值范围

GPIO_Init:有二个参数,均为结构体指针,右键Go To definition :可以查看函数的定义

 

/** 
  * @brief General Purpose I/O
  */

typedef struct
{
  __IO uint32_t CRL;   //端口配置低寄存器
  __IO uint32_t CRH;   //端口配置高寄存器
  __IO uint32_t IDR;   //端口输入数据寄存器
  __IO uint32_t ODR;   //端口输出数据寄存器
  __IO uint32_t BSRR;  //端口位设置/复位寄存器
  __IO uint32_t BRR;   //端口位复位寄存器
  __IO uint32_t LCKR;  //端口配置锁定寄存器
} GPIO_TypeDef;
/** 
  * @brief  GPIO Init structure definition  
  */

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

 

 

 

函数原型如下:

 1 /**
 2   * @brief  Initializes the GPIOx peripheral according to the specified
 3   *         parameters in the GPIO_InitStruct.
 4   * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
 5   * @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
 6   *         contains the configuration information for the specified GPIO peripheral.
 7   * @retval None
 8   */
 9 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
10 {
11   uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
12   uint32_t tmpreg = 0x00, pinmask = 0x00;
13   /* Check the parameters */
14   assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
15   assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));
16   assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));  
17   
18 /*---------------------------- GPIO Mode Configuration -----------------------*/
19   currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
20   if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
21   { 
22     /* Check the parameters */
23     assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
24     /* Output mode */
25     currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
26   }
27 /*---------------------------- GPIO CRL Configuration ------------------------*/
28   /* Configure the eight low port pins */
29   if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
30   {
31     tmpreg = GPIOx->CRL;
32     for (pinpos = 0x00; pinpos < 0x08; pinpos++)
33     {
34       pos = ((uint32_t)0x01) << pinpos;
35       /* Get the port pins position */
36       currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
37       if (currentpin == pos)
38       {
39         pos = pinpos << 2;
40         /* Clear the corresponding low control register bits */
41         pinmask = ((uint32_t)0x0F) << pos;
42         tmpreg &= ~pinmask;
43         /* Write the mode configuration in the corresponding bits */
44         tmpreg |= (currentmode << pos);
45         /* Reset the corresponding ODR bit */
46         if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
47         {
48           GPIOx->BRR = (((uint32_t)0x01) << pinpos);
49         }
50         else
51         {
52           /* Set the corresponding ODR bit */
53           if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
54           {
55             GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
56           }
57         }
58       }
59     }
60     GPIOx->CRL = tmpreg;
61   }

 下面我门以初始化


#define   LED_G_GPIO_PIN       GPIO_Pin_0
#define   LED_G_GPIO_PORT       GPIOB
#define   LED_G_GPIO_CLK        RCC_APB2Periph_GPIOB



void
LED_GPIO_Config(void) {
  /*定义一个 GPIO_InitTypeDef 类型的结构体*/ GPIO_InitTypeDef GPIO_InitStruct;
/*开启 LED 相关的 GPIO 外设时钟*/ RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);
  

    /*选择要控制的 GPIO 引脚*/

     GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;

    /*设置引脚模式为通用推挽输出*/

     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

   /*设置引脚速率为 50MHz*/
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
     /*调用库函数,初始化 GPIO*/
    GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
  
    /*设置初始状态为 SetBits  关闭LED灯(低电平点亮)*/
  GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
    
}

难点就是函数种运用了结构体指针:

下面我们来学习一下C语言中的结构体

 

1. 什么是结构体?

结构体是一种工具,用这个工具可以定义自己的数据类型

2. 结构体与数组的比较

(1) 都由多个元素组成

(2) 各个元素在内存中的存储空间是连续的

(3) 数组中各个元素的数据类型相同,而结构体中的各个元素的数据类型可以不相同

3. 结构体的定义和使用

1>:一般形式

 

struct 结构体名
{
    类型名1 成员名1;
    类型名2 成员名2;
    
    类型名n 成员名n;
};
 
struct student
{
    char name[10];
    char sex;
    int age;
    float score;
};

//student 为结构体类型名

 

2>:定义结构体类型的变量,指针变量和数组

方法一:定义结构体类型时,同时定义该类型的变量

struct [student] /* [ ]表示结构体名是可选的 */
{
    char name[10];
    char sex;
    int age;
    float score;
}stu1, *ps, stu[5]; /* 定义结构体类型的普通变量、指针变量和数组 */

方法二:先定义结构体类型,再定义该类型的变量

struct student
{
    char name[10];
    char sex;
    int age;
    float score;
};
struct student stu1, *ps, stu[5]; /* 定义结构体类型的普通变量、指针变量和数组 */

方法三:用类型定义符typedef先给结构体类型命别名,再用别名定义变量

typedef struct [student]
{
    char name[10];
    char sex;
    int age;
    float score;
}STU;
 
STU stu1, *ps, stu[5]; /* 用别名定义结构体类型的普通变量、指针变量和数组 */

//注释:typedef

3:> 给结构体变量赋初值

struct [student]
{
    char name[10];
    char sex;
    int age;
    float score;
}stu[2]={{"Li"'F'2290.5}, {"Su"'M'2088.5}}; 

4:>引用结构体变量中的成员

1) 结构体变量名. 成员名:      stu1.name

2) 结构体指针变量->成员名:    ps->name

3) (*结构体指针变量). 成员名: (*ps).name

4) 结构体变量数组名. 成员名: stu[0].name

 

先写到这里 下次再补充

 

posted @ 2021-05-06 16:50  H先生H  阅读(2074)  评论(0)    收藏  举报