当前位置:文档之家› 实验二红外测距传感器实验

实验二红外测距传感器实验

信息工程学院实验报告课程名称:传感器原理及应用实验项目名称:实验二红外测距传感器实验实验时间:2016.10.8 班级:姓名:学号:一、实验目的1. 学习CC2530 单片机ADC 模块的使用。

2. 学习红外测距传感器的使用。

二、实验原理1. CC2530节点与红外测距传感器的硬件接口红外线测距传感器模块GP2Y0A21YK0F 成绩:指导老师(签名):(1). 红外测距传感器模块(GP2Y0A21YK0F)引脚OUT:模拟量输出接口(AD 模块)GND:外接GNDVCC:数字量输出接口(0 和1) 外接5V 电源(2). 传感器模块与CC2530 模块之间的连接2. ADC(1). 简介CC2530单片机的ADC支持多达14位的模拟数字转换,具有多达12位的ENOB(有效数字位)。

它包括一个模拟多路转换器,具有多达8个各自可配置的通道;以及一个参考电压发生器。

转换结果通过DMA写入存储器。

还具有若干运行模式。

ADC模块的方框图如下所示:ADC的主要特性如下:●可选的抽取率,这也设置了分辨率(7到12位)●8个独立的输入通道,可接受单端或差分信号●参考电压可选为内部单端、外部单端、外部差分或A VDD5 ●产生中断请求●转换结束时的DMA触发●温度传感器输入●电池测量功能(2). 寄存器简介本次实验中主要涉及到ADC模块的寄存器:数据的换算:例如:在CC2530 中配置ADC 的参考电压为A VDD5(3.3V),抽取率为512(12 位有效数据),由于在实验中采用单端转换方式,所以实际数据只有11 位。

这时,ADC 采集到的数据记为x,则ADC采集数据转换为电压(单位:V):V = x * 3.3 / 20483. 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. 用IAR Embedded Workbench for 8051 8.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). 用IAR Embedded Workbench for 8051 8.10 打开配套传感器实验中的“Curve.Edition\18.IRDMS\Main.eww”工程文件,然后通过IAR 将程序下载到CC2530 模块中。

程序下载完成后,点击IAR 开发环境中的运行程序按钮运行程序。

四、实验结果及分析:1. 程序正常运行后,每采集一次传感器数据,红色LED 闪烁一下,与此同时串口调试器显示信息(功能扩展,实现按键按一下传感器采样一次)如下图所示:2. 在实验过程中,将传感器水平正对着墙壁或障碍物远离移动,可以在串口调试软件上看到相应ADC 采集到的电压数据也发生相应的变化,其数值越小说明两者之间的距离越大。

3. 扩展实验现象(1). 程序正常运行后,在CurveDisplay 软件中可以观察到传感器的数据曲线,如下图所示:(2). 在实验过程中,将传感器水平正对着墙壁或障碍物远离移动,可以在CurveDisplay 软件上的传感器数据曲线也发生相应的变化,如下图所示:五、实验总结:通过这次学习和操作,我学到了对CC2530 单片机ADC 模块的使用,并懂的了红外测距传感器的使用。

以及通过自己对其功能扩展,实现按键控制传感器的采样。

这次的实验操作让我受益匪浅。

六、源程序清单(加上必要的注释)主要代码如下:#include <ioCC2530.h>#include <math.h>//GPIO_LED定义(1:点亮,0:熄灭)#define GPIO_GLED P1_0#define GPIO_RLED P1_1//GPIO_KEY定义(0:被按下,1:未按下)#define GPIO_SW1 P1_2#define GPIO_SW2 P1_3void InitClock(void) //初始化时钟{unsigned int i;//turn on 16MHz RC and 32MHz XOSC SLEEPCMD &= ~0x04;//wait for 32MHz XOSC stablewhile(!(SLEEPSTA & 0x40));//chip bug workaroundasm("nop");//延时63usfor(i = 0; i < 504; i++){asm("nop");}//Select 32MHz XOSC and the source for 32K clock CLKCONCMD = 0x00;//Wait for the change to be effectivewhile(CLKCONSTA != 0x00);//turn off 16MHz RCSLEEPCMD = 0x80;}void InitGPIO(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;}void InitUART(void) //初始化串口USART0{//P0[5..2]配置为外设IOP0SEL |= 0x3C;//USART 0 I/O location: Alternative 2 locationPERCFG &= ~0x01;//UART modeU0CSR |= 0x80;//无流控制,无校验,1位停止位,8位数据位,起始位为低电平,停止位为高电平U0UCR = 0x02;//波特率57600U0GCR |= 0x0A;U0BAUD = 216;//使能串口接收器U0CSR |= 0x40;}void UART_SendStr(const unsigned char *str) //通过串口发送字符串{while(*str){//发送一个字符U0DBUF = *str++;//等待发送完毕while(!UTX0IF);//清除发送中断标志UTX0IF = 0;}}void Float2Str(void *str, float Num, unsigned char FractLen) //将float型数据转换为字符串(FractLen:小数位数1-6){unsigned char *ptr = ((unsigned char *)str);unsigned char FractCache[6] = {'\0'};unsigned char i = FractLen, j;unsigned char tmp;unsigned char sign = (unsigned char)(Num < 0);unsigned long trunc; //整数部分unsigned long fract; //小数部分(4位)if (sign){Num *= -1;}trunc = (unsigned long)Num;fract = (unsigned long)((Num-(unsigned long)Num)*1000000); //处理小数部分if (fract == 0){ptr[i++] = '0';}else{for(j=0; j<6; j++){FractCache[j] = (unsigned char)((fract % 10) + '0');fract /= 10;}}//调整小数位数for(j=0; j<FractLen; j++){ptr[FractLen - 1 - j] = FractCache[6 - 1 - j];}//添加小数点ptr[i++] = '.';//处理整数部分if (trunc == 0){ptr[i++] = '0';}while (trunc > 0){ptr[i++] = (unsigned char)((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';}void DelayXus(unsigned int Xus) //延时Xus{while(Xus--){asm("nop");asm("nop");asm("nop");}}void DelayXms(unsigned int X) //延时Xms{while (X--){//延时1msDelayXus(1000);}}void InitADC(void) //初始化ADC{//P0.1配置为外设IOP0SEL |= 0x02;//P0.1配置为模拟IOAPCFG |= 0x02;}unsigned int ADC_ReadVal(void) //通过ADC读取P0.1的电压数据{int val;//ADC参考电压: A VDD5 PinADCCON3 |= 0x80;//512 decimation rate (12 bits ENOB)ADCCON3 |= 0x30;//Single channel: AIN1ADCCON3 &= ~0x0F;ADCCON3 |= 0x01;//Wait for the conversion to be donewhile(!(ADCCON1 & 0x80));//Read the result(最高位为符号位)val = (unsigned int)ADCL;val |= (unsigned int)(ADCH << 8);//Treat small negative as 0val = val < 0 ? 0 : val;//12位有效数据(由于单端转换,所以实际数据11位)val = val >> 4;return val;}void main(void){unsigned char cache[16];unsigned int val;float voltage;//初始化时钟InitClock();//初始化IOInitGPIO();//初始化串口USART0InitUART();//初始化ADCInitADC();//关闭GPIO_RLED和GPIO_GLEDGPIO_RLED = 0;GPIO_GLED = 0;//发送串口初始化成功消息UART_SendStr("\nUSART0 Init Successfully!\n");while(1){//点亮GPIO_RLEDGPIO_RLED = 1;//通过ADC读取P0.1的电压数据if(GPIO_SW1){GPIO_RLED = 0;}else {val = ADC_ReadVal();//换算为电压值voltage = val * 3.3 / 2048;//发送ADC采集到的数据UART_SendStr("V oltage(V): ");//最多保留三位小数Float2Str(cache, voltage, 3);UART_SendStr(cache);UART_SendStr(", Distance(cm): ");//换算成距离值(cm)并最多保留两位小数//6cm~80cm之间拟合公式:distance = 26.757 * voltage^-1.236Float2Str(cache, 26.757 * pow(voltage, -1.236), 2);UART_SendStr(cache);UART_SendStr("\n");//关闭GPIO_RLED// GPIO_RLED = 0;}//延时350msDelayXms(350);}}。

相关主题