Bootstrap

STMicroelectronics 系列:STM32F0 系列_(7).STM32F0系列GPIO配置与使用

STM32F0系列GPIO配置与使用

引言

GPIO(General Purpose Input/Output)是STM32F0系列单片机中最基础的外设之一。通过GPIO,单片机可以与其他外部设备进行交互,实现输入和输出功能。本节将详细介绍STM32F0系列GPIO的配置和使用方法,包括引脚配置、模式设置、输出控制和输入读取等。

在这里插入图片描述

GPIO概述

STM32F0系列单片机的GPIO是高度灵活的,每个GPIO端口最多有16个引脚。这些引脚可以被配置为多种模式,包括输入、输出、复用功能和模拟功能。GPIO的配置通常涉及以下几个步骤:

  1. 使能GPIO端口的时钟。

  2. 配置GPIO引脚的模式。

  3. 配置GPIO引脚的速度、输出类型和上拉/下拉电阻。

  4. 读取或设置GPIO引脚的值。

GPIO端口和引脚

STM32F0系列单片机的GPIO端口通常用字母A、B、C、D、E等表示,每个端口有16个引脚,用数字0-15表示。例如,GPIOA端口的引脚0表示为PA0

GPIO寄存器

GPIO的配置和操作主要通过以下几个寄存器进行:

  • GPIOx_MODER:模式寄存器,用于配置GPIO引脚的模式。

  • GPIOx_OTYPER:输出类型寄存器,用于配置输出类型(推挽或开漏)。

  • GPIOx_OSPEEDR:输出速度寄存器,用于配置输出速度。

  • GPIOx_PUPDR:上拉/下拉寄存器,用于配置上拉或下拉电阻。

  • GPIOx_ODR:输出数据寄存器,用于设置GPIO引脚的输出值。

  • GPIOx_IDR:输入数据寄存器,用于读取GPIO引脚的输入值。

  • GPIOx_BSRR:位设置/复位寄存器,用于设置或复位GPIO引脚的值。

  • GPIOx_LCKR:锁定寄存器,用于锁定GPIO配置。

GPIO配置步骤

1. 使能GPIO端口的时钟

在配置GPIO之前,首先需要使能相应的GPIO端口的时钟。STM32F0系列单片机的时钟控制寄存器位于RCC(Reset and Clock Control)模块中。例如,使能GPIOA端口的时钟可以使用以下代码:


// 使能GPIOA端口的时钟

RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

2. 配置GPIO引脚的模式

GPIO引脚的模式可以配置为输入、输出、复用功能或模拟功能。模式配置通过GPIOx_MODER寄存器进行。每个引脚有2位来表示模式,具体含义如下:

  • 00:输入模式

  • 01:输出模式

  • 10:复用功能模式

  • 11:模拟模式

例如,配置PA0引脚为输出模式:


// 配置PA0引脚为输出模式

GPIOA->MODER &= ~(0x3 << (0 * 2)); // 清除PA0的模式位

GPIOA->MODER |= (0x1 << (0 * 2));  // 设置PA0为输出模式

3. 配置GPIO引脚的速度

GPIO引脚的输出速度可以配置为低速、中速、高速或超高速。速度配置通过GPIOx_OSPEEDR寄存器进行。每个引脚有2位来表示速度,具体含义如下:

  • 00:低速

  • 01:中速

  • 10:高速

  • 11:超高速

例如,配置PA0引脚为高速输出:


// 配置PA0引脚为高速输出

GPIOA->OSPEEDR &= ~(0x3 << (0 * 2)); // 清除PA0的速度位

GPIOA->OSPEEDR |= (0x2 << (0 * 2));  // 设置PA0为高速输出

4. 配置GPIO引脚的输出类型

GPIO引脚的输出类型可以配置为推挽(Push-Pull)或开漏(Open-Drain)。输出类型配置通过GPIOx_OTYPER寄存器进行。每个引脚有1位来表示输出类型,具体含义如下:

  • 0:推挽输出

  • 1:开漏输出

例如,配置PA0引脚为推挽输出:


// 配置PA0引脚为推挽输出

GPIOA->OTYPER &= ~(0x1 << 0); // 清除PA0的输出类型位

5. 配置GPIO引脚的上拉/下拉电阻

GPIO引脚的上拉/下拉电阻可以配置为上拉、下拉、无上拉/下拉。上拉/下拉电阻配置通过GPIOx_PUPDR寄存器进行。每个引脚有2位来表示上拉/下拉电阻,具体含义如下:

  • 00:无上拉/下拉

  • 01:上拉

  • 10:下拉

  • 11:保留

例如,配置PA0引脚为上拉电阻:


// 配置PA0引脚为上拉电阻

GPIOA->PUPDR &= ~(0x3 << (0 * 2)); // 清除PA0的上拉/下拉位

GPIOA->PUPDR |= (0x1 << (0 * 2));  // 设置PA0为上拉电阻

GPIO操作

1. 设置GPIO引脚的输出值

设置GPIO引脚的输出值通过GPIOx_ODR寄存器进行。每个引脚有1位来表示输出值,0表示低电平,1表示高电平。例如,设置PA0引脚为高电平:


// 设置PA0引脚为高电平

GPIOA->ODR |= (0x1 << 0);

2. 读取GPIO引脚的输入值

读取GPIO引脚的输入值通过GPIOx_IDR寄存器进行。每个引脚有1位来表示输入值,0表示低电平,1表示高电平。例如,读取PA0引脚的输入值:


// 读取PA0引脚的输入值

uint32_t value = GPIOA->IDR & (0x1 << 0);

if (value) {

    // PA0引脚为高电平

} else {

    // PA0引脚为低电平

}

3. 使用位设置/复位寄存器

GPIOx_BSRR寄存器可以用于设置或复位GPIO引脚的值,而不需要读取和修改整个寄存器。例如,设置PA0引脚为高电平,同时复位PA1引脚为低电平:


// 设置PA0引脚为高电平,同时复位PA1引脚为低电平

GPIOA->BSRR = (0x1 << 0) | (0x1 << (1 + 16));

实例:控制LED灯

假设我们有一个LED灯连接到PA0引脚,我们将通过GPIO配置和操作来控制LED灯的亮灭。

硬件连接

  • LED灯阳极连接到PA0引脚。

  • LED灯阴极通过一个限流电阻连接到GND。

代码示例


#include "stm32f0xx.h"



void GPIO_Init(void) {

    // 使能GPIOA端口的时钟

    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;



    // 配置PA0引脚为推挽输出模式,高速

    GPIOA->MODER &= ~(0x3 << (0 * 2)); // 清除PA0的模式位

    GPIOA->MODER |= (0x1 << (0 * 2));  // 设置PA0为输出模式



    GPIOA->OSPEEDR &= ~(0x3 << (0 * 2)); // 清除PA0的速度位

    GPIOA->OSPEEDR |= (0x2 << (0 * 2));  // 设置PA0为高速输出



    GPIOA->OTYPER &= ~(0x1 << 0); // 设置PA0为推挽输出



    GPIOA->PUPDR &= ~(0x3 << (0 * 2)); // 清除PA0的上拉/下拉位

    GPIOA->PUPDR |= (0x0 << (0 * 2));  // 设置PA0为无上拉/下拉

}



void LED_Toggle(void) {

    // 切换PA0引脚的输出值

    GPIOA->ODR ^= (0x1 << 0);

}



int main(void) {

    // 初始化GPIO

    GPIO_Init();



    while (1) {

        // 切换LED灯状态

        LED_Toggle();



        // 延时1秒

        for (volatile uint32_t i = 0; i < 1000000; i++);

    }

}

代码解释

  1. GPIO_Init函数

    • 使能GPIOA端口的时钟。

    • 配置PA0引脚为输出模式。

    • 配置PA0引脚为高速输出。

    • 配置PA0引脚为推挽输出。

    • 配置PA0引脚为无上拉/下拉。

  2. LED_Toggle函数

    • 使用异或操作切换PA0引脚的输出值。如果PA0引脚当前为高电平,则切换为低电平;如果当前为低电平,则切换为高电平。
  3. main函数

    • 初始化GPIO。

    • 进入无限循环,每1秒切换一次LED灯的状态。

实例:读取按键状态

假设我们有一个按键连接到PA1引脚,我们将通过GPIO配置和操作来读取按键的状态。

硬件连接

  • 按键一端连接到PA1引脚。

  • 按键另一端连接到GND。

  • PA1引脚通过一个上拉电阻连接到VCC。

代码示例


#include "stm32f0xx.h"



void GPIO_Init(void) {

    // 使能GPIOA端口的时钟

    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;



    // 配置PA1引脚为输入模式,上拉电阻

    GPIOA->MODER &= ~(0x3 << (1 * 2)); // 清除PA1的模式位

    GPIOA->MODER |= (0x0 << (1 * 2));  // 设置PA1为输入模式



    GPIOA->PUPDR &= ~(0x3 << (1 * 2)); // 清除PA1的上拉/下拉位

    GPIOA->PUPDR |= (0x1 << (1 * 2));  // 设置PA1为上拉电阻

}



uint32_t Read_Button(void) {

    // 读取PA1引脚的输入值

    return GPIOA->IDR & (0x1 << 1);

}



int main(void) {

    // 初始化GPIO

    GPIO_Init();



    while (1) {

        // 读取按键状态

        uint32_t button_state = Read_Button();



        if (button_state) {

            // 按键未按下

            // 可以在这里添加未按下时的处理代码

        } else {

            // 按键按下

            // 可以在这里添加按下时的处理代码

        }



        // 延时100毫秒

        for (volatile uint32_t i = 0; i < 100000; i++);

    }

}

代码解释

  1. GPIO_Init函数

    • 使能GPIOA端口的时钟。

    • 配置PA1引脚为输入模式。

    • 配置PA1引脚为上拉电阻。

  2. Read_Button函数

    • 读取PA1引脚的输入值。如果按键按下,PA1引脚将被拉低,返回0;如果按键未按下,PA1引脚将保持高电平,返回1。
  3. main函数

    • 初始化GPIO。

    • 进入无限循环,每100毫秒读取一次按键状态,并根据按键状态执行相应的处理代码。

结语

通过本节的学习,您应该能够理解STM32F0系列单片机GPIO的基本配置和操作方法。通过实际的代码示例,您可以更好地掌握如何使用GPIO来控制LED灯和读取按键状态。接下来,我们将继续探讨STM32F0系列单片机的其他外设和功能。

;