STM32学习2:使用库函数控制GPIO输出

STM32 学习2 库函数控制GPIO输出

  • 一、GPIO寄存器介绍
  • 1. GPIO简介
  • 2. GPIO功能
  • (1)模式分类
  • (2)模式设置方法
  • MODE[1:0]:模式控制,用于配置端口引脚的模式:
  • CNF[1:0]:配置引脚输出速度:
  • PUPD[1:0]:上拉/下拉配置:
  • (3)**输入模式**:
  • (4)**输出模式**:
  • 3. GPIO的寄存器
  • (1)两个32位配置寄存器
  • (2)两个32位数据寄存器
  • (3)一个32位置位/复位寄存器:GPIOx_BSRR
  • (4)一个16位复位寄存器:GPIOx_BRR
  • (5)一个32位锁定寄存器:GPIOx_LCKR
  • 4. 时钟控制器
  • 二、GPIO配置
  • 1. 配置内容
  • 2. 配置结构体
  • (1)GPIO_Pin:
  • (2)Mode:
  • (3)Speed:
  • (4)OType:
  • (5)PuPd:
  • 三、GPIO使用步骤
  • 四、代码示例
  • 1. 跑马灯显示
  • 2. 显示数字
  • 一、GPIO寄存器介绍

    1. GPIO简介

    GPIO是STM32微控制器上的一组引脚,可配置为输入或输出模式,用于与外部设备进行数字信号交换。每个GPIO引脚都有一个唯一的编号,通常称为引脚名称或引脚号码。

    STM32系列微控制器通常具有多个GPIO引脚,数量取决于具体型号。

    GPIO模块是STM32微控制器中非常重要的功能之一,它允许微控制器与外部设备进行数字信号交换。通过正确配置和使用GPIO,可以实现各种应用,包括传感器接口、控制输出设备等。

    IO端口的基本作用

    2. GPIO功能

    (1)模式分类

    GPIO端口的每个位可以由软件分别配置成多种模式:

  • 输入浮空
  • 输入上拉
  • 输入下拉
  • 开漏输出
  • 推挽式输出
  • 推挽式复用功能
  • 开漏复用功能
  • (2)模式设置方法

    通过设置: GPIOx_CRL/CRH,具体有:

    MODE[1:0]:模式控制,用于配置端口引脚的模式:
  • 00:输入模式
  • 01:输出模式
  • 10:复用功能模式
  • 11:模拟输入模式
  • CNF[1:0]:配置引脚输出速度:
  • 00:低速
  • 01:中速
  • 10:高速
  • 11:最高速
  • PUPD[1:0]:上拉/下拉配置:
  • 00:无上拉/下拉
  • 01:上拉
  • 10:下拉
  • 11:保留
  • 这些值一般在使用寄存器编程需要用到,使用库函数时直接使用系统定义的宏来设置,一般定义如下:

  • GPIO_Mode_IN:输入模式,用于将GPIO引脚配置为输入模式。
  • GPIO_Mode_OUT:输出模式,用于将GPIO引脚配置为输出模式。
  • GPIO_Mode_AF:复用模式,用于将GPIO引脚配置为复用模式,通常用于连接外设。
  • GPIO_Mode_AN:模拟模式,用于将GPIO引脚配置为模拟模式,用于ADC输入等。
  • (3)输入模式

    GPIO引脚可以用于读取外部设备的数字信号。在输入模式下,引脚可以被连接到传感器、开关、按钮等外部设备,并且微控制器可以读取这些设备的状态(高电平或低电平)。
    下图是I/O端口位的输入设置:

    (4)输出模式

    GPIO引脚可以用于向外部设备发送数字信号。在输出模式下,微控制器可以控制引脚的状态,输出高电平或低电平信号,从而驱动LED、继电器、马达等外部设备。
    输出IO端口位配置:

    3. GPIO的寄存器

    在STM32系列微控制器中,GPIO的配置和控制通过一系列特定的寄存器完成。这些寄存器提供了对GPIO引脚的各种配置选项和控制功能。
    每个GPIO端口有:

    (1)两个32位配置寄存器

    控制端口引脚的模式、输出速度和上拉/下拉配置。

  • GPIOx_CRL
  • GPIOx_CRH,
  • (2)两个32位数据寄存器

  • GPIOx_IDR:输入数据寄存器,读取端口引脚的电平状态。
  • GPIOx_ODR:输出数据寄存器,设置端口引脚的电平状态。
  • (3)一个32位置位/复位寄存器:GPIOx_BSRR

    用于设置或复位端口引脚的电平。

    (4)一个16位复位寄存器:GPIOx_BRR

    用于复位端口引脚的电平。

    (5)一个32位锁定寄存器:GPIOx_LCKR

    锁定寄存器,用于锁定GPIO端口的配置。

    4. 时钟控制器

    在STM32微控制器中,每个GPIO端口都需要单独打开时钟以激活其功能。时钟控制器(Clock Controller)是用来控制微控制器内部各个模块的时钟信号的,包括GPIO模块。通过打开相应GPIO端口的时钟,可以使得该端口的GPIO模块开始正常工作。

    二、GPIO配置

    1. 配置内容

    在STM32中,使用寄存器对GPIO进行配置和控制。常见的GPIO配置包括以下几个步骤:

    1. 选择引脚模式:确定引脚是作为输入还是输出。这通常涉及设置相应的寄存器位。

    2. 配置引脚速率:根据需求选择引脚的输出速率,以适应外部设备的要求。速率通常包括低速、中速、高速等选项。

    3. 配置引脚上下拉:根据需要启用或禁用引脚的上拉或下拉电阻,以确保在未连接外部设备时引脚的稳定状态。

    4. 配置引脚中断(可选):如果需要,可以配置引脚触发中断,以便在引脚状态发生变化时触发微控制器的中断服务程序。

    2. 配置结构体

    GPIO配置结构体是一个用于配置GPIO引脚参数的数据结构,面是一个典型的GPIO配置结构体的说明:

    typedef struct {
        uint32_t GPIO_Pin;      // GPIO引脚编号,可以是单个引脚或者多个引脚的组合,如 GPIO_Pin_0 | GPIO_Pin_1
        GPIOMode_TypeDef Mode;  // GPIO引脚的工作模式,包括输入模式、输出模式、复用模式等
        GPIOSpeed_TypeDef Speed; // GPIO引脚的输出速率,通常有低速、中速、高速可选
        GPIOOType_TypeDef OType; // GPIO引脚的输出类型,通常有推挽输出和开漏输出两种类型
        GPIOPuPd_TypeDef PuPd;   // GPIO引脚的上拉/下拉电阻状态,可以选择无上拉/下拉、上拉、下拉
    } GPIO_InitTypeDef;
    
    

    初始化:

    GPIO_InitTypeDef GPIO_InitStruct;
    

    (1)GPIO_Pin:

    表示需要配置的GPIO引脚的编号,可以使用GPIO_Pin_X的形式表示单个引脚,也可以使用按位或操作将多个引脚组合在一起,例如 GPIO_Pin_0 | GPIO_Pin_1 表示同时配置GPIO引脚0和1。

    (2)Mode:

    表示GPIO引脚的工作模式,包括输入模式(GPIO_Mode_IN)、输出模式(GPIO_Mode_OUT)、复用模式(GPIO_Mode_AF)等。根据具体应用需求选择合适的工作模式。
    示例:

    GPIO_InitStruct.Mode = GPIO_Mode_IN; // 输入模式
    GPIO_InitStruct.Mode = GPIO_Mode_OUT; // 输出模式
    GPIO_InitStruct.Mode = GPIO_Mode_AF; // 复用模式
    

    如果是输出模式,还需要选择引脚的类型,通常有推挽输出和开漏输出两种类型。

    GPIO_InitStruct.Mode = GPIO_Mode_OUT; // 输出模式
    GPIO_InitStruct.Mode = GPIO_Mode_Out_PP; // 推挽输出
    GPIO_InitStruct.Mode = GPIO_Mode_Out_OD; // 开漏输出
    
    

    (3)Speed:

    表示GPIO引脚的输出速率,通常有低速(GPIO_Speed_2MHz)、中速(GPIO_Speed_50MHz)、高速(GPIO_Speed_100MHz)可选。选择合适的输出速率可以满足不同应用的需求。
    示例:

    GPIO_InitStruct.Speed = GPIO_Speed_2MHz; // 2MHz输出速率
    GPIO_InitStruct.Speed = GPIO_Speed_50MHz; // 50MHz输出速率
    GPIO_InitStruct.Speed = GPIO_Speed_100MHz; // 100MHz输出速率
    
    

    (4)OType:

    表示GPIO引脚的输出类型,包括推挽输出(GPIO_OType_PP)和开漏输出(GPIO_OType_OD)两种类型。推挽输出适用于驱动电平信号,而开漏输出适用于驱动开关或者双向总线。

    (5)PuPd:

    表示GPIO引脚的上拉/下拉电阻状态,可以选择无上拉/下拉(GPIO_PuPd_NOPULL)、上拉(GPIO_PuPd_UP)、下拉(GPIO_PuPd_DOWN)。根据实际连接情况选择合适的上拉/下拉电阻状态。
    示例:

    GPIO_InitStruct.Pull = GPIO_PuPd_NOPULL; // 无上拉/下拉
    GPIO_InitStruct.Pull = GPIO_PuPd_UP; // 上拉
    GPIO_InitStruct.Pull = GPIO_PuPd_DOWN; // 下拉
    
    

    配置完成后,可以使用GPIO_Init()函数将配置应用到GPIO引脚上:

    GPIO_Init(GPIOA, &GPIO_InitStruct); // 将配置应用到 GPIOA 端口上
    
    

    三、GPIO使用步骤

    以下是使用STM32的GPIO的一般步骤:

    1. 打开GPIO端口时钟;
    2. 初始化GPIO模块:在程序开始时,需要初始化GPIO模块,配置所需的引脚为输入或输出,并设置其他相关参数;
    3. 读取输入引脚状态:如果引脚配置为输入模式,可以使用相应的函数或指令来读取引脚的状态,判断外部设备的状态;
    4. 设置输出引脚状态:如果引脚配置为输出模式,可以使用相应的函数或指令来设置引脚的状态,向外部设备发送所需的信号;
    5. 处理中断(可选):如果配置了中断,需要编写相应的中断服务程序来处理引脚状态变化时的事件。

    四、代码示例

    1. 跑马灯显示

    实验使用普中开发板,LED电路如下:

    LED1的阴极连接在芯片的26号引脚PC0(GPIO端口C的第0管脚)上,当PC0输出低电平时,发光二极管正向导通,D1被点亮。因此,对PC0进行操作即可控制LED1。

    #include "stm32f10x_lib.h" //包含所有的STM32F10x库的头文件
    #include <stdio.h>
    
    // GPIO配置函数
    void GPIO_Configuration(void)
    {
        GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体
    
        // 开启GPIOC的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    
        // 设置GPIOC的模式为推挽输出
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //选择所有的pin
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置输出速度为50MHz
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出模式
        GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOC
    }
    
    // 延时函数
    void delay(u32 i)
    {
        while (i--) //当i不为0时,持续减1,实现延时
            ;
    }
    
    // 打开指定位置的LED
    void on(int position)
    {
        // GPIOC->BSRR = (1 << (16 + position)); //通过设置BSRR寄存器,关闭指定位置的LED
    	GPIO_ResetBits(GPIOC, GPIO_Pin_0 << position); //
    }
    
    // 关闭指定位置的LED
    void off(int position)
    {
        // GPIOC->BSRR = (1 << (position)); //通过设置BSRR寄存器,打开指定位置的LED
    	GPIO_SetBits(GPIOC, GPIO_Pin_0 << position);
    }
    
    // 主函数
    int main(void)
    {
        GPIO_Configuration(); //调用GPIO配置函数
    
        int j;
    
        //GPIOC->BRR = GPIO_Pin_0; //关闭0号位的LED
    		GPIO_SetBits(GPIOC, GPIO_Pin_All);
        while (1) //无限循环
        {
            for (j = 0; j < 8; j++) //遍历0到7号位
            {
                on(j); //打开j号位的LED
                delay(0xfffff); //延时
                off(j); //关闭j号位的LED
                delay(0xfffff); //延时
            }
        }
    }
    
    

    可以设置断点,打开GPIOA的查看窗口查看运行状态 :

    2. 显示数字

    #include "stm32f10x_lib.h" //包含所有的STM32F10x库的头文件
    #include <stdio.h>
    
    int arr[10][7] = {
    	{0,1,2,3,4,5},
    	{1,2},
    	{0,1,6,4,3},
    	{0,1,6,2,3},
    	{5,6,1,2},
    	{0,5,6,2,3},
    	{0,5,6,4,3,2},
    	{0,1,2},
    	{0,1,2,3,4,5,6},
    	{0,1,2,3,5,6}
    };
    
    // GPIO配置函数
    void GPIO_Configuration(void)
    {
        GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体
    
        // 开启GPIOC的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    
        // 设置GPIOC的模式为推挽输出
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //选择所有的pin
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置输出速度为50MHz
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出模式
        GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOC
    }
    
    // 延时函数
    void delay(u32 i)
    {
        while (i--) //当i不为0时,持续减1,实现延时
            ;
    }
    
    // 打开指定位置的LED
    void on(int position)
    {
    	GPIO_ResetBits(GPIOC, GPIO_Pin_0 << position); //
    }
    
    // 关闭指定位置的LED
    void off(int position)
    {
    	GPIO_SetBits(GPIOC, GPIO_Pin_0 << position);
    }
    void onArray(int array[], int len){
    	int j;
    	for(j=0;j<len;j++){
    		on(array[j]);
    	}
    }
    int count(int n){
    	int len = 1;
    	for (int i = 1; i < 7; i++) {
    			if (arr[n][i] != '\0') {
    					len++;
    			} else {
    					break;
    			}
    	}	
    return len;
    }
    void lightn(int n){
    
    	// 计算onArray 第二个参数,即二维数组第二维长度
    	int len = count(n);
    	onArray(arr[n], len);
    }
    
    void allOff(){
    	GPIO_SetBits(GPIOC, GPIO_Pin_All);
    }
    // 主函数
    int main(void)
    {
        GPIO_Configuration(); //调用GPIO配置函数
    
        int j;
    
    	GPIO_SetBits(GPIOC, GPIO_Pin_All);
        while (1) //无限循环
        {
           
    	   for(int i=0;i<10;i++){
    		   lightn(i);
    		   delay(0xfffff);
    		   allOff();
    		   delay(0xff);
    	   }
        }
    }
    
    

    本文代码开源地址:
    https://gitee.com/xundh/stm32_arm_learn

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32学习2:使用库函数控制GPIO输出

    发表评论