深入了解STM32-GPIO的相关介绍和功能

一.GPIO的工作模式,通常的操作步骤

二.相关输出函数及功能实现

三.相关输入函数与功能


1.GPIO的工作模式,通常的操作步骤

  1. GPIO(General Purpose Input Output)通用输入输出口,可配置为8种输出输入方式。
  2. 引脚电压0~3.3V,部分引脚可容忍5V。
  3. 使用GPIO时通常先用RCC开启GPIO时钟,之后利用函数初始化GPIO(代码见下),最后控制GPIO口即可。(如LED灯,蜂鸣器)

#include "stm32f10x.h"                  // Device header


/*实现芯片上LED的点亮与熄灭*/
int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//配置时钟
	
	GPIO_InitTypeDef GPIO_InitStruture;//定义结构体给他起名,赋值
	GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruture.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOC,&GPIO_InitStruture);//配置定时器,需要结构体参数
	
//	GPIO_SetBits(GPIOC,GPIO_Pin_13);//设置高电平——暗
	GPIO_ResetBits(GPIOC,GPIO_Pin_13);//设置低电平——亮
	while(1)
	{
		
	}
}

2.相关输出函数及功能实现

  1. GPIO的输出函数可再库函数中自己查看详情信息,我只简单介绍一下
  2. void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
    void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
  3. 前两个函数用于将指定位分别设置成高低电平。
  4. 第三个函数可以选中想要控制的端口之后设置端口,第四个函数直接对16个端口进行写入。
  5. 利用以上函数可以实现LED的闪烁以及LED流水灯(以led闪烁为例),注意面包板上引脚位置,和代码的GPIO设定,代码如下
    #include "stm32f10x.h"
    
    /**
      * @brief  微秒级延时
      * @param  xus 延时时长,范围:0~233015
      * @retval 无
      */
    void Delay_us(uint32_t xus)
    {
    	SysTick->LOAD = 72 * xus;				//设置定时器重装值
    	SysTick->VAL = 0x00;					//清空当前计数值
    	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
    	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
    	SysTick->CTRL = 0x00000004;				//关闭定时器
    }
    
    /**
      * @brief  毫秒级延时
      * @param  xms 延时时长,范围:0~4294967295
      * @retval 无
      */
    void Delay_ms(uint32_t xms)
    {
    	while(xms--)
    	{
    		Delay_us(1000);
    	}
    }
     
    /**
      * @brief  秒级延时
      * @param  xs 延时时长,范围:0~4294967295
      * @retval 无
      */
    void Delay_s(uint32_t xs)
    {
    	while(xs--)
    	{
    		Delay_ms(1000);
    	}
    } 

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置时钟注意GPIO
	
	GPIO_InitTypeDef GPIO_InitStruture;//定义结构体给他起名,赋值,注意结构式是地址
	GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruture.GPIO_Pin = GPIO_Pin_0;//选择memner
	GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruture);//配置定时器,需要结构体参数
	
//	GPIO_SetBits(GPIOA,GPIO_Pin_0);//LED高电平不亮
//	GPIO_ResetBits(GPIOA,GPIO_Pin_0);//低电平,亮
//	GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);//置低电平
//	GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);//置高电平
	
	while(1)
	{
		/*通过上方函数实现led闪烁,此时led长脚接的正极*/
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);
		Delay_ms(500);
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);
		Delay_ms(500);
	}
}

3.相关输入函数与功能

  1. stm32中的数据类型与c语言有所不同,通过typedef函数对数据类型换了一个名字用来简化操作,新名如下:
  • 2.利用新的名字定义了如下的读取函数,也是只简单介绍一下

  • uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
    uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
  • 第一个函数用于读取数据寄存器某一个端口的值;
  • 第二个函数可以读取整个数据寄存器,这两个函数都时用来读取GPIO口用的
  • 后面这两个函数与上方类似,但是是在输出模式下,用于查看自己输出的是什么
  • 3.可使用上方函数实现按钮控制LED灯,相关代码如下

    #include "stm32f10x.h"                  // Device header
    
    
    /**
      *@brief    根据引脚初始化LED,默认是点亮状态,可以去除注释关闭
      *@param 无
      *@retval  无
      */
    void LED_Init(void)
    {
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置时钟注意GPIO
    	
    	/*定义结构体*/
    	GPIO_InitTypeDef GPIO_InitStruture;
    	GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP;
    	GPIO_InitStruture.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
    	GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOA,&GPIO_InitStruture);
    	
    //	GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);
    }
    
    /**
      *@brief    引脚1的led点亮与熄灭
      *@param 1亮0灭
      *@retval 无 
      */
    void LED1_ctrl(uint8_t a)
    {
    	if(a)
    	{
    		GPIO_SetBits(GPIOA,GPIO_Pin_1);
    	}else GPIO_ResetBits(GPIOA,GPIO_Pin_1);
    }
    
    /**
      *@brief    引脚2的led点亮与熄灭
      *@param 1亮0灭
      *@retval 无 
      */
    void LED2_ctrl(uint8_t a)
    {
    	if(a)
    	{
    		GPIO_SetBits(GPIOA,GPIO_Pin_2);
    	}else GPIO_ResetBits(GPIOA,GPIO_Pin_2);
    }
    
    /**
    *@brief    按下同一按钮后取反不亮
      *@param 无
      *@retval  无
      */
    void LED1_Turn(void)
    {
    	/*使用if中的函数读取当前端口的输出状态,输出为0置1,否之置0,实现电平翻转*/
    	if( GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1) == 0)
    	{
    		GPIO_SetBits(GPIOA,GPIO_Pin_1);//亮
    	}
    	else GPIO_ResetBits(GPIOA,GPIO_Pin_1);//不亮
    }
    void LED2_Turn(void)
    {
    	if( GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2) == 0)
    	{
    		GPIO_SetBits(GPIOA,GPIO_Pin_2);
    	}
    	else GPIO_ResetBits(GPIOA,GPIO_Pin_2);
    }
    
    

    #include "stm32f10x.h"                  // Device header
    #include "Delay.h"
    
    void Key_Init(void)
    {
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//配置时钟注意GPIO
    	
    	/*定义结构体*/
    	GPIO_InitTypeDef GPIO_InitStruture;
    	GPIO_InitStruture.GPIO_Mode = GPIO_Mode_IPU;//按钮配置成上拉输入
    	GPIO_InitStruture.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
    	GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOB,&GPIO_InitStruture);
    }
    
    /**
      *@brief    读取按钮,读取PB的值,PB1是1,PB11是2
      *@param 无
    *@retval  按下后1或2,不按0
      */
    uint8_t Key_Gotnum(void)
    {
    	uint8_t Keynum=0;
    	if( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)//如果按键按下
    	{
    		/*经典消抖*/
    		Delay_ms(20);
    		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0);
    		Delay_ms(20);
    		Keynum=1;
    	}
    	if( GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0)//如果按键按下
    	{
    		/*经典消抖*/
    		Delay_ms(20);
    		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0);
    		Delay_ms(20);
    		Keynum=2;
    	}
    	return Keynum;
    }
    
    
    #include "stm32f10x.h"                  // Device header
    #include "Delay.h"
    #include "LED.h"
    #include "key.h"
    
    static uint8_t keynum;
    
    int main(void)
    {	
    	LED_Init();
    	Key_Init();
    	while(1)
    	{
    		/*通过keynum的值控制两个led*/
    		keynum = Key_Gotnum();
    		if (keynum == 1)
    		{
    			LED1_Turn();
    		}
    		if (keynum == 2)
    		{
    			LED2_Turn();
    		}
    	}
    }
    

    最后,由于本人刚刚学习stm32很多地方理解的不够深入,如果你发现错误或者哪里没有理解请告诉我

    作者:numbers0410

    物联沃分享整理
    物联沃-IOTWORD物联网 » 深入了解STM32-GPIO的相关介绍和功能

    发表评论