stm32-GPIO相关介绍与一些功能

本文详细介绍了STM32F10x中GPIO的工作模式,包括操作步骤、输出输入函数的实现,如LED控制和按钮输入处理,以及相关的延时函数。展示了如何配置GPIO、控制GPIO引脚电平并实现简单的LED闪烁和按钮控制逻辑。
摘要由CSDN通过智能技术生成

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

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

三.相关输入函数与功能


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

  1. GPIOGeneral 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很多地方理解的不够深入,如果你发现错误或者哪里没有理解请告诉我

  • 29
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值