红外测距传感器(GP2D12、74HC595、ADC0832)

红外测距传感器GP2D12

    • 应用
    • 要做的项目
    • 原理
    • 仿真效果图
    • 74HC595的作用(串入)
    • 项目目录
    • ADC0832X.c(延用之前的,但注意CS、CLK、DIO所对应的端口发生了变化)
    • 74HC595.c(像装水一样,装满了溢出到下一个74HC595)
    • mainX.c(主函数)

应用

汽车雷达(倒车、开车时,在一定的距离内遇到障碍物会发出报警声)

要做的项目

描述:数码管显示距离值的GP2D12仿真测距警报器
功能:将红外传感器感知距离用LCD显示距离值,在小于30cm时,发出报警

原理

发送红外线、接收红外线
红外测距传感器(GP2D12、74HC595、ADC0832)_第1张图片
距离和电压的关系是:随着距离的增大,电压是先升后降
红外测距传感器(GP2D12、74HC595、ADC0832)_第2张图片
将距离R产生的电压V(模拟信号)传到ADC0832,ADC0832会把电压值V转化为数字值,然后可根据公式计算将数字值转化为距离R(以下是计算公式)
红外测距传感器(GP2D12、74HC595、ADC0832)_第3张图片
红外测距传感器(GP2D12、74HC595、ADC0832)_第4张图片

仿真效果图

红外测距传感器(GP2D12、74HC595、ADC0832)_第5张图片

红外测距传感器(GP2D12、74HC595、ADC0832)_第6张图片

74HC595的作用(串入)

可想象成一群人排队入座,假设有3个人,3个座位;
第一个人进去坐第一个位;
当第二个人进来时,第一个人坐第2个位,第二个人坐第一个位;
当第三个人进来时,第一个人坐第3个位,第二个人坐第2个位,第三个人坐第3个位;

如:1111_1010,先从高位读起,则左边的1先进,然后按上面的原理,接着是下一个1进来

项目目录

红外测距传感器(GP2D12、74HC595、ADC0832)_第7张图片

ADC0832X.c(延用之前的,但注意CS、CLK、DIO所对应的端口发生了变化)

#include	   
#include   
#include     
#include

#define INT8U  unsigned char
#define INT16U unsigned int
#define INT32U unsigned long

sbit CS=P0^2;	  
sbit CLK=P0^1;	     
sbit DIO=P0^0;

INT8U Get_AD_Result()
{	 
	INT8U i=0,dat1=0x00,dat2=0x00;
	CS=0;//片选
	CLK=0;_nop_();_nop_();
	DIO=1;//启动0832
	CLK=1;_nop_();_nop_();	


	CLK=0;_nop_();_nop_();
	DIO=1;//选择单通道还是双通道
	CLK=1;_nop_();_nop_();

	CLK=0;_nop_();_nop_();
	DIO=0;//选择0还是1通道
	CLK=1;_nop_();_nop_();

	CLK=0; DIO=1;_nop_();_nop_(); //释放总线,准备采集
	for(i=0;i<8;i++)//下降沿采集数据,从高位到低位
	{
		CLK=1;_nop_();_nop_(); 
		CLK=0; _nop_();_nop_();
		dat1=(dat1<<1)|((INT8U)DIO);
	}	
	for(i=0;i<8;i++)//下降沿采集数据,从低位到高位
	{
		dat2=(dat2)|(((INT8U)DIO)<<i);	
		CLK=1;_nop_();_nop_(); 
		CLK=0; _nop_();_nop_();
	}
	_nop_();_nop_();
	CS=1;//0832片选结束
	if(dat2==dat1)	//如果两个数据相等,就输出
		return dat1;
	else
		return 0;
}//5v 255	126 3.24 324
/*
INT16U Digit_Convert_Analog(INT8U dat)
{
	INT16U AnalogValue=0x0000;//   x*500/256=y
	AnalogValue=(INT16U)((dat*500.0)/256.0);
	return AnalogValue;
}
*/

74HC595.c(像装水一样,装满了溢出到下一个74HC595)

#include
#include
#include
#include

#define INT8U unsigned char
#define INT16U unsigned int
#define INT32U unsigned long

sbit DS = P3^5; //数据串行输入端 (看图即可)
sbit SH_CP = P3^6; //数据串行输入移位时钟信号,上升沿有效
sbit ST_CP = P3^7; //数据并行输出时钟信号,上升沿有效

//串入函数(串型输入)
void serialInputData(INT8U dat)
{
	INT8U i = 0;
	for(i=0; i<8; i++)
	{
		if(dat&0x80) //1000_0000	通过与让它从高位开始读 (取最高位)
			DS=1;	  //高电平
		else
			DS=0;	  //低电平
		
		dat=dat<<1;	//左移动一位:本来1111_0101 变成了 111_0101
		SH_CP=0; _nop_();_nop_();
		SH_CP=1; _nop_();_nop_();
	}
	SH_CP=0; _nop_();_nop_();
}

//并出函数	(把8位数据一下放到锁存器中,即放到了第一个7段数码管)
void paralledOutputData()
{
	ST_CP=0; _nop_();_nop_();
	ST_CP=1; _nop_();_nop_();
	ST_CP=0; _nop_();_nop_();	
}

mainX.c(主函数)

#include	   
#include   
#include     
#include

#define INT8U  unsigned char
#define INT16U unsigned int
#define INT32U unsigned long
#define MC 1388	 //对应公式表的常量值
#define BC -5	 //对应公式表的常量值
#define KC 2	 //对应公式表的常量值

INT8U code segment7[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};	 //共阴极7段数码管
INT8U numstr[4];	  //表示有3个7段数码管
sbit beeppin = P1^0;	//P1^0连的是一个小喇叭(蜂鸣器)

//导入函数
extern INT8U Get_AD_Result();	   	//获取ADC0832的转化结果函数
extern void serialInputData(INT8U dat);	 //串入函数
extern void paralledOutputData();	    //并出函数

//蜂鸣器发声函数
void beep()
{
	INT8U i=0, j=150;
	beeppin = 1;
	for(i=0; i<60; i++)
	{
		beeppin = !beeppin;	   //一会是0一会是1
		j=150;		//j值越高音频越高
		while(j--);
	}
}

//获取距离的函数(根据公式计算将ADC0832采集的数字值转化为距离R)
float getDistance()
{
	float d=0.00, sum=0, avg=0;
	INT8U i=0;
	
	for(i=0; i<10; i++)		 //采集10次
	{
		sum = sum + Get_AD_Result();
	}
	avg = (INT8U)(sum/10.0);  //采集总数  除以 10.0(平均值)
	d = ( (MC*1.0) / ((avg+BC)*1.0) ) - (KC*1.0);	  //这里用的是公式2
	return d;
}

//数值转换为十进制的函数
void distance2numstr(float d)
{
	INT16U dis = (INT16U)(d*10); 	 //数值从float型强制转换为int整数型
	numstr[0] = dis/100+'0';		//取百位,并且把它变成字符型
	numstr[1] = ((dis/10)%10)+'0';	//取十位,并且把它变成字符型
	numstr[2] = dis%10+'0';			//取个位,并且把它变成字符型
}

void main()
{
	float dis = 0;
	while(1)
	{
		dis = getDistance();	//获取距离
		if(dis<30)	//当距离小于30时蜂鸣器发声
			beep();
		distance2numstr(dis); //距离转换为十进制
		//串入
		serialInputData(~segment7[numstr[2]-'0']);		//第一个进去的放到最后一个74HC595,减'0'是为了让字符变成数值,而因为仿真中是共阳极,所以要用~把共阴极数码管转值一下
		serialInputData((~segment7[numstr[1]-'0'])&0x7F);  // &0x7F的作用是打一个小数点
		serialInputData(~segment7[numstr[0]-'0']);
		//并出
		paralledOutputData();
	}
}

注:数值显示上可能会有一定的误差
红外测距传感器(GP2D12、74HC595、ADC0832)_第8张图片

喜欢的朋友可以关注我的个人公众号,后台回复java资料、单片机、安卓可免费领取资源。
红外测距传感器(GP2D12、74HC595、ADC0832)_第9张图片

你可能感兴趣的:(DSP)