实验二红外测距传感器实验.docx
《实验二红外测距传感器实验.docx》由会员分享,可在线阅读,更多相关《实验二红外测距传感器实验.docx(21页珍藏版)》请在冰豆网上搜索。
实验二红外测距传感器实验
信息工程学院实验报告
成绩:
指导教师(签名):
课程名称:
传感器原理及应用
实验工程名称:
实验二 红外测距传感器实验实验时间:
2016.10.8
班级:
:
学号:
一、实验目的
1.学习CC2530单片机ADC模块的使用。
2.学习红外测距传感器的使用。
二、实验原理
1.CC2530节点与红外测距传感器的硬件接口
红外线测距传感器模块GP2Y0A21YK0F
(1).红外测距传感器模块(GP2Y0A21YK0F)引脚
OUT:
模拟量输出接口(AD模块)
GND:
外接GND
VCC:
数字量输出接口(0和1)外接5V电源
(2).传感器模块与CC2530模块之间的连接
2.ADC
(1).简介
CC2530单片机的ADC支持多达14位的模拟数字转换,具有多达12位的ENOB〔有效数字位〕。
它包括一个模拟多路转换器,具有多达8个各自可配置的通道;以及一个参考电压发生器。
转换结果通过DMA写入存储器。
还具有假设干运行模式。
ADC模块的方框图如下所示:
ADC的主要特性如下:
●可选的抽取率,这也设置了分辨率〔7到12位〕
●8个独立的输入通道,可承受单端或差分信号
●参考电压可选为部单端、外部单端、外部差分或AVDD5
●产生中断请求
●转换完毕时的DMA触发
●温度传感器输入
●电池测量功能
(2).存放器简介
本次实验中主要涉及到ADC模块的存放器:
数据的换算:
例如:
在CC2530中配置ADC的参考电压为AVDD5(3.3V),抽取率为512(12位有效数据),由于在实验中采用单端转换方式,所以实际数据只有11位。
这时,ADC采集到的数据记为x,那么
ADC采集数据转换为电压(单位:
V):
V=x*3.3/2048
3.GP2Y0A21YK0F红外测距传感器
(1).概述
夏普GP2Y0A21YK0F测距传感器是基于PSD的微距传感器,其有效的测量距离在80cm,有效的测量角度大于40度,输出信号为模拟电压,在0到8cm左右的围与距离成正比非线性关系,在10-80cm的距离成反比非线性关系,平均功耗为30mA,反响时间约为5ms,并且对背景光及温度的适应性较强。
GP2Y0A21YK0F传感器的默认的测距分辨率为1mm。
由于GP2Y0A21YK0F传感器采用的是PSD光信号调制法,因此其输出的信号电压并不是标准的直流电压,而是叠加了波幅约为0.2V,频率1KHz的方波,由于波幅到达0.2V,这就影响了分辨率。
如果不进展信号处理,分辨率的精度仅能到达1mm。
而如果经过有效处理,在正常情况下可以到达0.1mm以上的精度,完全可以满足一般工程定距等方面的需求。
Sharp的红外传感器都是基于一个原理,三角测量原理。
红外发射器按照一定的角度发射红外光束,当遇到物体以后,光束会反射回来,反射回来的红外光线被CCD检测器检测到以后,会获得一个偏移值L,利用三角关系,在知道了发射角度a,偏移距L,中心矩X,以及滤镜的焦距f以后,传感器到物体的距离D就可以通过几何关系计算出来了。
传感器特点:
●根本不受背景光及温度的影响,能满足大局部工程应用的性能要求,有很高的性价比,具有很好的工程应用价值。
(2).使用方法
本实验利用CC2530的ADC模块采集红外测距传感器输出的模拟电压数据,然后换算成电压值,在根据数据手册上的特性曲线,如下列图所示:
将特性曲线通过MATLAB可以拟合出计算公式,直接根据电压值计算出距离,假设测量出的电压为voltage(V),待测距离为distance(cm),那么distance=26.757*voltage^-1.236。
三、实验容与步骤
1.将仿真器的一端JTAG接口与一个CC2530模块相连,并翻开CC2530节点的电源,再将仿真器的另一端用USB接口与PC计算机相连。
2.用MiniUSB线将CC2530节点与计算机的USB口连接起来后,翻开串口调试器软件,设置波特率57600,校验位None,数据位8,停顿位1,然后点击翻开串口按钮,如下列图所示:
说明:
串口号可以在设备管理器看到,具体方法如下列图所示:
3.用IAREmbeddedWorkbenchfor80518.10翻开配套传感器实中的“SerialPort.Edition\18.IRDMS\Main.eww〞工程文件。
4.点击IAR功能菜单上的绿色下载按钮
,进入程序下载页面,如下列图所示:
5.程序下载完成后,点击IAR开发环境中的运行程序按钮运行程序,如下列图所示:
此外,也可以通过点击其它按钮实现对当前程序的调试(单步、断点、暂停、步入等功能)。
6.扩展实验
为了能够更加直观地观察到传感器工作的状况,在实验过程中可以利用光盘中配套的上位机软件CurveDisplay来观察传感器的数据曲线。
操作步骤
(1).将仿真器的一端JTAG接口与一个CC2530模块相连,并翻开CC2530节点的电源,再将仿真器的另一端用USB接口与PC计算机相连。
(2).用MiniUSB线将CC2530节点与计算机的USB口连接起来后,翻开配套传感器实验中的“CurveDisplay\CurveDisplay.exe〞上位机软件,选择正确的串口号后,再设置波特率57600,校验位None,数据位8,停顿位1,最后点击翻开连接按钮,如下所示:
(3).用IAREmbeddedWorkbenchfor80518.10翻开配套传感器实验中的“Curve.Edition\18.IRDMS\Main.eww〞工程文件,然后通过IAR将程序下载到CC2530模块中。
程序下载完成后,点击IAR开发环境中的运行程序按钮运行程序。
四、实验结果及分析:
1.程序正常运行后,每采集一次传感器数据,红色LED闪烁一下,与此同时串口调试器显示信息〔功能扩展,实现按键按一下传感器采样一次〕
如下列图所示:
2.在实验过程中,将传感器水平正对着墙壁或障碍物远离移动,可以在串口调试软件上看到相应ADC采集到的电压数据也发生相应的变化,其数值越小说明两者之间的距离越大。
3.扩展实验现象
(1).程序正常运行后,在CurveDisplay软件中可以观察到传感器的数据曲线,如下列图所示:
(2).在实验过程中,将传感器水平正对着墙壁或障碍物远离移动,可以在CurveDisplay软件上的传感器数据曲线也发生相应的变化,如下列图所示:
五、实验总结:
通过这次学习和操作,我学到了对CC2530单片机ADC模块的使用,并懂的了红外测距传感器的使用。
以及通过自己对其功能扩展,实现按键控制传感器的采样。
这次的实验操作让我受益匪浅。
六、源程序清单〔加上必要的注释〕
主要代码如下:
#include
#include
//GPIO_LED定义(1:
点亮,0:
熄灭)
#defineGPIO_GLEDP1_0
#defineGPIO_RLEDP1_1
//GPIO_KEY定义(0:
被按下,1:
未按下)
#defineGPIO_SW1P1_2
#defineGPIO_SW2P1_3
voidInitClock(void)//初始化时钟
{
unsignedinti;
//turnon16MHzRCand32MHzXOSC
SLEEPCMD&=~0x04;
//waitfor32MHzXOSCstable
while(!
(SLEEPSTA&0x40));
//chipbugworkaround
asm("nop");
//延时63us
for(i=0;i<504;i++)
{
asm("nop");
}
//Select32MHzXOSCandthesourcefor32Kclock
CLKCONCMD=0x00;
//Waitforthechangetobeeffective
while(CLKCONSTA!
=0x00);
//turnoff16MHzRC
SLEEPCMD=0x80;
}
voidInitGPIO(void)//初始化GPIO
{
//GPIO_RLED引脚(P1_0,通用IO,输出)
P1SEL&=~0x01;
P1DIR|=0x01;
//GPIO_GLED引脚(P1_1,通用IO,输出)
P1SEL&=~0x02;
P1DIR|=0x02;
//GPIO_SW1引脚(P1_2,通用IO,输入)
P1SEL&=~0x04;
P1DIR&=~0x04;
//GPIO_SW2引脚(P1_3,通用IO,输入)
P1SEL&=~0x08;
P1DIR&=~0x08;
}
voidInitUART(void)//初始化串口USART0
{
//P0[5..2]配置为外设IO
P0SEL|=0x3C;
//USART0I/Olocation:
Alternative2location
PERCFG&=~0x01;
//UARTmode
U0CSR|=0x80;
//无流控制,无校验,1位停顿位,8位数据位,起始位为低电平,停顿位为高电平
U0UCR=0x02;
//波特率57600
U0GCR|=0x0A;
U0BAUD=216;
//使能串口接收器
U0CSR|=0x40;
}
voidUART_SendStr(constunsignedchar*str)//通过串口发送字符串
{
while(*str)
{
//发送一个字符
U0DBUF=*str++;
//等待发送完毕
while(!
UTX0IF);
//去除发送中断标志
UTX0IF=0;
}
}
voidFloat2Str(void*str,floatNum,unsignedcharFractLen)//将float型数据转换为字符串(FractLen:
小数位数1-6)
{
unsignedchar*ptr=((unsignedchar*)str);
unsignedcharFractCache[6]={'\0'};
unsignedchari=FractLen,j;
unsignedchartmp;
unsignedcharsign=(unsignedchar)(Num<0);
unsignedlongtrunc;//整数局部
unsignedlongfract;//小数局部(4位)
if(sign)
{
Num*=-1;
}
trunc=(unsignedlong)Num;
fract=(unsignedlong)((Num-(unsignedlong)Num)*1000000);
//处理小数局部
if(fract==0)
{
ptr[i++]='0';
}
else
{
for(j=0;j<6;j++)
{
FractCache[j]=(unsignedchar)((fract%10)+'0');
fract/=10;
}
}
//调整小数位数
for(j=0;j{
ptr[FractLen-1-j]=FractCache[6-1-j];
}
//添加小数点
ptr[i++]='.';
//处理整数局部
if(trunc==0)
{
ptr[i++]='0';
}
while(trunc>0)
{
ptr[i++]=(unsignedchar)((trunc%10)+'0');
trunc/=10;
}
//添加符号位
if(sign)
{
ptr[i++]='-';
}
//字符串逆序输出
for(j=0;j<(i/2);j++)
{
tmp=ptr[j];
ptr[j]=ptr[(i-j)-1];
ptr[(i-j)-1]=tmp;
}
//添加字符串完毕符
ptr[i]='\0';
}
voidDelayXus(unsignedintXus)//延时Xus
{
while(Xus--)
{
asm("nop");
asm("nop");
asm("nop");
}
}
voidDelayXms(unsignedintX)//延时Xms
{
while(X--)
{
//延时1ms
DelayXus(1000);
}
}
voidInitADC(void)//初始化ADC
{
//P0.1配置为外设IO
P0SEL|=0x02;
//P0.1配置为模拟IO
APCFG|=0x02;
}
unsignedintADC_ReadVal(void)//通过ADC读取P0.1的电压数据
{
intval;
//ADC参考电压:
AVDD5Pin
ADCCON3|=0x80;
//512decimationrate(12bitsENOB)
ADCCON3|=0x30;
//Singlechannel:
AIN1
ADCCON3&=~0x0F;
ADCCON3|=0x01;
//Waitfortheconversiontobedone
while(!
(ADCCON1&0x80));
//Readtheresult(最高位为符号位)
val=(unsignedint)ADCL;
val|=(unsignedint)(ADCH<<8);
//Treatsmallnegativeas0
val=val<0?
0:
val;
//12位有效数据(由于单端转换,所以实际数据11位)
val=val>>4;
returnval;
}
voidmain(void)
{
unsignedcharcache[16];
unsignedintval;
floatvoltage;
//初始化时钟
InitClock();
//初始化IO
InitGPIO();
//初始化串口USART0
InitUART();
//初始化ADC
InitADC();
//关闭GPIO_RLED和GPIO_GLED
GPIO_RLED=0;
GPIO_GLED=0;
//发送串口初始化成功消息
UART_SendStr("\nUSART0InitSuccessfully!
\n");
while
(1)
{
//点亮GPIO_RLED
GPIO_RLED=1;
//通过ADC读取P0.1的电压数据
if(GPIO_SW1)
{GPIO_RLED=0;}
else{
val=ADC_ReadVal();
//换算为电压值
voltage=val*3.3/2048;
//发送ADC采集到的数据
UART_SendStr("Voltage(V):
");
//最多保存三位小数
Float2Str(cache,voltage,3);
UART_SendStr(cache);
UART_SendStr(",Distance(cm):
");
//换算成距离值(cm)并最多保存两位小数
//6cm~80cm之间拟合公式:
distance=26.757*voltage^-1.236
Float2Str(cache,26.757*pow(voltage,-1.236),2);
UART_SendStr(cache);
UART_SendStr("\n");
//关闭GPIO_RLED
//GPIO_RLED=0;
}
//延时350ms
DelayXms(350);
}
}