GPIO输入-外电检测

前言

(1)本系列是基于STM32的项目笔记,内容涵盖了STM32各种外设的使用,由浅入深。

(2)小编使用的单片机是STM32F105RCT6,项目笔记基于小编的实际项目,但是博客中的内容适用于各种单片机开发的同学学习和使用。

学习目标

  1. 外电检测电路原理的分析。
  2. 外电检测程序代码的开发,掌握GPIO口输入模式的配置。
  3. 实验效果:外电连接LED1亮,外电断开 LED1灭。

外电检测硬件原理图

原理分析

外电的状态是通过PB1端口来检测的。 那分别分析PB1 在没有外电输入和有外电输入的状态。

(1)外电断开

PB1 通过下拉电阻R55 接地,PB1输入低电平。

(2)外电输入端口连接5V供电

R55/(R54+R55) = VR55(A点) / 5V (VR54+R55)

PB1的电压值为:VR55 =5*200 /(100+200) = 3.33V,高电平。

程序实现--外电状态检测

外电检测GPIO的初始化

端口定义: 外电检测的端口是PB1
复制代码
// AC Check Pin
#define CHECK_ACSTATE_PORT       GPIOB
#define CHECK_ACSTATE_PIN           GPIO_Pin_1

PB1的初始化GPIO的初始化:

复制代码
void hal_GpioConfig_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE); 	
	
	GPIO_InitStructure.GPIO_Pin = CHECK_ACSTATE_PIN;     
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //浮空输入
	GPIO_Init(CHECK_ACSTATE_PORT, &GPIO_InitStructure);	
	
        AcState = (en_AcLinkSta)hal_GPIO_GetACState();  /// 
} 

上拉,下拉,悬空方式的选择:

选择浮空输入模式

复制代码
typedef enum
{ GPIO_Mode_AIN = 0x0,//模拟输入
  GPIO_Mode_IN_FLOATING = 0x04,//浮空输入
  GPIO_Mode_IPD = 0x28,//上拉输入
  GPIO_Mode_IPU = 0x48,//下拉输入
  GPIO_Mode_Out_OD = 0x14,//通用开漏输出
  GPIO_Mode_Out_PP = 0x10,//通用推挽输出
  GPIO_Mode_AF_OD = 0x1C,//复用开漏输出
  GPIO_Mode_AF_PP = 0x18//复用推挽输出
}GPIOMode_TypeDef;

如果GPIO模式选择: 上拉输入, 则在外电掉电的状态下 PB1 也是高电平。

GPIO模式选择上拉输入时,Rdo不存在,此时电路中只有其他3个电阻,不论外电连接或断开,PB1均被上拉电阻拉高,为高电平。

如果GPIO模式选择: 下拉输入, 则在外电连接的状态下 PB1的电平会变小。

GPIO模式选择下拉输入时,Rup不存在,此时电路中只有其他3个电阻,R55 和RDO 并联之后整体的阻值变小, R54不变。根据串联电路分压, PB1的电压会变小。

常用的GPIO输入库函数

GPIO 常用输入函数
复制代码
//读取单个输入端口的数据
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);

定义外电状态枚举类型变量

复制代码
typedef enum
{
	 STA_AC_BREAK = 0,
	  STA_AC_LINK,
}en_AcLinkSta;

外电检测函数

复制代码
// 获取PB1端口状态(高低电平)
static unsigned char hal_GPIO_GetACState(void)
{
	return (GPIO_ReadInputDataBit(CHECK_ACSTATE_PORT,  CHECK_ACSTATE_PIN ));		
}
void delay_1msTest(void)
{
	unsigned int i=0;
	i = 72000;
	while(i--);   
}

外电检测函数任务
返回值   外电的状态
en_AcLinkSta hal_Gpio_AcStateCheck(void)
{
	en_AcLinkSta state;
	static unsigned char times = 0;	//静态延时计数
	state = (en_AcLinkSta)hal_GPIO_GetACState();//记录第一次检测到的外电状态
	delay_1msTest();
	if(state == AcState)
	{如果本次获取的状态和上次一样,则清零延时计数
		times	= 0;
	}
	else if(state != AcState)
  {///如果状态有变化
		times	++; //计数增加
		if(times > 20)
		{如果不一样的状态计数超过20次  则更新 AcState 状态。
			times = 0;
			AcState = state;
		}
	}
	return AcState;///
}
///

hal_GPIO.h代码

复制代码
#ifndef ____HAL_GPIO_H_
#define ____HAL_GPIO_H_
 
// AC Check Pin
#define CHECK_ACSTATE_PORT       GPIOB
#define CHECK_ACSTATE_PIN        GPIO_Pin_1

typedef enum
{
		STA_AC_BREAK = 0,
	  STA_AC_LINK,
}en_AcLinkSta;

void hal_GpioConfig_init(void);
en_AcLinkSta hal_Gpio_AcStateCheck(void);

#endif
//

hal_GPIO.c代码

复制代码
#include "stm32F10x.h"
#include "hal_GPIO.H"

static unsigned char hal_GPIO_GetACState(void);

static en_AcLinkSta AcState;// 外电的状态静态全局变量

/GPIO 初始化函数
void hal_GpioConfig_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE); 	
	
	GPIO_InitStructure.GPIO_Pin = CHECK_ACSTATE_PIN;     
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //浮空输入
	GPIO_Init(CHECK_ACSTATE_PORT, &GPIO_InitStructure);	
	
  AcState = (en_AcLinkSta)hal_GPIO_GetACState();  ///上电获取外电的状态   
}

// 获取PB1端口状态(高低电平)
static unsigned char hal_GPIO_GetACState(void)
{
	return (GPIO_ReadInputDataBit(CHECK_ACSTATE_PORT, GPIO_Pin_1));		
}
void delay_1msTest(void)
{
	unsigned int i=0;
	i = 7200;
	while(i--);   
}


en_AcLinkSta hal_Gpio_AcStateCheck(void)
{
	en_AcLinkSta state;
	static unsigned char times = 0;	//静态延时计数
	
	state = (en_AcLinkSta)hal_GPIO_GetACState();
	
	delay_1msTest();
	if(state == AcState)
	{如果本次获取的状态和上次一样,则清零延时计数
		times	= 0;
	}
	else if(state != AcState)
  {///如果状态有变化
		times	++; //计数增加
		if(times > 20)
		{如果不---样的状态计数超过20次 则更新 Acstate 状态。
			times = 0;
			AcState = state;
		}
	}
	return AcState;///
}
///

修改main函数

复制代码
#include "stm32f10x.h"
#include "hal_timer.h"
#include "hal_led.h"
#include "hal_gpio.h"

int main(void)
{
	hal_LedInit();
	hal_GpioConfig_init();
//	hal_timerInit();
  while (1)
  {		
		if(hal_Gpio_AcStateCheck() == STA_AC_BREAK)
		{
			GPIO_ResetBits(LED7_PORT,LED7_PIN);
		}
		else
		{	
			GPIO_SetBits(LED7_PORT,LED7_PIN);			
		}
  }
}
相关推荐
small_wh1te_coder6 分钟前
硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
linux·c语言·汇编·嵌入式硬件·算法·c
花落已飘1 小时前
STM32中实现shell控制台(shell窗口输入实现)
stm32·单片机·嵌入式硬件
花落已飘1 小时前
STM32中实现shell控制台(命令解析实现)
stm32·shell
没有钱的钱仔1 小时前
STM32低功耗模式全面指南
css·stm32·css3
牵牛老人3 小时前
Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
stm32·单片机·qt
宇钶宇夕4 小时前
针对工业触摸屏维修的系统指南和资源获取途径
单片机·嵌入式硬件·自动化
黑听人4 小时前
【力扣 简单 C】70. 爬楼梯
c语言·leetcode
杜子不疼.4 小时前
二分查找,乘法口诀表,判断闰年,判断素数,使用函数实现数组操作
c语言
和风化雨4 小时前
stm32的三种开发方式
stm32·单片机·嵌入式硬件
kanhao1005 小时前
三态逻辑详解:单片机GPIO、计算机总线系统举例
单片机·嵌入式硬件