当前位置: 首页 > article >正文

STM32 对射式红外传感器配置

这次用的是STM32F103的开发板(这里面的exti.c文件没有how to use this driver 配置说明)

对射式红外传感器

由一个红外发光二极管和NPN光电三极管组成,M3固定安装孔,有输出状态指示灯,输出高电平灯灭,输出低电平灯亮。有遮挡,输出高电平。无遮挡,输出低电平。使用3.3-5VDC 宽电压LM393比较器输出,信号干净,波形好,驱动能力强,超过15mA。输出形式:数字开关量输出(0和1)。广泛用于电机转速检测,脉冲计数,位置限位等。

引脚:

VCC:接电源正极3.3V-5V

GND:接电源负极

DO:TTL开关信号输出

AO:此模块不起作用

操作说明:

1、接好VCC和GND,模块电源指示灯会亮
2、模块槽中无遮挡时,接收管导通,模块DO输出低电平,开关指示灯亮;遮挡时,DO输出高电平,开关指示灯灭。
3、模块DO可与继电器相连,组成限位开关等功能,也可以与有源蜂鸣器模块相连,组成报警器。
4、DO输出接口可以与单片机10口直接相连,一般接外部中断,检测传感器是否有遮档,如用电机码盘则可检测电机的转速。

原理:

测距离: 测速传感器输出为脉冲信号,一个脉冲中断一次;红外射线导通的时候是低电平,所以我们设置中断为低电平触法模式。一般码盘上有整数格子,无论是多少格其实原理一样,例如10格码盘,也就是有10个空格子,电机转一圈后便是射线导通10次,外部低电平触法10次;安装上面的思路,我们的测速传感器就可以发挥出效果了,我们知道一圈就有10个中断,于是我们计算中断次数,得到的总次数除于10也就是电机转动次数了,然后按照轮子的周长,计算轮子一圈是多长,就可以推算出小车已经跑多远了。

测速度: 按照测距离的思路,我们用一个MCU定时器计算,1秒内接收多少个外部中断,例如一秒内接收了20个外部中断,我们就可以判断小车速度为1秒小车轮子转两圈,然后再计算出小车轮子的周长,就可得知小车1秒行驶的速度。

接线图:

代码配置:

分为GPIO配置、中断线与GPIO引脚的连接、EXTI配置、NVIC配置(与上一章的按键中断一样)

EXTI函数解析:

//调用它,就可以把EXTI的配置都清除,恢复成上电的默认的状态
void EXTI_DeInit(void);

//调用这个函数,就可以根据这个结构体里的参数配置EXTI外设,初始化EXTI要用到这个函数
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

//调用这个函数,可以把参数传递的结构体变量赋一个默认值
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);

//这个函数是用来软件触发外部中断的,调用这个函数,参数给一个指定的中断线,就能软件触发一次外部中断
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);

在外设运行的过程中,会产生一些状态标志位   比如外部中断来了,会有一个挂起的寄存器置了一个标志位,对于其他外设,如串口收到数据,会置标志位,定时器时间到也会置标志位,这些标志位都是放在状态寄存器的,当程序想要看这些标志位时,就会用到这四个函数

FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);//可以获取指定的标志位是否被置1

void EXTI_ClearFlag(uint32_t EXTI_Line);//可以对置1的标志位进行清除

//在中断函数里,如果你想查看标志位和清除标志位,用下面两个函数
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);//获取中断标志位是否被置1

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);//清除中断挂起标志位

总结:如果想要在主程序里查看和清除标志位,就用上面两个函数。

           如果想要在中断函数里查看和清除标志位,就用下面两个函数。

NVIC函数解析:

//这个函数是用来中断分组的,参数是中断分组的方式
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

//根据结构体里面指定的参数初始化NVIC
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

//设置中断向量表
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);

//系统低功耗配置
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);

代码:

void CountSensor_Init(void)
{
	//------------------------定义结构体变量-----------------------------------
	
	GPIO_InitTypeDef GPIO_InitStructure;								//定义GPIO结构体变量
	EXTI_InitTypeDef EXTI_InitStructure;								//定义EXTI结构体变量
	NVIC_InitTypeDef NVIC_InitStructure;								//定义NVIC结构体变量
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启GPIO的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//开启AFIO的时钟
	
	//---------------------GPIO配置--------------------------------------
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;			//模式选择上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;   			//配置引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //速率
	GPIO_Init(GPIOB,&GPIO_InitStructure);	                //GPIO初始化
	
	//---------------------GPIO配置--------------------------------------
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//将中断线与GPIO引脚连接
	//---------------------EXTI配置--------------------------------------
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line14; 					//配置中断线
	EXTI_InitStructure.EXTI_LineCmd =  ENABLE;  					//中断使能
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 	        //选择中断模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;         //下降沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	//---------------------EXTI配置--------------------------------------
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组,这里放到模块函数里了,一般情况放在主函数第一行(如上一章按键中断)
	
	//---------------------NVIC配置--------------------------------------
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;				//选择中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;					    //使能中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;		    //抢占优先级配置
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;					//响应优先级配置
	
	NVIC_Init(&NVIC_InitStructure);
	
	//---------------------NVIC配置--------------------------------------
	
}

中断函数:

uint16_t CountSensor_Count;
//中断函数
void EXTI15_10_IRQHandler(void)
{
	//判断中断标志位是否为 1 EXTI_GetITStatus的返回值为 SET(1)  或者RESET(0)
	if(EXTI_GetITStatus(EXTI_Line14) == SET)
	{
		//判断电平,以免发生抖动
		if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14) == 0)
		{
		CountSensor_Count++;
		}
		//中断标志位置1,程序就会跳转到中断函数,
		//如果不清除中断标志位,就会一直申请中断,这样就会不断响应中断,执行中断函数,
		//程序就会卡死在中断函数里,所以每次中断程序结束后,都应该清除一下中断标志位
		EXTI_ClearITPendingBit(EXTI_Line14);
		
	}
	
}

//返回值
uint16_t CountSensor_Get(void)
{
	return CountSensor_Count;
}

主函数:

功能:挡住传感器模块槽,OLDE显示数字变化+1

#include "CountSensor.h"
int main(void)
{
	LED_Init();
	OLED_Init();
	CountSensor_Init();
	OLED_ShowString(1, 1, "Count:");
	while(1)
    {
	
	
	    OLED_ShowNum(1, 7, CountSensor_Get(),5);

    }	
	
}


 


http://www.kler.cn/a/523761.html

相关文章:

  • 【Julia】Julia预编译与外部库:从崩溃到完美集成
  • [STM32 - 野火] - - - 固件库学习笔记 - - -十三.高级定时器
  • CMAKE工程编译好后自动把可执行文件传输到远程开发板
  • SVG 矩形:深入理解与实际应用
  • LabVIEW纤维集合体微电流测试仪
  • 2025.1.26机器学习笔记:C-RNN-GAN文献阅读
  • Excel - Binary和Text两种Compare方法
  • 高效学习方法分享
  • 9.8 实战:使用 GPT Builder 开发定制化 ChatGPT 应用
  • 使用 Go 和 gqlgen 实现 GraphQL API:实战指南
  • NodeJs / Bun 分析文件编码 并将 各种编码格式 转为 另一个编码格式 ( 比如: GB2312→UTF-8, UTF-8→GB2312)
  • 【论文推荐|深度学习,滑坡检测,多光谱影像,自然灾害,遥感】2022年Landslide4Sense竞赛成果:基于多源卫星影像的先进滑坡检测算法研究(五)
  • 【某大厂一面】数组和链表区别
  • MATLAB绘图:动态波浪图
  • lwIP——4 网络接口
  • [MySQL]事务的隔离级别原理与底层实现
  • 2.策略模式(Strategy)
  • 如何使用Git进行版本控制?
  • 单细胞分析基础-第一节 数据质控、降维聚类
  • NLP自然语言处理通识
  • 前端25.1.26学习记录
  • IDM-VTON本地部署教程:双重编码 + 文字提示,解锁真实野外试穿
  • 【Elasticsearch】 索引模板 ignore_missing_component_templates
  • 【自学嵌入式(6)天气时钟:软硬件准备、串口模块开发】
  • 一文大白话讲清楚webpack进阶——5——dev-server原理及其作用
  • 【信息系统项目管理师-选择真题】2010上半年综合知识答案和详解