STMicroelectronics 系列:STM32G0 系列_(8).STM32G0系列的GPIO接口

STM32G0系列的GPIO接口

1. GPIO接口概述

GPIO(General Purpose Input/Output)接口是STM32G0系列单片机中非常重要的外设之一,用于实现单片机与外部世界的交互。GPIO接口可以配置为多种不同的模式,包括输入、输出、复用功能等,以满足不同的应用需求。STM32G0系列单片机的GPIO接口具有以下特点:

  • 丰富的端口:STM32G0系列单片机通常具有多个GPIO端口,每个端口包含多个引脚。

  • 灵活的配置:每个GPIO引脚可以独立配置为不同的模式,如推挽输出、开漏输出、上拉或下拉输入等。

  • 增强的防护:GPIO引脚具有内置的ESD(静电放电)防护和过压保护功能。

  • 中断功能:GPIO引脚可以配置为中断输入,用于快速响应外部事件。

  • 2. GPIO寄存器

    STM32G0系列单片机的GPIO接口通过一组寄存器进行配置和控制。这些寄存器包括:

  • MODER(Mode Register):模式寄存器,用于配置每个引脚的工作模式。

  • OTYPER(Output Type Register):输出类型寄存器,用于配置每个引脚的输出类型。

  • OSPEEDR(Output Speed Register):输出速度寄存器,用于配置每个引脚的输出速度。

  • PUPDR(Pull-Up/Pull-Down Register):上拉/下拉寄存器,用于配置每个引脚的上拉或下拉电阻。

  • ODR(Output Data Register):输出数据寄存器,用于设置每个引脚的输出电平。

  • IDR(Input Data Register):输入数据寄存器,用于读取每个引脚的输入电平。

  • AFR(Alternate Function Register):复用功能寄存器,用于配置每个引脚的复用功能。

  • 2.1 MODER寄存器

    MODER寄存器用于配置每个引脚的工作模式。每个引脚的模式由2位来表示,具体如下:

  • 00:输入模式(通用输入)

  • 01:输出模式(通用推挽输出)

  • 10:输出模式(通用开漏输出)

  • 11:复用功能模式

  • 代码示例:配置GPIO引脚为推挽输出模式
    
    // 配置GPIOA的第5引脚为推挽输出模式
    
    GPIOA->MODER |= (1 << 10);  // 设置为01
    
    GPIOA->MODER &= ~(1 << 11); // 清除第11位
    
    

    2.2 OTYPER寄存器

    OTYPER寄存器用于配置每个引脚的输出类型。每个引脚的输出类型由1位来表示,具体如下:

  • 0:推挽输出

  • 1:开漏输出

  • 代码示例:配置GPIO引脚为开漏输出模式
    
    // 配置GPIOA的第5引脚为开漏输出模式
    
    GPIOA->OTYPER |= (1 << 5);  // 设置第5位为1
    
    

    2.3 OSPEEDR寄存器

    OSPEEDR寄存器用于配置每个引脚的输出速度。每个引脚的输出速度由2位来表示,具体如下:

  • 00:低速(2 MHz)

  • 01:中速(25 MHz)

  • 10:高速(50 MHz)

  • 11:非常高(100 MHz)

  • 代码示例:配置GPIO引脚为高速输出
    
    // 配置GPIOA的第5引脚为高速输出
    
    GPIOA->OSPEEDR |= (1 << 10);  // 设置为10
    
    GPIOA->OSPEEDR &= ~(1 << 11); // 清除第11位
    
    

    2.4 PUPDR寄存器

    PUPDR寄存器用于配置每个引脚的上拉或下拉电阻。每个引脚的上拉/下拉电阻由2位来表示,具体如下:

  • 00:无上拉/下拉

  • 01:上拉

  • 10:下拉

  • 11:保留

  • 代码示例:配置GPIO引脚为上拉输入
    
    // 配置GPIOA的第5引脚为上拉输入
    
    GPIOA->MODER &= ~(1 << 10);  // 清除第10位
    
    GPIOA->MODER &= ~(1 << 11);  // 清除第11位
    
    GPIOA->PUPDR |= (1 << 10);   // 设置为01
    
    GPIOA->PUPDR &= ~(1 << 11);  // 清除第11位
    
    

    2.5 ODR寄存器

    ODR寄存器用于设置每个引脚的输出电平。每个引脚的输出电平由1位来表示,具体如下:

  • 0:低电平

  • 1:高电平

  • 代码示例:设置GPIO引脚为高电平
    
    // 设置GPIOA的第5引脚为高电平
    
    GPIOA->ODR |= (1 << 5);  // 设置第5位为1
    
    

    2.6 IDR寄存器

    IDR寄存器用于读取每个引脚的输入电平。每个引脚的输入电平由1位来表示,具体如下:

  • 0:低电平

  • 1:高电平

  • 代码示例:读取GPIO引脚的输入电平
    
    // 读取GPIOA的第5引脚的输入电平
    
    uint32_t input_level = GPIOA->IDR & (1 << 5);
    
    

    2.7 AFR寄存器

    AFR寄存器用于配置每个引脚的复用功能。每个引脚的复用功能由4位来表示,具体如下:

  • 0000:复用功能0

  • 0001:复用功能1

  • 1111:复用功能15

  • 代码示例:配置GPIO引脚为复用功能
    
    // 配置GPIOA的第5引脚为复用功能1
    
    GPIOA->MODER |= (3 << 10);  // 设置为11(复用功能模式)
    
    GPIOA->AFR[0] &= ~(0xF << 20);  // 清除复用功能配置
    
    GPIOA->AFR[0] |= (1 << 20);     // 设置复用功能为1
    
    

    3. GPIO初始化

    在使用GPIO之前,需要对其进行初始化。STM32G0系列单片机提供了HAL库来简化GPIO的初始化过程。通过HAL库,可以轻松地配置GPIO的工作模式、输出类型、输出速度和上拉/下拉电阻。

    3.1 使用HAL库初始化GPIO

    3.1.1 配置GPIO结构体

    首先,需要定义一个GPIO_InitTypeDef结构体来配置GPIO的属性。该结构体包含以下字段:

  • Pin:指定要配置的引脚。

  • Mode:指定引脚的工作模式。

  • Pull:指定引脚的上拉/下拉电阻。

  • Speed:指定引脚的输出速度。

  • Alternate:指定引脚的复用功能。

  • 3.1.2 初始化GPIO

    使用HAL_GPIO_Init函数来初始化GPIO引脚。该函数需要两个参数:GPIO_TypeDef类型的指针和GPIO_InitTypeDef类型的指针。

    代码示例:使用HAL库初始化GPIO
    
    #include "stm32g0xx_hal.h"
    
    
    
    // 定义GPIO结构体
    
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    
    
    // 初始化GPIOA的第5引脚为推挽输出模式,高电平,无上拉/下拉
    
    void GPIO_Init(void) {
    
        // 使能GPIOA时钟
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
    
        // 配置GPIOA的第5引脚
    
        GPIO_InitStruct.Pin = GPIO_PIN_5;
    
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    
        GPIO_InitStruct.Pull = GPIO_NOPULL;
    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    
    
    
        // 初始化GPIOA
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    }
    
    
    
    int main(void) {
    
        // 初始化系统
    
        HAL_Init();
    
    
    
        // 初始化GPIO
    
        GPIO_Init();
    
    
    
        // 设置GPIOA的第5引脚为高电平
    
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    
    
    
        // 无限循环
    
        while (1) {
    
            // 读取GPIOA的第5引脚的输入电平
    
            uint32_t input_level = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5);
    
    
    
            // 根据输入电平切换输出电平
    
            if (input_level == GPIO_PIN_RESET) {
    
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    
            } else {
    
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    
            }
    
    
    
            // 延时100ms
    
            HAL_Delay(100);
    
        }
    
    }
    
    

    3.2 使用寄存器直接初始化GPIO

    除了使用HAL库外,还可以通过直接操作寄存器来初始化GPIO。这种方式更加灵活,但需要对寄存器有深入的了解。

    代码示例:使用寄存器直接初始化GPIO
    
    #include "stm32g0xx.h"
    
    
    
    void GPIO_Init(void) {
    
        // 使能GPIOA时钟
    
        RCC->IOPENR |= RCC_IOPENR_IOPAEN;
    
    
    
        // 配置GPIOA的第5引脚为推挽输出模式
    
        GPIOA->MODER |= (1 << 10);  // 设置为01
    
        GPIOA->MODER &= ~(1 << 11); // 清除第11位
    
    
    
        // 配置GPIOA的第5引脚为高速输出
    
        GPIOA->OSPEEDR |= (1 << 10);  // 设置为10
    
        GPIOA->OSPEEDR &= ~(1 << 11); // 清除第11位
    
    
    
        // 配置GPIOA的第5引脚为无上拉/下拉
    
        GPIOA->PUPDR &= ~(1 << 10);  // 清除第10位
    
        GPIOA->PUPDR &= ~(1 << 11);  // 清除第11位
    
    }
    
    
    
    int main(void) {
    
        // 初始化GPIO
    
        GPIO_Init();
    
    
    
        // 设置GPIOA的第5引脚为高电平
    
        GPIOA->ODR |= (1 << 5);
    
    
    
        // 无限循环
    
        while (1) {
    
            // 读取GPIOA的第5引脚的输入电平
    
            uint32_t input_level = GPIOA->IDR & (1 << 5);
    
    
    
            // 根据输入电平切换输出电平
    
            if (input_level == 0) {
    
                GPIOA->ODR |= (1 << 5);  // 设置为高电平
    
            } else {
    
                GPIOA->ODR &= ~(1 << 5); // 设置为低电平
    
            }
    
    
    
            // 延时100ms
    
            for (uint32_t i = 0; i < 1000000; i++);
    
        }
    
    }
    
    

    4. GPIO中断配置

    GPIO中断功能允许单片机在检测到外部事件时快速响应。STM32G0系列单片机的GPIO中断可以通过配置EXTI(External Interrupt/Event Controller)来实现。

    4.1 EXTI中断配置

    EXTI中断配置包括以下步骤:

    1. 配置GPIO引脚为中断输入模式

    2. 配置EXTI线

    3. 配置NVIC(Nested Vectored Interrupt Controller)

    4. 编写中断服务函数

    4.1.1 配置GPIO引脚为中断输入模式

    首先,需要将GPIO引脚配置为中断输入模式。可以通过设置MODER寄存器来实现。

    代码示例:配置GPIO引脚为中断输入模式
    
    // 配置GPIOA的第5引脚为中断输入模式
    
    GPIOA->MODER &= ~(1 << 10);  // 清除第10位
    
    GPIOA->MODER &= ~(1 << 11);  // 清除第11位
    
    GPIOA->PUPDR |= (1 << 10);   // 设置为上拉
    
    GPIOA->PUPDR &= ~(1 << 11);  // 清除第11位
    
    
    4.1.2 配置EXTI线

    EXTI线需要配置为与GPIO引脚对应的中断线。通过设置EXTICR寄存器来实现。

    代码示例:配置EXTI线
    
    // 配置EXTI线5为GPIOA的第5引脚
    
    SYSCFG->EXTICR[1] &= ~(0xF << 0);  // 清除配置
    
    SYSCFG->EXTICR[1] |= (0x0 << 0);   // 设置为GPIOA
    
    
    4.1.3 配置NVIC

    NVIC用于管理中断优先级和使能中断。通过设置ISER寄存器来使能中断,并通过IPR寄存器来配置中断优先级。

    代码示例:配置NVIC
    
    // 使能EXTI线5的中断
    
    NVIC->ISER[0] |= (1 << 5);  // 使能EXTI线5的中断
    
    
    
    // 配置EXTI线5的中断优先级
    
    NVIC_SetPriority(EXTI0_1_IRQn, 1);  // 设置优先级为1
    
    
    4.1.4 编写中断服务函数

    中断服务函数(ISR)是在中断发生时执行的函数。需要在stm32g0xx_it.c文件中编写ISR。

    代码示例:编写中断服务函数
    
    #include "stm32g0xx_hal.h"
    
    
    
    // 中断服务函数
    
    void EXTI0_1_IRQHandler(void) {
    
        // 清除中断标志
    
        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
    
    
    
        // 处理中断
    
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET) {
    
            // 按键按下
    
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);  // 设置为高电平
    
        } else {
    
            // 按键释放
    
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);  // 设置为低电平
    
        }
    
    }
    
    
    
    // 初始化GPIO中断
    
    void GPIO_Interrupt_Init(void) {
    
        // 使能GPIOA时钟
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
    
        // 配置GPIOA的第5引脚为中断输入模式
    
        GPIO_InitTypeDef GPIO_InitStruct = {0};
    
        GPIO_InitStruct.Pin = GPIO_PIN_5;
    
        GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
    
        GPIO_InitStruct.Pull = GPIO_NOPULL;
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    
    
        // 配置EXTI线5为GPIOA的第5引脚
    
        HAL_NVIC_SetPriority(EXTI0_1_IRQn, 1, 0);
    
        HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
    
    
    
        // 使能EXTI线5的中断
    
        EXTI->IMR1 |= (1 << 5);  // 使能中断
    
        EXTI->FTSR1 |= (1 << 5); // 选择下降沿触发
    
    }
    
    
    
    int main(void) {
    
        // 初始化HAL库
    
        HAL_Init();
    
    
    
        // 初始化GPIO中断
    
        GPIO_Interrupt_Init();
    
    
    
        // 无限循环
    
        while (1) {
    
            // 主程序逻辑
    
        }
    
    }
    
    

    5. GPIO常用配置

    5.1 LED控制

    LED控制是GPIO应用中最常见的场景之一。通过配置GPIO引脚为输出模式,可以控制LED的亮灭。

    代码示例:控制LED
    
    #include "stm32g0xx_hal.h"
    
    
    
    // 定义GPIO结构体
    
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    
    
    // 初始化LED引脚
    
    void LED_Init(void) {
    
        // 使能GPIOA时钟
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
    
        // 配置GPIOA的第5引脚为推挽输出模式
    
        GPIO_InitStruct.Pin = GPIO_PIN_5;
    
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    
        GPIO_InitStruct.Pull = GPIO_NOPULL;
    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    }
    
    
    
    // 点亮LED
    
    void LED_On(void) {
    
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    
    }
    
    
    
    // 熄灭LED
    
    void LED_Off(void) {
    
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    
    }
    
    
    
    int main(void) {
    
        // 初始化HAL库
    
        HAL_Init();
    
    
    
        // 初始化LED引脚
    
        LED_Init();
    
    
    
        // 无限循环
    
        while (1) {
    
            // 点亮LED
    
            LED_On();
    
            HAL_Delay(500);  // 延时500ms
    
    
    
            // 熄灭LED
    
            LED_Off();
    
            HAL_Delay(500);  // 延时500ms
    
        }
    
    }
    
    

    5.2 按键检测

    按键检测是另一个常见的GPIO应用。通过配置GPIO引脚为输入模式,并使用中断或轮询方式来检测按键状态。

    代码示例:按键检测
    
    #include "stm32g0xx_hal.h"
    
    
    
    // 定义GPIO结构体
    
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    
    
    // 初始化按键引脚
    
    void Key_Init(void) {
    
        // 使能GPIOA时钟
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
    
        // 配置GPIOA的第5引脚为上拉输入模式
    
        GPIO_InitStruct.Pin = GPIO_PIN_5;
    
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    
        GPIO_InitStruct.Pull = GPIO_PULLUP;
    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    }
    
    
    
    // 检测按键状态
    
    uint32_t Key_Read(void) {
    
        return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5);
    
    }
    
    
    
    int main(void) {
    
        // 初始化HAL库
    
        HAL_Init();
    
    
    
        // 初始化按键引脚
    
        Key_Init();
    
    
    
        // 无限循环
    
        while (1) {
    
            // 读取按键状态
    
            uint32_t key_status = Key_Read();
    
    
    
            // 根据按键状态执行相应操作
    
            if (key_status == GPIO_PIN_RESET) {
    
                // 按键按下
    
                // 执行相应操作,例如点亮LED
    
                LED_On();
    
            } else {
    
                // 按键释放
    
                // 执行相应操作,例如熄灭LED
    
                LED_Off();
    
            }
    
    
    
            // 延时100ms
    
            HAL_Delay(100);
    
        }
    
    }
    
    

    5.3 中断方式的按键检测

    使用中断方式检测按键可以提高系统的响应速度和效率。当按键按下时,外部中断会被触发,中断服务函数会立即处理按键事件。

    代码示例:中断方式的按键检测
    
    #include "stm32g0xx_hal.h"
    
    
    
    // 定义GPIO结构体
    
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    
    
    // 初始化按键引脚
    
    void Key_Interrupt_Init(void) {
    
        // 使能GPIOA时钟
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
    
        // 配置GPIOA的第5引脚为中断输入模式
    
        GPIO_InitStruct.Pin = GPIO_PIN_5;
    
        GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
    
        GPIO_InitStruct.Pull = GPIO_PULLUP;
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    
    
        // 使能EXTI线5的中断
    
        HAL_NVIC_SetPriority(EXTI0_1_IRQn, 1, 0);
    
        HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
    
    }
    
    
    
    // 中断服务函数
    
    void EXTI0_1_IRQHandler(void) {
    
        // 清除中断标志
    
        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
    
    
    
        // 处理中断
    
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET) {
    
            // 按键按下
    
            LED_On();  // 点亮LED
    
        } else {
    
            // 按键释放
    
            LED_Off(); // 熄灭LED
    
        }
    
    }
    
    
    
    // 定义LED控制函数
    
    void LED_Init(void) {
    
        // 使能GPIOA时钟
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
    
        // 配置GPIOA的第5引脚为推挽输出模式
    
        GPIO_InitStruct.Pin = GPIO_PIN_5;
    
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    
        GPIO_InitStruct.Pull = GPIO_NOPULL;
    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    }
    
    
    
    void LED_On(void) {
    
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    
    }
    
    
    
    void LED_Off(void) {
    
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    
    }
    
    
    
    int main(void) {
    
        // 初始化HAL库
    
        HAL_Init();
    
    
    
        // 初始化LED引脚
    
        LED_Init();
    
    
    
        // 初始化按键中断
    
        Key_Interrupt_Init();
    
    
    
        // 无限循环
    
        while (1) {
    
            // 主程序逻辑
    
        }
    
    }
    
    

    5.4 模拟输入

    STM32G0系列单片机的GPIO引脚还可以配置为模拟输入模式,用于读取模拟信号。模拟输入模式通常与ADC(模数转换器)配合使用。

    代码示例:配置GPIO引脚为模拟输入
    
    #include "stm32g0xx_hal.h"
    
    
    
    // 定义GPIO结构体
    
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    
    
    // 初始化模拟输入引脚
    
    void Analog_Init(void) {
    
        // 使能GPIOA时钟
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
    
        // 配置GPIOA的第5引脚为模拟输入模式
    
        GPIO_InitStruct.Pin = GPIO_PIN_5;
    
        GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    
        GPIO_InitStruct.Pull = GPIO_NOPULL;
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    }
    
    
    
    // 读取模拟输入值
    
    uint32_t ADC_Read(void) {
    
        // 假设ADC1配置为使用GPIOA的第5引脚
    
        HAL_ADC_Start(&hadc1);
    
        HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
    
        return HAL_ADC_GetValue(&hadc1);
    
    }
    
    
    
    int main(void) {
    
        // 初始化HAL库
    
        HAL_Init();
    
    
    
        // 初始化ADC
    
        ADC_Init();
    
    
    
        // 初始化模拟输入引脚
    
        Analog_Init();
    
    
    
        // 无限循环
    
        while (1) {
    
            // 读取模拟输入值
    
            uint32_t adc_value = ADC_Read();
    
    
    
            // 处理ADC值
    
            if (adc_value > 2048) {
    
                // 模拟输入值大于2048,执行相应操作
    
                LED_On();
    
            } else {
    
                // 模拟输入值小于等于2048,执行相应操作
    
                LED_Off();
    
            }
    
    
    
            // 延时100ms
    
            HAL_Delay(100);
    
        }
    
    }
    
    
    
    // ADC初始化函数(假设已经配置好ADC1)
    
    void ADC_Init(void) {
    
        // 使能ADC1时钟
    
        __HAL_RCC_ADC1_CLK_ENABLE();
    
    
    
        // 配置ADC1
    
        ADC_HandleTypeDef hadc1;
    
        hadc1.Instance = ADC1;
    
        hadc1.Init.ScanConvMode = DISABLE;  // 禁用扫描模式
    
        hadc1.Init.ContinuousConvMode = DISABLE;  // 禁用连续转换模式
    
        hadc1.Init.DiscontinuousConvMode = DISABLE;  // 禁用不连续转换模式
    
        hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;  // 软件触发转换
    
        hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;  // 数据右对齐
    
        hadc1.Init.NbrOfConversion = 1;  // 1次转换
    
    
    
        // 初始化ADC1
    
        HAL_ADC_Init(&hadc1);
    
    
    
        // 配置ADC通道
    
        ADC_ChannelConfTypeDef sConfig = {0};
    
        sConfig.Channel = ADC_CHANNEL_5;  // 选择通道5
    
        sConfig.Rank = 1;  // 通道排序
    
        sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES;  // 采样时间
    
    
    
        // 配置ADC通道
    
        HAL_ADC_ConfigChannel(&hadc1, &sConfig);
    
    }
    
    

    5.5 复用功能配置

    GPIO引脚的复用功能允许引脚用于多个外设。例如,可以将GPIO引脚配置为USART的TX或RX引脚。

    代码示例:配置GPIO引脚为USART的TX和RX
    
    #include "stm32g0xx_hal.h"
    
    
    
    // 定义GPIO结构体
    
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    
    
    // 初始化USART的GPIO引脚
    
    void USART_GPIO_Init(void) {
    
        // 使能GPIOA时钟
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
    
    
        // 配置GPIOA的第9引脚为USART1的TX引脚
    
        GPIO_InitStruct.Pin = GPIO_PIN_9;
    
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    
        GPIO_InitStruct.Pull = GPIO_NOPULL;
    
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    
        GPIO_InitStruct.Alternate = GPIO_AF6_USART1;
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    
    
        // 配置GPIOA的第10引脚为USART1的RX引脚
    
        GPIO_InitStruct.Pin = GPIO_PIN_10;
    
        GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
    
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    }
    
    
    
    // USART初始化函数(假设已经配置好USART1)
    
    void USART_Init(void) {
    
        // 使能USART1时钟
    
        __HAL_RCC_USART1_CLK_ENABLE();
    
    
    
        // 配置USART1
    
        USART_HandleTypeDef huart1;
    
        huart1.Instance = USART1;
    
        huart1.Init.BaudRate = 115200;  // 波特率
    
        huart1.Init.WordLength = UART_WORDLENGTH_8B;  // 8位数据
    
        huart1.Init.StopBits = UART_STOPBITS_1;  // 1位停止位
    
        huart1.Init.Parity = UART_PARITY_NONE;  // 无奇偶校验
    
        huart1.Init.Mode = UART_MODE_TX_RX;  // 传输和接收模式
    
        huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;  // 无硬件流控制
    
        huart1.Init.OverSampling = UART_OVERSAMPLING_16;  // 16倍过采样
    
    
    
        // 初始化USART1
    
        HAL_UART_Init(&huart1);
    
    }
    
    
    
    int main(void) {
    
        // 初始化HAL库
    
        HAL_Init();
    
    
    
        // 初始化USART的GPIO引脚
    
        USART_GPIO_Init();
    
    
    
        // 初始化USART
    
        USART_Init();
    
    
    
        // 无限循环
    
        while (1) {
    
            // 发送数据
    
            uint8_t data = 'A';
    
            HAL_UART_Transmit(&huart1, &data, 1, HAL_MAX_DELAY);
    
    
    
            // 延时100ms
    
            HAL_Delay(100);
    
        }
    
    }
    
    

    5.6 总结

    STM32G0系列单片机的GPIO接口非常灵活和强大,可以通过多种方式配置引脚的工作模式、输出类型、输出速度和上拉/下拉电阻。此外,GPIO还支持中断功能,可以快速响应外部事件。通过HAL库或直接操作寄存器,可以轻松实现各种GPIO应用,如LED控制、按键检测、模拟输入和复用功能配置。

    希望本文档对您理解和使用STM32G0系列单片机的GPIO接口有所帮助。如有任何疑问或需要进一步的帮助,请参阅STM32官方文档或联系技术支持。

    作者:kkchenkx

    物联沃分享整理
    物联沃-IOTWORD物联网 » STMicroelectronics 系列:STM32G0 系列_(8).STM32G0系列的GPIO接口

    发表回复