当前位置:文档之家› 三轴加速度传感器设计

三轴加速度传感器设计

中北大学课程设计说明书2013/2014 学年第 2 学期学院:专业:学生姓名:学号:课程设计题目:三轴加速度传感器设计起迄日期:课程设计地点:指导教师:专业负责人:下达任务书日期: 2014年6 月13 日目录1、课程设计目的 (1)2、课程设计内容和要求 (1)2、1设计要求 (1)2.2、设计要求 (1)3、设计方案及实现情况 (1)3.1、设计思路 (1)3.2、工作原理及框图 (1)3.3、主要电路模块的使用 (2)3.4、实物结果图 (6)4、课程设计总结 (7)5、参考文献·························· (7)6、附录················································································ (8)附录1 原理图····················································· (8)附录2 PCB版图····················································· (9)附录3 C语言代码····················································· (10)1、课程设计目的综合应用模电、数电、微机原理、单片机原理、传感器原理及应用和专业知识,通过理论与实践相结合,掌握所学知识的综合应用方法,培养和提高解决本专业实际工程问题的能力。

2、课程设计内容和要求2、1设计要求:1. 文献检索和综述;2. 掌握三轴加速度传感器的工作原理;3. 画出传感器装配结构图;用protel绘制原理图;4. 所写说明书格式规范,内容完整;5. 参加答辩。

2.2、设计内容:1. 设计传感器整体结构;4. 以ADXL345三轴加速度计为模型,设计测量电路,给出电路元件参数;5. 基于单片机的采集与显示电路方案设计;6. 用ADXL345搭建测试系统,仿真实验处理结果。

3、设计方案及实现情况3.1、设计思路根据题目要求,首先要对传感器整体结构进行设计,以满足ADXL345三轴加速度计运行的环境;其次,选择合适的通信方式使单片机与传感器能正常通信传输数据;最后,对单片机外围结构进行设计,使单片机能正常工作,编写合适的C 语言程序,使传感器传输的数据能够在外围器件上显示出来。

3.2、工作原理及框图(1)工作原理 ADXL345三轴加速度计能够将三个方向的加速度g 储存在其内部寄存其中,所以,通过适当控制指令以及与单片机通信,就可将其传输到单片机中,然后对其进行编译。

显示模块这里使用的是LCD1602,编译后的数据传送到与LCD1602相连的I/O口,通过读写指令就可显示出数据。

每当ADXL345三轴加速度计记录数据发生变化时,就更新LCD1602中显示的数据,这样就达到了基于单片机的采集与显示电路的设计。

(2)系统框图图1系统框图3.3、主要电路模块的使用(1)ADXL345电源模块由于ADXL345使用的是 3.3V 供电电源,所以要对5V 输入电源就行转化,这里使用的是RT9161 电源芯片,比 1117 更低的压降,更快的负载相应速度,非常适合高噪声电源环境。

如图2,ADXL34单片机1602显单片机当输入电压为5V时,输出为 3.3V,电路中所接的电容起滤波的作用。

图2 RT9161电源模块(2)ADXL345加速度计模块ADXL345是一款小而薄的超低功耗3轴加速度计,分辨率高(13)位,测量范围达±16g。

数字输出数据为16位二进制补码格式,可通过SPI或数字接口访问。

它可以在倾斜测量应用中测量静态重力加速度,还可以测量运动或冲击导致的动态加速度。

其高分辨率,能够测量不到 1.0°的倾斜角变化。

图3 ADXL345引脚图表1引脚功能表在本实验中,如图4,使用的是SPI通信,采用3线连接,片选接地,SDIO和SCLK与单片机相连进行通信。

ADXL345图4 SPI通信接口表2 存储数据所在寄存器地址如图5为本实验中ADXL345加速度计的原理图示意。

图5 ADXL345原理图(3)单片机模块在本实验中,使用到单片机的功能很少,因此,单片机工作在最小模块下。

图6 晶振模块图7 复位模块图8 单片机引脚连接图(4)LCD1602显示模块点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上64×16个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。

例如屏的第一行的亮暗由RAM区的000H——00FH 的16字节的内容决定,当(000H)=FFH时,则屏幕的左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH时,则屏幕的右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=00H,……(00EH)=00H,(00FH)=00H时,则在屏幕的顶部显示一条由8段亮线和8条暗线组成的虚线。

这就是LCD显示的基本原理。

表3 LCD1602管脚功能在此处,LCD1602的8个数据引脚需要上拉电阻来限制电流,同时3引脚可以接一个电位器用来调节显示屏背光亮度。

图9LCD1602原理图3.4、实物结果图由于在众多仿真软件中,没有ADXL345加速度计的模型,同时为了体现出ADXL345与MCU通信的过程,所以并不能用串行通信软件代替,所以此处通过,实物演示来例证。

图10实物结果图4、课程设计总结经过为期三周的课程设计,我对C语言有了更加深刻的认识。

在编写程序的时候,我才发现能看懂程序和能自己写程序是两个完全不同的概念,自己一开始写程序时,即便是一个很简单的功能模块,在编译时也可能产生很多错误,在不断的改错过程中,自己对C语言的语法结构有了深刻的理解,对编译过程中常见的错误也有了全面的认识。

通过这三周的课程设计,我在熟悉了EDA-V实验箱的操作同时,也学到了很多在学习课本知识时所体会不到的东西。

最初拿到课程设计任务书时,感觉每个模块都在做实验时用过,心想只要把各个模块组合到一起就可以实现系统功能了,但结果其实不然;同时,通过实际动手连接元件,更加加深了我对ADXL345的深刻认识。

完成此次设计后,我不仅能对PROTEUS仿真软件熟练操作,能达到学以致用,同时还掌握了ADXL345和LCD1602的工作原理。

经过这一过程,我发现平常的学习在注重理论知识的掌握同时,要加强实验环节,只有通过不断地实践,我们才能把知识掌握的更牢固,理解的更透彻。

5、参考文献[1]Creed Huddleston著,张鼎译.智能传感器设计.人民邮电出版社,2009[2]松井邦彦著.传感器实用电路设计与制作. 北京:科学出版社,2005[3]范茂军主编.互联网与传感器技术. 北京:机械工业出版社,2012[4]刘爱华、满宝元主编.传感器原理与应用技术.北京:人民邮电出版社,2010[5]张宪主编.传感器与测控电路.北京:化学工业出版社,2011附录1、原理图附图1 ADXL345与单片机原理图2、PCB版图附图2 PCB版图3、C语言代码#include <REG51.H>#include <math.h> //Keil library#include <stdio.h> //Keil library#include <INTRINS.H>#define uchar unsigned char#define uint unsigned int#define DataPort P0 //LCD1602数据端口sbit SCL=P1^0; //IIC时钟引脚定义sbit SDA=P1^1; //IIC数据引脚定义sbit LCM_RS=P2^0; //LCD1602命令端口sbit LCM_RW=P2^1; //LCD1602命令端口sbit LCM_EN=P2^2; //LCD1602命令端口#define SlaveAddress 0xA6 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改//ALT ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3Atypedef unsigned char BYTE;typedef unsigned short WORD;BYTE BUF[8]; //接收数据缓存区uchar ge,shi,bai,qian,wan; //显示变量int dis_data; //变量void delay(unsigned int k);void InitLcd(); //初始化lcd1602void Init_ADXL345(void); //初始化ADXL345void WriteDataLCM(uchar dataW);void WriteCommandLCM(uchar CMD,uchar Attribc);void DisplayOneChar(uchar X,uchar Y,uchar DData);void conversion(uint temp_data);void Single_Write_ADXL345(uchar REG_Address,ucharREG_data); //单个写入数据uchar Single_Read_ADXL345(uchar REG_Address); //单个读取内部寄存器数据void Multiple_Read_ADXL345(); //连续的读取内部寄存器数据//------------------------------------void Delay5us();void Delay5ms();void ADXL345_Start();void ADXL345_Stop();void ADXL345_SendACK(bit ack);bit ADXL345_RecvACK();void ADXL345_SendByte(BYTE dat);BYTE ADXL345_RecvByte();void ADXL345_ReadPage();void ADXL345_WritePage();//-----------------------------------//*********************************************************void conversion(uint temp_data){wan=temp_data/10000+0x30 ;temp_data=temp_data%10000; //取余运算qian=temp_data/1000+0x30 ;temp_data=temp_data%1000; //取余运算bai=temp_data/100+0x30 ;temp_data=temp_data%100; //取余运算 shi=temp_data/10+0x30 ;temp_data=temp_data%10; //取余运算 ge=temp_data+0x30;}/*******************************/void delay(unsigned int k){unsigned int i,j;for(i=0;i<k;i++){for(j=0;j<121;j++){;}}}/*******************************/void WaitForEnable(void)void WaitForEnable(void){DataPort=0xff;LCM_RS=0;LCM_RW=1;_nop_();LCM_EN=1;_nop_();_nop_();_nop_();_nop_();while(DataPort&0x80);LCM_EN=0;_nop_();_nop_();}/*******************************/void WriteCommandLCM(uchar CMD,uchar Attribc){if(Attribc)WaitForEnable();LCM_RS=0;LCM_RW=0;_nop_();DataPort=CMD;_nop_();_nop_();_nop_();_nop_();LCM_EN=1;_nop_();_nop_();_nop_();_nop_();LCM_EN=0; /*******************************/void WriteDataLCM(uchar dataW)WaitForEnable();LCM_RS=1;LCM_RW=0;_nop_(); DataPort=dataW;_nop_();LCM_EN=1;__nop_();_nop_();_nop_();_nop_(); LCM_EN=0;}/***********************************/ void InitLcd(){WriteCommandLCM(0x38,1); WriteCommandLCM(0x08,1); WriteCommandLCM(0x01,1); WriteCommandLCM(0x06,1); WriteCommandLCM(0x0c,1);}/***********************************/void DisplayOneChar(uchar X,uchar Y,uchar DData) {Y&=1;X&=15;if(Y)X|=0x40;X|=0x80;WriteCommandLCM(X,0);WriteDataLCM(DData);}/**************************************延时5微秒**************************************/void Delay5us(){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}/**************************************延时5毫秒**************************************/void Delay5ms(){WORD n = 560;while (n--);}/**************************************起始信号**************************************/void ADXL345_Start(){SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线Delay5us(); //延时SDA = 0; //产生下降沿 Delay5us(); //延时SCL = 0; //拉低时钟线}/**************************************停止信号**************************************/void ADXL345_Stop(){SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时SDA = 1; //产生上升沿 Delay5us(); //延时}/**************************************发送应答信号入口参数:ack (0:ACK 1:NAK)**************************************/void ADXL345_SendACK(bit ack){SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(); //延时SCL = 0; //拉低时钟线 Delay5us(); //延时}/**************************************接收应答信号**************************************/bit ADXL345_RecvACK(){SCL = 1; //拉高时钟线Delay5us(); //延时CY = SDA; //读应答信号SCL = 0; //拉低时钟线Delay5us(); //延时return CY;}/**************************************向IIC总线发送一个字节数据**************************************/void ADXL345_SendByte(BYTE dat){BYTE i;for (i=0; i<8; i++) //8位计数器{dat <<= 1; //移出数据的最高位 SDA = CY; //送数据口SCL = 1; //拉高时钟线Delay5us(); //延时SCL = 0; //拉低时钟线Delay5us(); //延时}ADXL345_RecvACK();}/**************************************从IIC总线接收一个字节数据**************************************/BYTE ADXL345_RecvByte(){BYTE i;BYTE dat = 0;SDA = 1; //使能内部上拉,准备读取数据,for (i=0; i<8; i++) //8位计数器{dat <<= 1;SCL = 1; //拉高时钟线Delay5us(); //延时dat |= SDA; //读数据SCL = 0; //拉低时钟线Delay5us(); //延时}return dat;}//******单字节写入*******************************************void Single_Write_ADXL345(uchar REG_Address,uchar REG_data){ADXL345_Start(); //起始信号ADXL345_SendByte(SlaveAddress); //发送设备地址+写信号ADXL345_SendByte(REG_Address); //内部寄存器地址, ADXL345_SendByte(REG_data); //内部寄存器数据,ADXL345_Stop(); //发送停止信号}//********单字节读取*****************************************uchar Single_Read_ADXL345(uchar REG_Address){ uchar REG_data;ADXL345_Start(); //起始信号ADXL345_SendByte(SlaveAddress); //发送设备地址+写信号ADXL345_SendByte(REG_Address); //发送存储单元地址,从0开始ADXL345_Start(); //起始信号ADXL345_SendByte(SlaveAddress+1); //发送设备地址+读信号REG_data=ADXL345_RecvByte(); //读出寄存器数据ADXL345_SendACK(1);ADXL345_Stop(); //停止信号 return REG_data;}//*********************************************************////连续读出ADXL345内部加速度数据,地址范围0x32~0x37////*********************************************************void Multiple_read_ADXL345(void){ uchar i;ADXL345_Start(); //起始信号ADXL345_SendByte(SlaveAddress); //发送设备地址+写信号ADXL345_SendByte(0x32); //发送存储单元地址,从0x32开始ADXL345_Start(); //起始信号ADXL345_SendByte(SlaveAddress+1); //发送设备地址+读信号for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF{BUF[i] = ADXL345_RecvByte(); //BUF[0]存储0x32地址中的数据if (i == 5){ADXL345_SendACK(1); //最后一个数据需要回NOACK}else{ADXL345_SendACK(0); //回应ACK}}ADXL345_Stop(); //停止信号Delay5ms();}//*****************************************************************//初始化ADXL345,根据需要请参考pdf进行修改************************void Init_ADXL345(){Single_Write_ADXL345(0x31,0x0B); //测量范围,正负16g,13位模式Single_Write_ADXL345(0x2C,0x08); //速率设定为12.5 Single_Write_ADXL345(0x2D,0x08); //选择电源模式Single_Write_ADXL345(0x2E,0x80); //使能 DATA_READY 中断Single_Write_ADXL345(0x1E,0x00); //X偏移量根据测试传感器的状态写入Single_Write_ADXL345(0x1F,0x00); //Y 偏移量根据测试传感器的状态写入Single_Write_ADXL345(0x20,0x05); //Z 偏移量根据测试传感器的状态写入}//***********************************************************************//显示x轴void display_x(){ float temp;dis_data=(BUF[1]<<8)+BUF[0]; //合成数据if(dis_data<0){dis_data=-dis_data;DisplayOneChar(2,0,'-'); //显示正负符号位}else DisplayOneChar(2,0,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,conversion(temp); //转换出显示需要的数据DisplayOneChar(0,0,'X'); //第0行,第0列显示X DisplayOneChar(1,0,':');DisplayOneChar(3,0,qian);DisplayOneChar(4,0,'.');DisplayOneChar(5,0,bai);DisplayOneChar(6,0,shi);DisplayOneChar(7,0,'g');}//***********************************************************************//显示y轴void display_y(){ float temp;dis_data=(BUF[3]<<8)+BUF[2]; //合成数据if(dis_data<0){dis_data=-dis_data;DisplayOneChar(2,1,'-'); //显示正负符号位}else DisplayOneChar(2,1,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,conversion(temp); //转换出显示需要的数据DisplayOneChar(0,1,'Y'); //第1行,第0列显示y DisplayOneChar(1,1,':');DisplayOneChar(3,1,qian);DisplayOneChar(4,1,'.');DisplayOneChar(5,1,bai);DisplayOneChar(6,1,shi);DisplayOneChar(7,1,'g');}//***********************************************************************//显示z轴void display_z(){ float temp;dis_data=(BUF[5]<<8)+BUF[4]; //合成数据if(dis_data<0){dis_data=-dis_data;DisplayOneChar(10,1,'-'); //显示负符号位}else DisplayOneChar(10,1,' '); //显示空格temp=(float)dis_data*3.9; //计算数据和显示,conversion(temp); //转换出显示需要的数据DisplayOneChar(10,0,'Z'); //第0行,第10列显示Z DisplayOneChar(11,0,':');DisplayOneChar(11,1,qian);DisplayOneChar(12,1,'.');DisplayOneChar(13,1,bai);DisplayOneChar(14,1,shi);DisplayOneChar(15,1,'g');}//*********************************************************//******主程序********//*********************************************************void main(){uchar devid;delay(500); //上电延时InitLcd(); //液晶初始化5Init_ADXL345(); //初始化ADXL345devid=Single_Read_ADXL345(0X00);//读出的数据为0XE5,表示正确while(1) //循环{Multiple_Read_ADXL345(); //连续读出数据,存储在BUF中display_x(); //---------显示X轴 display_y(); //---------显示Y轴 display_z(); //---------显示Z轴 delay(200); //延时}}。

相关主题