STM32标准库学习------GPIO

GPIO简介

---------------------------------------------------------------------------------------------------------------------------------

  • GPIO(General Purpose Input Output)通用输入输出口
  • 可配置为8种输入输出模式
  • 引脚电平:0V~3.3V,部分引脚可容忍5V
  • 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等
  • 输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

---------------------------------------------------------------------------------------------------------------------------------

 GPIO基本结构

  GPIO位结构

 GPIO模式

  • 通过配置GPIO的端口配置寄存器,端口可以配置成以下8种模式

浮空/上拉/下拉输入

模拟输入

开漏/推挽输出

复用开漏/推挽输出

 代码测试

---------------------------------------------------------------------------------------------------------------------------------

LED灯闪烁(连线图+代码)

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

int main(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式:推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				//GPIO引脚:Pin_0
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度:50MHz
	GPIO_Init(GPIOA, &GPIO_InitStructure);
		
	while (1)
	{
		/*GPIO_ResetBits设置低电平,GPIO_SetBits设置高电平*/
		GPIO_ResetBits(GPIOA, GPIO_Pin_0);					//将GPIOA_Pin_0设置为低电平
		Delay_ms(500);										
		GPIO_SetBits(GPIOA, GPIO_Pin_0);					//将GPIOA_Pin0设置为高电平
		Delay_ms(500);										
		
		/*GPIO_WriteBit设置低/高电平,由Bit_RESET/Bit_SET指定*/
		GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);		//将GPIOA_Pin_0设置为低电平
		Delay_ms(500);										
		GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);			//将GPIOA_Pin_0设置为高电平
		Delay_ms(500);										
		
		/*GPIO_WriteBit设置低/高电平,由数据0/1指定,数据需要强转为BitAction类型*/
		GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);		//将Pin_0设置为低电平
		Delay_ms(500);										
		GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);		//将Pin_0设置为高电平
		Delay_ms(500);	

		/*GPIO_Write设置GPIOA16位*/
		GPIO_Write(GPIOA, ~0x0001);							//将GPIOA_Pin_0设置为低电平,其它设置为高电平
		Delay_ms(500);										
		GPIO_Write(GPIOA, 0x0001);							//将GPIOA_Pin_0设置为高电平,其它设置位低电平
		Delay_ms(500);		
	}
}

LED流水灯(连线图+代码)

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

int main(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式:推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;				//GPIO引脚:Pin_All(所有引脚)
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度:50MHz
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
	
	while (1)
	{		
		/*使用GPIO_Write,同时设置GPIOA所有引脚的高低电平(32位),实现LED流水灯*/
		GPIO_Write(GPIOA, ~0x0001);	//0000 0000 0000 0001,GPIOA_Pin_0引脚为低电平,其它为高电平
		Delay_ms(100);				                       
		GPIO_Write(GPIOA, ~0x0002);	//0000 0000 0000 0010,GPIOA_Pin_1引脚为低电平,其它为高电平
		Delay_ms(100);				                      
		GPIO_Write(GPIOA, ~0x0004);	//0000 0000 0000 0100,GPIOA_Pin_2引脚为低电平,其它为高电平
		Delay_ms(100);				                       
		GPIO_Write(GPIOA, ~0x0008);	//0000 0000 0000 1000,GPIOA_Pin_3引脚为低电平,其它为高电平
		Delay_ms(100);				                      
		GPIO_Write(GPIOA, ~0x0010);	//0000 0000 0001 0000,GPIOA_Pin_4引脚为低电平,其它为高电平
		Delay_ms(100);				                      
		GPIO_Write(GPIOA, ~0x0020);	//0000 0000 0010 0000,GPIOA_Pin_5引脚为低电平,其它为高电平
		Delay_ms(100);				                       
		GPIO_Write(GPIOA, ~0x0040);	//0000 0000 0100 0000,GPIOA_Pin_6引脚为低电平,其它为高电平
		Delay_ms(100);				                       
		GPIO_Write(GPIOA, ~0x0080);	//0000 0000 1000 0000,GPIOA_Pin_7引脚为低电平,其它为高电平
		Delay_ms(100);				
	}
}

 蜂鸣器(连线图+代码)

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

int main(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式:推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;              //GPIO引脚:Pin_12
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //GPIO速度:50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);
		
	while (1)
	{
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//GPIOB_Pin_12设置为低电平,蜂鸣器鸣叫
		Delay_ms(100);							
		GPIO_SetBits(GPIOB, GPIO_Pin_12);		//GPIOB_Pin_12设置为高电平,蜂鸣器停止
		Delay_ms(100);							
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//GPIOB_Pin_12设置为低电平,蜂鸣器鸣叫
		Delay_ms(100);							
		GPIO_SetBits(GPIOB, GPIO_Pin_12);		//GPIOB_Pin_12设置为高电平,蜂鸣器停止
		Delay_ms(700);							
	}
}

按键控制LED灯(连线图+代码)

 (LED.h + LED.c)

#ifndef __LED_H
#define __LED_H

void LED_Init(void);
void LED_On(uint8_t Num);
void LED_Off(uint8_t Num);
void LED_Turn(uint8_t Num);

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

/**
  * 函    数:LED初始化
  * 参    数:NULL
  * 返 回 值:NULL
  */
void LED_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;			//GPIO模式:推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;		//GPIO引脚:Pin_1、Pin_2
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//GPIO速度:50MHz
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/*设置GPIO初始化后的默认电平*/
	GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);				//Pin_1、Pin_2设置为高电平(LED默认关闭)
}

/**
  * 函    数:LED开启
  * 参    数:uint8_t Num
  * 返 回 值:NULL
  */
void LED_On(uint8_t Num)
{
	if (1 == Num)
	{
		GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);			//GPIOA_Pin_1设置为低电平
	}
	if (2 == Num)
	{
		GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);			//GPIOA_Pin_2设置为低电平
	}
}

/**
  * 函    数:LED关闭
  * 参    数:uint8_t Num
  * 返 回 值:NULL
  */
void LED_Off(uint8_t Num)
{
	if (1 == Num)
	{
		GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);				//GPIOA_Pin_1设置为高电平
	}
	if (2 == Num)
	{
		GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);				//GPIOA_Pin_2设置为高电平
	}
}

/**
  * 函    数:LED状态翻转
  * 参    数:uint8_t Num
  * 返 回 值:NULL
  */
void LED_Turn(uint8_t Num)
{
	if (1 == Num)
	{
		if (!GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1))			//读取GPIO输出数据寄存器的状态,如果GPIOA_Pin_1输出为低电平
		{
			GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET);			//GPIOA_Pin_1设置为高电平
		}
		else
		{
			GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET);		//GPIOA_Pin_1设置为低电平
		}
	}
	if (2 == Num)
	{
		if (!GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2))			//读取GPIO输出数据寄存器的状态,如果GPIOA_Pin_2输出为低电平
		{
			GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_SET);			//GPIOA_Pin_2设置为高电平
		}
		else
		{
			GPIO_WriteBit(GPIOA, GPIO_Pin_2, Bit_RESET);		//GPIOA_Pin_2设置为低电平
		}
	}
}

(Delay.h + Delay.c)

#ifndef __DELAY_H
#define __DELAY_H

void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);

#endif
#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);
	}
} 

 (Key.h + Key.c)

#ifndef __KEY_H
#define __KEY_H

void Key_Init(void);
uint8_t Key_GetNum(void);

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

/**
  * 函    数:按键初始化
  * 参    数:NULL
  * 返 回 值:NULL
  */
void Key_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;		
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;				//GPIO模式:上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;		//GPIO引脚:Pin_1、Pin_11
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//GPIO速度:50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}	

/**
  * 函    数:按键获取键码值
  * 参    数:NULL
  * 返 回 值:按下按键的键码值,范围:0~2,返回0代表没有按键按下
  * 注意事项:此函数是阻塞式操作,当按键按住不放时,函数会卡住,直到按键松手
  */
uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;											//定义变量,默认键码值为0
	
	if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1))				//读取GPIO输入数据寄存器的状态,如果GPIOB_Pin_1输出为低电平,则表示按键1按下
	{
		Delay_ms(20);											//延时消抖(按键抖动大概10~15ms)
		while (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1));      //等待按键松手,读取GPIO输入数据寄存器的状态,如果GPIOB_Pin_1输出为低电平,则表示按键1未松手
		Delay_ms(20);                                           //延时消抖(按键抖动大概10~15ms)
		KeyNum = 1;                                             //键码值为1
	}
	
	if (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11))				//读取GPIO输入数据寄存器的状态,如果GPIOB_Pin_11输出为低电平,则代表按键2按下
	{
		Delay_ms(20);											//延时消抖(按键抖动大概10~15ms)
		while (!GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11));		//等待按键松手,读取GPIO输入数据寄存器的状态,如果GPIOB_Pin_11输出为低电平,则表示按键2未松手
		Delay_ms(20);                                           //延时消抖(按键抖动大概10~15ms)
		KeyNum = 2;                                             //键码值为2
	}
	return KeyNum;												//返回键码值,如果没有按键按下,键码为默认值0
}

(main.c)

#include "stm32f10x.h"                  // Device header
#include "LED.h"
#include "Key.h"

uint8_t KeyNum;						//接收按键键码值

int main(void)
{
	/*模块初始化*/
	LED_Init();						//LED初始化
	Key_Init();						//按键初始化
	
	while (1)
	{
		KeyNum = Key_GetNum();		//获取按键键码值
		
		if (1 == KeyNum)			//如果按键1按下
		{
			LED_Turn(1);			//LED1灯状态翻转
		}
		if (2 == KeyNum)			//如果按键2按下
		{
			LED_Turn(2);			//LED2灯状态翻转
		}
	}
}

光敏电阻控制蜂鸣器(连线图+代码)

(Puzzer.h + Puzzer.c)

#ifndef __PUZZER_H
#define __PUZZER_H

void Puzzer_Init(void);
void Puzzer_On(void);
void Puzzer_Off(void);
void Puzzer_Turn(void);

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

/**
  * 函    数:蜂鸣器初始化
  * 参    数:NULL
  * 返 回 值:NULL
  */
void Puzzer_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
	 
	/*GPIO初始化*/	
	GPIO_InitTypeDef GPIO_InitStructure;			            
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;            //GPIO模式:推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;                  //GPIO引脚:Pin_12
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;           //GPIO速度:50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	/*设置GPIO初始化后的默认电平*/
	GPIO_SetBits(GPIOB, GPIO_Pin_12);							//GPIOB_Pin_12设置为高电平(蜂鸣器默认关闭)
}

/**
  * 函    数:蜂鸣器开启
  * 参    数:NULL
  * 返 回 值:NULL
  */
void Puzzer_On(void)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET);				//GPIOB_Pin_12设置为低电平
	//GPIO_ResetBits(GPIOB, GPIO_Pin_12):
}

/**
  * 函    数:蜂鸣器关闭
  * 参    数:NULL
  * 返 回 值:NULL
  */
void Puzzer_Off(void)
{
	GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET);					//GPIOB_Pin_12设置为高电平
	//GPIO_SetBits(GPIOB, GPIO_Pin_12);
}

/**
  * 函    数:蜂鸣器状态翻转
  * 参    数:NULL
  * 返 回 值:NULL
  */
void Puzzer_Turn(void)
{
	if (!GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_12))			//读取GPIO输出寄存器的状态,如果GPIOB_Pin_12输出低电平
	{
		GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET);				//GPIOB_Pin_12设置为高电平
	}
	else
	{
		GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET);			//GPIOB_Pin_12设置为低电平
	}

}

(LDR.h + LDR.c)

#ifndef __LDR_H
#define __LDR_H

void LDR_Init(void);
uint8_t LDR_GetNum(void);

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

/**
  * 函    数:光敏传感器初始化
  * 参    数:NULL
  * 返 回 值:NULL
  */
void LDR_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;				//GPIO模式:上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;                  //GPIO引脚:Pin_13
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;           //GPIO速度:50MHz
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/**
  * 函    数:获取光敏传感器输出电平
  * 参    数:无
  * 返 回 值:光敏传感器输出的电平,范围:0/1
  */
uint8_t LDR_GetNum(void)
{
	return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);			//读取GPIO输入寄存器的状态,并返回GPIOB_Pin_13电平:0/1
}	

(main.c)

#include "stm32f10x.h"                  // Device header
#include "Puzzer.h"
#include "LDR.h"

int main(void)
{
	/*模块初始化*/
	Puzzer_Init();					//蜂鸣器初始化
	LDR_Init();						//光敏传感器初始化
	
	while (1)
	{
		if (1 == LDR_GetNum())		//如果光敏传感器输出为1
		{
			Puzzer_On();			//蜂鸣器开启
		}
		else
		{
			Puzzer_Off();			//蜂鸣器关闭
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值