总 :STM32——学习总纲

参考资料:

STM32F1系列参考手册-V10(中)

一、GPIO简介

1.1 GPIO 特点

 

1.2 GPIO 电气特性*

stm32芯片资料STM32F103ZET6(English)

1.3 GPIO 引脚分布

电源引脚:V开头

晶振引脚:

复位引脚:

下载引脚:通过 串口、JTAG、SWD下载有不同的下载IO

BOOT引脚:

GPIO引脚:p开口

二、IO端口基本结构

F1与F3、F7、H7的差异点在于上下拉电阻的位置。

F1的IO做为输入禁止使用上下拉电阻,这是由硬件决定的。

额外补充:

模电学习——场效应管(FET)

记忆:箭头方向就是电子流动方向。想要mos管导通,需要 gs 压差满足 箭头方向上的电子流通。

三、GPIO的八种模式(F1)

前置

STM32F1系列参考手册-V10(中)

3.1 输入浮空

特点:

3.2 输入上拉

特点:

弱上拉

3.3 输入下拉

特点:

3.4 模拟功能

特点:

输入只走模拟输入

3.5 开漏输出

寄存器介绍参考前置

特点:

开漏模式下,寄存器写0,NMOS管导通,此时IO口呈低电平↓

开漏模式下,寄存器写1,P、N mos管皆不导通,此时IO口为高阻态,F1系列想要输出高电平,需要外部的上拉电阻。

3.6 开漏复用

特点:

不由寄存器控制,由片上外设控制输出 

3.7 推挽输出

寄存器介绍参考前置

特点:

可控制 P/N MOS管的反向导通,控制 IO 口输出高低电平。

3.8 推挽复用 

特点:

不由寄存器控制,由片上外设控制输出

3.* F4/F7/H7 系列和 F1 系列的 GPIO 差异点

四、GPIO寄存器(F1)

STM32F1系列参考手册-V10(中)

“GPIOx_” 中的 ‘x’ 代表A~E组别,每个组有以下七个寄存器

4.1 端口配置 高、低 寄存器(Configuration Register Low/High)

此俩寄存器用于配置 IO 口的 工作模式和输出速度。

一组 IO 有16个,高、低寄存器每四个bit(CNFy、MODEy)配置一个IO,两个寄存器64bit,共配置16个IO。

当配置 bit 0b1000, 按配置是 上拉/下拉 输入模式,但不能确定上拉还是下拉,还需要ODR寄存器进行设置。

具体CR配置如下截图。

GPIOx_CRL

GPIOx_CRH

4.2 端口输出数据寄存器(Out Data Register)

GPIOx_ODR

16个 bit 对应16个IO。用于设置IO引脚输出时的高低电平。

还可通过此寄存器配置上拉/下拉输入配置。

4.3 端口输入数据寄存器(Input Data Register)

GPIOx_IDR

只读,读取对应 IO 的状态,用于判断引脚电平。

4.4 端口位设置/清除寄存器(Bit Set Reset Register)

GPIOx_BSRR

高16bit,写 1 清除ODR寄存器对应bit为0,写0无影响。

低16bit,写 1 清除ODR寄存器对应bit为1,写0无影响。

此寄存器用于控制 ODR寄存器

4.5 不建议使用的寄存器

    GPIOx_BRR

    GPIOx_LCKR

4.6 ODR 与 BSRR*

类似C中 volatile关键词,从原始地址获取值,以防缓存值与原始值不一致。

五、通用外设驱动模型(四步法)

六、GPIO配置步骤

GPIO配置 属于 通用外设驱动模型四步法的前三步。

 

相关库函数

源码分析

__HAL_RCC_GPIOA_CLK_ENABLE()  

stm32f1xx_hal_rcc.h

使用宏定义控制寄存器IO端口A时钟使能。 APB2ENR |=  (1 << 2)

HAL_GPIO_Init

通过结构体中的 @ref 查找HAL库定义好的宏参数,例如 @ref GPIO_pins_define 。

/**
  * @brief GPIO Init structure definition
  */
typedef struct
{
  uint32_t Pin;       /*!< Specifies the GPIO pins to be configured.
                           This parameter can be any value of @ref GPIO_pins_define */

  uint32_t Mode;      /*!< Specifies the operating mode for the selected pins.
                           This parameter can be a value of @ref GPIO_mode_define */

  uint32_t Pull;      /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                           This parameter can be a value of @ref GPIO_pull_define */

  uint32_t Speed;     /*!< Specifies the speed for the selected pins.
                           This parameter can be a value of @ref GPIO_speed_define */
} GPIO_InitTypeDef;


/** 
  * @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  Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
  * @param  GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
  * @param  GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
  *         the configuration information for the specified GPIO peripheral.
  * @retval None
  */
void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init);

寄存器基地址:

#define GPIOA               ((GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB               ((GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC               ((GPIO_TypeDef *)GPIOC_BASE)
#define GPIOD               ((GPIO_TypeDef *)GPIOD_BASE)
#define GPIOE               ((GPIO_TypeDef *)GPIOE_BASE)
#define GPIOF               ((GPIO_TypeDef *)GPIOF_BASE)
#define GPIOG               ((GPIO_TypeDef *)GPIOG_BASE)
/** @defgroup GPIO_pins_define GPIO pins define
  * @{
  */
#define GPIO_PIN_0                 ((uint16_t)0x0001)  /* Pin 0 selected    */
#define GPIO_PIN_1                 ((uint16_t)0x0002)  /* Pin 1 selected    */
#define GPIO_PIN_2                 ((uint16_t)0x0004)  /* Pin 2 selected    */
#define GPIO_PIN_3                 ((uint16_t)0x0008)  /* Pin 3 selected    */
#define GPIO_PIN_4                 ((uint16_t)0x0010)  /* Pin 4 selected    */
#define GPIO_PIN_5                 ((uint16_t)0x0020)  /* Pin 5 selected    */
#define GPIO_PIN_6                 ((uint16_t)0x0040)  /* Pin 6 selected    */
#define GPIO_PIN_7                 ((uint16_t)0x0080)  /* Pin 7 selected    */
#define GPIO_PIN_8                 ((uint16_t)0x0100)  /* Pin 8 selected    */
#define GPIO_PIN_9                 ((uint16_t)0x0200)  /* Pin 9 selected    */
#define GPIO_PIN_10                ((uint16_t)0x0400)  /* Pin 10 selected   */
#define GPIO_PIN_11                ((uint16_t)0x0800)  /* Pin 11 selected   */
#define GPIO_PIN_12                ((uint16_t)0x1000)  /* Pin 12 selected   */
#define GPIO_PIN_13                ((uint16_t)0x2000)  /* Pin 13 selected   */
#define GPIO_PIN_14                ((uint16_t)0x4000)  /* Pin 14 selected   */
#define GPIO_PIN_15                ((uint16_t)0x8000)  /* Pin 15 selected   */
#define GPIO_PIN_All               ((uint16_t)0xFFFF)  /* All pins selected */
/** @defgroup GPIO_mode_define GPIO mode define
  * @brief GPIO Configuration Mode
  *        Elements values convention: 0xX0yz00YZ
  *           - X  : GPIO mode or EXTI Mode
  *           - y  : External IT or Event trigger detection
  *           - z  : IO configuration on External IT or Event
  *           - Y  : Output type (Push Pull or Open Drain)
  *           - Z  : IO Direction mode (Input, Output, Alternate or Analog)
  * @{
  */
#define  GPIO_MODE_INPUT                        0x00000000u   /*!< Input Floating Mode                   */
#define  GPIO_MODE_OUTPUT_PP                    0x00000001u   /*!< Output Push Pull Mode                 */
#define  GPIO_MODE_OUTPUT_OD                    0x00000011u   /*!< Output Open Drain Mode                */
#define  GPIO_MODE_AF_PP                        0x00000002u   /*!< Alternate Function Push Pull Mode     */
#define  GPIO_MODE_AF_OD                        0x00000012u   /*!< Alternate Function Open Drain Mode    */
#define  GPIO_MODE_AF_INPUT                     GPIO_MODE_INPUT          /*!< Alternate Function Input Mode         */

#define  GPIO_MODE_ANALOG                       0x00000003u   /*!< Analog Mode  */

#define  GPIO_MODE_IT_RISING                    0x10110000u   /*!< External Interrupt Mode with Rising edge trigger detection          */
#define  GPIO_MODE_IT_FALLING                   0x10210000u   /*!< External Interrupt Mode with Falling edge trigger detection         */
#define  GPIO_MODE_IT_RISING_FALLING            0x10310000u   /*!< External Interrupt Mode with Rising/Falling edge trigger detection  */

#define  GPIO_MODE_EVT_RISING                   0x10120000u   /*!< External Event Mode with Rising edge trigger detection               */
#define  GPIO_MODE_EVT_FALLING                  0x10220000u   /*!< External Event Mode with Falling edge trigger detection              */
#define  GPIO_MODE_EVT_RISING_FALLING           0x10320000u   /*!< External Event Mode with Rising/Falling edge trigger detection       */
/** @defgroup GPIO_pull_define GPIO pull define
  * @brief GPIO Pull-Up or Pull-Down Activation
  * @{
  */
#define  GPIO_NOPULL        0x00000000u   /*!< No Pull-up or Pull-down activation  */
#define  GPIO_PULLUP        0x00000001u   /*!< Pull-up activation                  */
#define  GPIO_PULLDOWN      0x00000002u   /*!< Pull-down activation                */
/** @defgroup GPIO_speed_define  GPIO speed define
  * @brief GPIO Output Maximum frequency
  * @{
  */
#define  GPIO_SPEED_FREQ_LOW              (GPIO_CRL_MODE0_1) /*!< 2MHz  Low speed */
#define  GPIO_SPEED_FREQ_MEDIUM           (GPIO_CRL_MODE0_0) /*!< 10MHz Medium speed */
#define  GPIO_SPEED_FREQ_HIGH             (GPIO_CRL_MODE0)   /*!< 50MHz High speed */

HAL_GPIO_WritePin

/**
  * @brief  Sets or clears the selected data port bit.
  *
  * @note   This function uses GPIOx_BSRR register to allow atomic read/modify
  *         accesses. In this way, there is no risk of an IRQ occurring between
  *         the read and the modify access.
  *
  * @param  GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
  * @param  GPIO_Pin: specifies the port bit to be written.
  *          This parameter can be one of GPIO_PIN_x where x can be (0..15).
  * @param  PinState: specifies the value to be written to the selected bit.
  *          This parameter can be one of the GPIO_PinState enum values:
  *            @arg GPIO_PIN_RESET: to clear the port pin
  *            @arg GPIO_PIN_SET: to set the port pin
  * @retval None
  */
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
/**
  * @brief  GPIO Bit SET and Bit RESET enumeration
  */
typedef enum
{
  GPIO_PIN_RESET = 0u,
  GPIO_PIN_SET
} GPIO_PinState;

HAL_GPIO_TogglePin

/**
  * @brief  Toggles the specified GPIO pin
  * @param  GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
  * @param  GPIO_Pin: Specifies the pins to be toggled.
  * @retval None
  */
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);

HAL_GPIO_ReadPin

/**
  * @brief  Reads the specified input port pin.
  * @param  GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
  * @param  GPIO_Pin: specifies the port bit to read.
  *         This parameter can be GPIO_PIN_x where x can be (0..15).
  * @retval The input port pin value.
  */
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);

七、编程实战

 7.1 点亮一个LED && LED亮灭控制

LED 链接原理图

此原理图可用推挽输出,开漏输出控制,开漏输出是能输出低电平,以及一个高阻态特性,在此情景中符合发光二极管控制原理。

 

7.1.1 工程新建

1.新建BSP板级支持包文件夹

2.代码编写

#ifndef _LED_H
#define _LED_H
#include "./SYSTEM/sys/sys.h"


void led_init(void); 

#endif
#include "./BSP/LED/led.h"


void led_init(void)
{
	GPIO_InitTypeDef gpio_init_struct;
	
	gpio_init_struct.Pin = GPIO_PIN_5;
	gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
	gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
	
	__HAL_RCC_GPIOB_CLK_ENABLE();
	HAL_GPIO_Init(GPIOB, &gpio_init_struct); /* PB5 pullpush low */
	
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);

}
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"


int main(void)
{
    HAL_Init();                                 /* ³õʼ»¯HAL¿â */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* ÉèÖÃʱÖÓ,72M */
    delay_init(72);                             /* ³õʼ»¯ÑÓʱº¯Êý */
    led_init();                                 /* ³õʼ»¯LED */
    
    while(1)
    {
			/*write pin control*/
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);                              /* LED1 Ãð */
			delay_ms(500);
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
			delay_ms(500);

			/*Toggle pin control*/
			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
			delay_ms(200);
    }
}

7.2 通过KEY来控制LED亮灭

按键通常会有抖动,需要  软件去抖获取 KEY 的状态,一般是5~10ms。

按键原理图

 PA0配置输入下拉,PE2.3.4配置输入上拉。获取两种状态。

#ifndef __KEY_H
#define __KEY_H

#include "./SYSTEM/sys/sys.h"


void key_init(void);
uint8_t key_scan(void);

#endif
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"


/* °´¼ü³õʼ»¯º¯Êý */
void key_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    
    __HAL_RCC_GPIOE_CLK_ENABLE();
    
    gpio_init_struct.Pin = GPIO_PIN_2;
    gpio_init_struct.Mode = GPIO_MODE_INPUT;
    gpio_init_struct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOE, &gpio_init_struct);
}

/* °´¼üɨÃ躯Êý */
uint8_t key_scan(void)
{
    if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == 0)
    {
        delay_ms(10);   /* Ïû¶¶ */
        if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == 0)
        {
            while(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == 0);  /* µÈ´ý°´¼üËÉ¿ª */
            return 1;   /* °´¼ü°´ÏÂÁË */
        }
    }
    return 0;   /* °´¼üûÓа´Ï */
}
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"


int main(void)
{
    HAL_Init();                         /* ³õʼ»¯HAL¿â */
    sys_stm32_clock_init(RCC_PLL_MUL9); /* ÉèÖÃʱÖÓ, 72Mhz */
    delay_init(72);                     /* ÑÓʱ³õʼ»¯ */
    led_init();                         /* LED³õʼ»¯ */
    key_init();                         /* KEY³õʼ»¯ */
    while(1)
    {
        if(key_scan())
        {
            HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
        }
        else
        {
            delay_ms(10);
        }
    }
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐