当前位置:网站首页>STM32学习总结(二)——GPIO

STM32学习总结(二)——GPIO

2022-08-11 05:25:00 LIGAZN菜鸟

一、GPIO是什么?

GPIO的全称是General-Purpose Input /Output Ports,中文意思是通用IO端口。GPIO是单片机的最基本功能之一,也是我们学习单片机最基础的部分。顾名思义,GPIO具有输入和输出功能,无论是输入还是输出,都有高电平和低电平两种形式。下面我们就来介绍一下GPIO的配置。
STM32F103ZET6有112个GPIO端口,他们分别是GPIOA——GPIOG,每组各有16个GPIO端口(0:15)。

1.GPIO的输入模式

图片: !
GPIO的输入模式主要有四种,浮空输入,上拉输入,下拉输入和模拟输入,都可以通过软件配置成要用的模式。

2.GPIO的输出模式

输出模式有四种,开漏输出,推挽式输出,推挽式复用功能,开漏复用功能。通俗来说,推挽式输出高电平就是高电平,输出低电平就是低电平,而开漏输出输出低电平就是低电平,输出高电平还要看输出1时要看上拉还是下拉电阻,这个上下拉可以配置。平时用的最多的就是推挽输出。而复用推挽输出和复用开漏输出指的是GPIO口被用作第二功能时的配置情况(并非作为通用IO口使用),比如在配置串口的TXD端口时,就需要把模式配置为复用推挽输出。

二、GPIO的配置

1.使能时钟

在使用GPIO之前,我们先要使能对应GPIO的时钟,STM32F103ZET6的GPIO都是挂在APB2总线上的,所以我们要调用APB2时钟使能函数使能相应的IO端口。

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);

2.初始化IO口(配置IO端口)

下面给出一段代码,配置IO端口为推挽输出模式,输出速率为50MHZ

	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);

STM32中文参考手册给出了各个外设配置时应该选择的GPIO模式,如果不清楚该怎么配置,可以直接查阅该表。
在这里插入图片描述

3.输出高低电平

	GPIO_SetBits(GPIOE,GPIO_Pin_5); //输出低电平为GPIO_ReSetBits

4.跑马灯实验

接下来就是著名的点灯大师的操作,下面以跑马灯为例,使用通用IO的输入和输出功能

	void LED_Init()//配置I/O端口
{
    
// 库函数操作
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_5); 
	
	GPIO_Init(GPIOE,&GPIO_InitStructure);
	GPIO_SetBits(GPIOE,GPIO_Pin_5); 
// 寄存器操作
// *RCC->APB2ENR|=1<<3;//时钟使能
// RCC->APB2ENR|=1<<6;
// GPIOB->CRL&=0XFF0FFFFF;
// GPIOB->CRL|=0X00300000;
// GPIOB->ODR|=1<<5;
// GPIOE->CRL&=0XFF0FFFFF;
// GPIOE->CRL|=0X00300000;
// GPIOE->ODR|=1<<5;//设置I/O口模式
}

主函数为

		while(1)
	{
    
	  LED1=1;
		LED2=0;
		delay_ms(300);
		LED1=0;
		LED2=1;
		delay_ms(300);
	}

这样就实现跑马灯的功能了,其实就是交替控制连接跑马灯的IO口输出高低电平。

三、IO中断

具有112个IO端口的大容量芯片,最多可以在配置16个外部中断。在这里插入图片描述
外部中断的意思就是在IO口的输入电平是我们想要的变化时(上升沿或者下降沿)就触发中断,这个可以用来检测按键的按下和测量脉冲数量。下面给出一段使用外部来检测按键按下的程序。

void EXTIX_Init(void)
{
    
 
   	EXTI_InitTypeDef EXTI_InitStructure;
 	  NVIC_InitTypeDef NVIC_InitStructure;

    KEY_Init();	 // 按键端口初始化

  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟



   //GPIOE.3 中断线以及中断初始化配置 下降沿触发 //KEY1
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
  	EXTI_InitStructure.EXTI_Line=EXTI_Line3;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_Init(&EXTI_InitStructure);	  	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

   //GPIOE.4 中断线以及中断初始化配置 下降沿触发 //KEY0
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
  	EXTI_InitStructure.EXTI_Line=EXTI_Line4;
  	EXTI_Init(&EXTI_InitStructure);	  	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器


   //GPIOA.0 中断线以及中断初始化配置 上升沿触发 PA0 WK_UP
 	  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); 

  	EXTI_InitStructure.EXTI_Line=EXTI_Line0;
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  	EXTI_Init(&EXTI_InitStructure);		//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器


  	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//使能按键WK_UP所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;					//子优先级3
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure); 

  	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;			//使能按键KEY1所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子优先级1 
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);  	  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

  	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;			//使能按键KEY0所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;					//子优先级0 
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);  	  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
 
}

值得注意的是,在配置外部中断时需要使能AFIO时钟,这里顺便提一下,什么时候要使能AFIO时钟,我们从《STM32中文参考手册_V10》中找到:对寄存器 AFIO_EVCR、AFIO_MAPR 和 AFIO_EXTICRX 进行读写操作前,应当首先打开 AFIO 的时钟,这些寄存器是用于“事件控制”、“重映射”、“调试IO配置”、“外部中断”的。例如 AFIO_EXTICRX 用于选择 EXTIx 外部中断的输入源。
关于外部中断的部分就讲到这里,后续还会更新中断篇,会在那里更详细地记录自己的理解。

总结

GPIO的使用在单片机开发中很常见,使用起来也很简单,就是使能时钟然后根据需要配置模式即可,在使用任意一个IO之前都要记得事先配置IO才能使用,这一点经常忘记。这次的学习总结就记录到这里,请各位大佬批评指正。

原网站

版权声明
本文为[LIGAZN菜鸟]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_58838850/article/details/126228818