STM32GPIO从工作模式到工程创建

简介

介绍STM32标准库的基本概念及其在嵌入式开发中的重要性,强调GPIO作为外设基础模块的关键作用。

GPIO基本概念

GPIO(General-Purpose Input/Output,通用输入 / 输出)是 MCU(微控制器)上最基础、最常用的外设之一,本质是一组可通过软件配置的通用引脚,用于连接外部硬件(如 LED、按键、传感器等),实现数据的输入和输出控制。

IO口

我们知道每一个板子都有很多个引脚,以STM32F103RCT6为例,

STM32F103RCT6 共有 64 个引脚。其中 51 个用于数据的输入输出。为了管理这些引脚,引入 GPIO 端口来管理。

每个 GPIO 端口最多管理 16 个 IO 口(专用于数据输入输出的引脚)。51 个 IO 口必须使用多个 GPIO 端口才能管理。因此对 GPIO 端口进行编号:GPIOA,GPIOB,GPIOC...

那我们怎么表示每个端口的IO口呢?

很简单,我们都知道每个端口都有16个引脚,分别是pin0,pin1,pin2...pin15,而这些引脚分配在不同的端口下,因此就有了PA0,PA1,PA2,PA3,...,PA15这样的说法,在不同的端口下,每个引脚的端口号都不一样,我能将STM32F103RCT6的51个引脚分成了GPIOA(Pin0-Pin15),GPIOB(Pin0-Pin15),GPIOC(Pin0-Pin15),以及GPIOD(PIN0-PIN2).

那各个端口又是如何处理各个IO口的呢?

通过各自的寄存器。每个外设都有它的特定的寄存器。GPIO 端口有 7 个寄存器:

CRL 配置低寄存器

CRH 配置高寄存器

IDR 输入数据寄存器,读取它可获取 IO 口电平状态,1 高电平,0 低电平

ODR 输出数据寄存器,写它可以对 IO 输出高低电平,1 高电平,0 低电平。开漏时写 1 输出高阻抗

BSRR 复位/置位寄存器

BRR 复位寄存器

LCKR 配置锁定寄存器

IO的基本结构:

了解完什么是GPIO,我们再来了解一下GPIO的几种工作模式

4 种输入模式:

输入浮空 ,输入上拉, 输入下拉,模拟输入

4 种输出模式:

通用推挽输出,通用开漏输出,复用功能推挽输出,复用功能开漏输出

输入浮空/上拉/下拉配置

输入模拟配置

推挽输出(上面是高电平下面是低电平)

开漏输出(上面是高电平下面是低电平)

那怎么选择我们的输出模式呢?

对外输出数字信号时,一般配置为推挽输出。

一般外部电路外接上拉电阻,并且所有设备都配置为开漏时,才使用开漏模式。I2C 总线配置为开漏模式。

在开漏模式时,对输入数据寄存器的读访问可得到I/O状态

在推挽式模式时,对输出数据寄存器的读访问得到最后一次写的值。

在知道了GPIO的输入输出模式之后,我们来看一下GPIO.h库下一些比较常用的函数

#include "stm32f10x_gpio.h"

// GPIO 端口默认初始化
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
// AFIO 默认初始化
void GPIO_AFIODeInit(void);
// GPIO 端口初始化(重点使用)
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
// GPIO 结构体初始化
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);

// 读 IDR 的某个位
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
// 读 IDR 所有低 16 个位
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

// 读 ODR 的某个位
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
// 读 ODR 的所有低 16 个位
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
// 对 ODR 某些位置 1
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
// 对 ODR 某些位清 0
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
// 对 ODR 的某个位写 0 或 1
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
// 写 ODR 的所有低 16 个位
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

// 锁定配置
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

// 事件输出配置
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
// 使能/禁用事件输出
void GPIO_EventOutputCmd(FunctionalState NewState);

// 复用功能重映射配置
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

// 外部中断线配置
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

在了解完一些常用的函数之后我们就可以开始我们简单的GPIO的配置了

GPIO初始化步骤

  • 硬件连接分析:明确目标引脚及电路设计需求(如驱动LED、读取按键)。
  • 时钟使能:调用RCC_APB2PeriphClockCmd()开启对应GPIO端口的时钟。
  • 参数配置:填充GPIO_InitTypeDef结构体(引脚号、模式、速度等)。
  • 初始化函数调用:通过GPIO_Init()完成配置。

关键函数与参数详解

  • GPIO_Init():参数配置逻辑与实例(如GPIO_Mode_Out_PP推挽输出)。
  • GPIO_SetBits()/GPIO_ResetBits():控制引脚高低电平的方法。

代码实例

提供完整的初始化代码片段,以点亮LED为例:

gpio.c

#include"gpio.h"


void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能时钟

	GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_Out_PP;//推挽输出模式
	GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_6| GPIO_Pin_7|GPIO_Pin_8;//选择Pin
	GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, & GPIO_InitStruct);
	GPIO_WriteBit(GPIOC, GPIO_Pin_6| GPIO_Pin_7|GPIO_Pin_8,Bit_SET);//默认输出高电平

}


void delay(uint32_t ms)
{

	for(uint32_t i=0;i<=ms*7200;i++)
	{
	
		__NOP();
	}
}	




gpio.h

#ifndef  __GPIO_H_
#define  __GPIO_H_
#include "stm32f10x.h"
#include <stdio.h>
void MX_GPIO_Init(void);

void delay(uint32_t ms);

#endif

main.c

/**
  ******************************************************************************
  * @file    Project/STM32F10x_StdPeriph_Template/main.c 
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */  

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>
#include"gpio.h"
int main(void)
{
	MX_GPIO_Init();
	while(1)
	{
			GPIO_WriteBit(GPIOC,  GPIO_Pin_6,Bit_RESET);//默认输出低电平
			delay(500);
			GPIO_WriteBit(GPIOC,  GPIO_Pin_6,Bit_SET);//默认输出高电平
			delay(500);
			GPIO_WriteBit(GPIOC,  GPIO_Pin_7,Bit_RESET);//默认输出低电平
			delay(500);
			GPIO_WriteBit(GPIOC,  GPIO_Pin_7,Bit_SET);//默认输出高电平
			delay(500);
			GPIO_WriteBit(GPIOC,  GPIO_Pin_8,Bit_RESET);//默认输出低电平
			delay(500);
			GPIO_WriteBit(GPIOC,  GPIO_Pin_8,Bit_SET);//默认输出高电平
			delay(500);
			GPIO_WriteBit(GPIOC,  GPIO_Pin_7|GPIO_Pin_8,Bit_RESET);//默认输出低电平
			delay(500);
			GPIO_WriteBit(GPIOC, GPIO_Pin_7|GPIO_Pin_8,Bit_SET);//默认输出高电平
			delay(500);
			GPIO_WriteBit(GPIOC,  GPIO_Pin_6|GPIO_Pin_8,Bit_RESET);//默认输出低电平
			delay(500);
			GPIO_WriteBit(GPIOC, GPIO_Pin_6|GPIO_Pin_8,Bit_SET);//默认输出高电平
			delay(500);
		
	}
	
}

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

常见问题与调试技巧

  • 时钟未使能导致初始化失败。
  • 模式选择错误(如输入误配为输出)。
  • 使用逻辑分析仪或万用表验证信号。

总结

强调标准库在快速开发中的优势,建议结合数据手册(如《STM32参考手册》)深入理解寄存器与库函数的关联。通过观察原理图找到等所在引脚,通过所在的引脚去配置,并分析灯的有效电平是高电平还是低电平.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值