GPIO输入输出

一、GPIO(General Purpose Input Output)通用输入输出口

1、可配置为8种输入输出模式

2、引脚电平:0V~3.3V,部分引脚可容忍5V

3、输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等

(1)LED:发光二极管,正向通电点亮,反向通电不亮

(2)有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定

(3)无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音

4、输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

(1)按键:常见的输入设备,按下导通,松手断开

按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动

(2)传感器模块:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出

5、在STM32中,所有的GPIO都是挂载在APB2外设总线上的

二、LED闪烁

1、按照以下接线方式连接,并将STLINK插到电脑上

2、新建一个STM32工程

操作STM32的GPIO总共需要3个步骤

        (1)使用RCC开启GPIO的时钟

        (2)使用GPIO_Init函数初始化GPIO

        (3)使用输出或者输入的函数控制GPIO口

这里总共涉及了RCC和GPIO两个外设

RCC库函数

GPIO库函数

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

用结构体的参数来初始化GPIO口,先定义一个结构体变量,然后再给结构体赋值,后调用这个函数,这个函数内部就自动读取结构体的值,再自动把外设各个参数配置好

void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
GPIO_StructInit函数,这个函数可以把结构体变量赋值一个默认值

 3、编写代码

(1)添加延时函数

 

并将新建的文件夹在keil软件中添加组和文件

 配置工程选项

 (2)声明头文件

(3)编写LED闪烁代码

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

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//开启时钟
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;	//推挽输出
	GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0;	//GPIOA外设的0号引脚
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;	//输出速度50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//GPIO_ResetBits(GPIOA,GPIO_Pin_0);	//低电平 led亮
	//GPIO_SetBits(GPIOA,GPIO_Pin_0);	//高电平 led灭
	//GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);//led亮
	//GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);	//led灭
	while(1)
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_0);	//低电平 led亮
		Delay_ms(500);
		GPIO_SetBits(GPIOA,GPIO_Pin_0);	//高电平 led灭
		Delay_ms(500);
		
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);//led亮
		Delay_ms(100);
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);	//led灭
		Delay_ms(100);
		
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)0);//led亮 强制类型转换 0类型转换为枚举类型
		Delay_ms(500);
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)1);	//led灭 强制类型转换 1类型转换为枚举类型
		Delay_ms(500);
	}
}

(4)实现效果

LED闪烁

三、LED流水灯

1、按照以下接线方式连接,并将STLINK插到电脑上

2、复制LED闪烁的工程

利用按位或的操作方式,对多个引脚进行同时设置

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ;	//GPIOA外设的0~7号引脚

GPIO_Write的使用 

  3、编写代码

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

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//开启时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;	//推挽输出
	GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ;	//GPIOA外设的0~7号引脚
	//GPIO_InitStructure.GPIO_Pin= GPIO_Pin_All;
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;	//输出速度50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	while(1)
	{
		GPIO_Write(GPIOA,~0X0001);	//0000 0000 0000 0001 这16个二进制分别对应PA0到PA15总共16个端口,低电平亮,所以按位取反
		Delay_ms(500);
		GPIO_Write(GPIOA,~0X0002);	//0000 0000 0000 0010
		Delay_ms(500);
		GPIO_Write(GPIOA,~0X0004);	//0000 0000 0000 0100
		Delay_ms(500);
		GPIO_Write(GPIOA,~0X0008);	//0000 0000 0000 1000
		Delay_ms(500);
		GPIO_Write(GPIOA,~0X0010);	//0000 0000 0001 0000
		Delay_ms(500);
		GPIO_Write(GPIOA,~0X0020);	//0000 0000 0010 0000
		GPIO_Write(GPIOA,~0X0040);	//0000 0000 0100 0000
		Delay_ms(500);
		GPIO_Write(GPIOA,~0X0080);	//0000 0000 1000 0000
		Delay_ms(500);
		
	}
}

4、实现效果

LED流水灯

四、蜂鸣器

1、按照以下接线方式连接,并将STLINK插到电脑上

 2、复制LED闪烁的工程

编写代码

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

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);	//开启时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;	//推挽输出
	GPIO_InitStructure.GPIO_Pin= GPIO_Pin_12;	//GPIOB外设的12号引脚
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;	//输出速度50MHz
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	while(1)
	{
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);	//低电平 buzzer响
		Delay_ms(100);
		GPIO_SetBits(GPIOB,GPIO_Pin_12);	//高电平 buzzer关
		Delay_ms(100);
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);	//低电平 buzzer响
		Delay_ms(100);
		GPIO_SetBits(GPIOB,GPIO_Pin_12);	//高电平 buzzer关
		Delay_ms(700);
	}
}

实现效果

蜂鸣器

五、按键控制LED

1、按照以下接线方式连接,并将STLINK插到电脑上

2、在工程上完成LED和按键的驱动代码

将驱动代码封装在另外的.c和.h文件里(利用模块化编程的方式)

(1)打开工程文件夹,新建一个Hardware文件夹,用来存放硬件驱动

(2)打开keil,打开工程管理,添加组

(3)配置工程选项

(4)在新建文件夹中添加.c和.h文件

.c文件(用来存放驱动程序的主体代码)

.h文件 (用来存放这个驱动程序对外提供的函数或变量的声明)

 

 (5)写驱动代码

 在主函数上面写上LED模块的头文件

(6)用同样的方法把按键封装在驱动函数模块里

3、编写代码

(1)main.c

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

uint8_t ButtonNum;

int main(void)
{
	LED_Init();
	Button_Init();
	
	while(1)
	{
		ButtonNum=Button_GetNum();
		if(ButtonNum==1)
		{
			LED1_Turn();
		}
		if(ButtonNum==2)
		{
			LED2_Turn();
		}
	}
}

(2)LED.c

#include "stm32f10x.h"                  // Device header

void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);
}


void LED1_ON(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}

void LED1_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_1);
}

void LED1_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1) == 0)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_1);	//高电平 LED1灭
	}
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_1);	//低电平 LED1亮
	}
}

void LED2_ON(void)
{
	GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}

void LED2_OFF(void)
{
	GPIO_SetBits(GPIOA,GPIO_Pin_2);
}

void LED2_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2) == 0)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_2);	//高电平 LED2灭
	}
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_2);	//低电平 LED2亮
	}
}


 (3)LED.h

#ifndef __LED_H
#define __LED_H

void LED_Init(void);
void LED1_ON(void);
void LED1_OFF(void);
void LED1_Turn(void);
void LED2_ON(void);
void LED2_OFF(void);
void LED2_Turn(void);

#endif

(4)button.c

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

void Button_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;	//上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

uint8_t Button_GetNum(void)
{
	uint8_t ButtonNum =0;
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);
		Delay_ms(20);
		ButtonNum=1;
	}
	
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0);
		Delay_ms(20);
		ButtonNum=2;
	}
	
	return ButtonNum;
}


(5)button.h

#ifndef __BUTTON_H
#define __BUTTON_H

void Button_Init(void);
uint8_t Button_GetNum(void);

#endif

4、实现效果

按键控制LED

六、光敏传感器控制蜂鸣器

1、按照以下接线方式连接,并将STLINK插到电脑上

 2、封装蜂鸣器

(1)buzzer.c

#include "stm32f10x.h"                  // Device header

void Buzzer_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB,GPIO_Pin_12);
}

void Buzzer_ON(void)
{
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}

void Buzzer_OFF(void)
{
	GPIO_SetBits(GPIOB,GPIO_Pin_12);
}

void Buzzer_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_12) == 0)
	{
		GPIO_SetBits(GPIOB,GPIO_Pin_12);
	}
	else
	{
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);
	}
}

 (2)buzzer.h

#ifndef __BUZZER_H
#define __BUZZER_H

void Buzzer_Init(void);
void Buzzer_ON(void);
void Buzzer_OFF(void);
void Buzzer_Turn(void);

#endif

(3)LightSensor.c

#include "stm32f10x.h"                  // Device header

void LightSensor(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

uint8_t LightSensor_Get(void)
{
	return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13);
}

(4)LihtSensor.h

#ifndef __LIGHT_SENSOR_H
#define __LIGHT_SENSOR_H

void LightSensor(void);
uint8_t LightSensor_Get(void);


#endif

3、编写代码

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


int main(void)
{
	Buzzer_Init();
	LightSensor_Init();
	
	while(1)
	{
		if(LightSensor_Get() == 1)    //比较暗的情况
		{
			Buzzer_ON();
		}
		else
		{
			Buzzer_OFF();
		}
	}
}

4、实现效果

光敏传感器控制蜂鸣器

七、GPIO的使用方法

1、初始化时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx,ENABLE);    //x为A、B等

2、定义结构体

GPIO_InitTypeDef GPIO_InitStructure;

3、赋值结构体

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;    //选择8种输入输出模式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_x;        //x为0、1、2等引脚号,可以用按位或选择多个引脚
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//选择输出速度

4、初始化外设

GPIO_Init(GPIOx,&GPIO_InitStructure);    //x为A、B等,将指定的GPIO外设初始化好

5、8个读取和写入的函数

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);
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);

6、模块化编程

因为自己做产品,外围硬件较多,就要把每个硬件的驱动函数单独提取出来,封装在.c和.h文件里,有利于简化主函数的逻辑

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值