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);			
		}
  }
}
相关推荐
艾芯微科技2 小时前
HR911130C|汉仁 HANRUN 集成变压器千兆 RJ45 网口参数、电路、PCB 布线、替代与采购避坑
网络·单片机·嵌入式硬件·集成测试·51单片机
白搞电子4 小时前
ESP-Mosaico 黑胶轮滑动画与音乐编排:从设备原型到电脑预览工作台
单片机·嵌入式硬件
新晨单片机设计4 小时前
S028C-基于STM32单片机WIFI智能电表(温度)【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus·wifi智能电表
1234567890@world5 小时前
正点原子 ATK-DLRK3568 嵌入式Linux系统开发手册V1.3 详细总结
linux·stm32·单片机
Navigator_Z5 小时前
LeetCode //C - 1301. Number of Paths with Max Score
c语言·算法·leetcode
女神下凡6 小时前
芯参谋(68):ADC模数转换器电路设计指南
arm开发·单片机·嵌入式硬件·硬件工程·设计规范
学逆向的6 小时前
C 多文件开发
c语言·开发语言·网络安全
学逆向的7 小时前
C 内存属性
c语言·开发语言·算法·网络安全
Zwawa7 小时前
一盏 LED 不够用了:让同一盏灯说出不同的话
c语言·单片机·嵌入式
芯岭技术郦7 小时前
入门级 32 位 MCU,PY32F002B
单片机·嵌入式硬件