您好,欢迎来到意榕旅游网。
搜索
您的当前位置:首页基于51单片机的云台姿态测量课程设计

基于51单片机的云台姿态测量课程设计

来源:意榕旅游网


单片机课程设计报告

课题名称 : 云台姿态测量系统设计 院 系 : 专业班级 : 姓 名 : 学 号 :

目录 一 概述 .................................................................................................................................... 2 1.1问题提出 ................................................................................................................... 2 1.2方证 ................................................................................................................... 3 二 硬件设计 ........................................................................................................................... 5 2.1控制模块 ................................................................................................................... 5 2.2显示模块 ................................................................................................................... 6 2.3传感器模块 ............................................................................................................... 8 三 软件设计 ......................................................................................................................... 10 3.1 系统初始化 ............................................................................................................. 11 3.2 显示程序 ................................................................................................................. 11 3.3 传感器控制部分 .................................................................................................... 12 四 系统调试 ......................................................................................................................... 13 4.1硬件调试 ................................................................................................................. 13 4.2软件调试 ................................................................................................................. 13 五 总结 ................................................................................................................................. 16 参考文献 ............................................................................................................................... 17 附录 ....................................................................................................................................... 18 附录A:元器件清单 ..................................................................................................... 18 附录B:电路设计图 ..................................................................................................... 19 附录C:C程序源代码 .................................................................................................. 20

1

一 概述 1.1问题提出 云台是安装、固定摄像机的支撑设备,它分为固定和电动云台两种。 固定云台适用于监视范围不大的情况,在固定云台上安装好摄像机后可调整摄像机的水平和俯仰的角度,达到最好的工作姿态后只要锁定调整机构就可以了。 电动云台适用于对大范围进行扫描监视,它可以扩大摄像机的监视范围。电动云台高速姿态是由两台执行电动机来实现,电动机接受来自控制器的信号精确地运行定位。在控制信号的作用下,云台上的摄像机既可自动扫描监视区域,也可在监控中心值班人员的操纵下跟踪监视对象。 三轴陀螺仪:同时测定6个方向的位置,移动轨迹,加速。 单轴的只能测量两个方向的量,也就是一个系统需要三个陀螺仪,而3轴的一个就能替代三个单轴的。3轴的体积小、重量轻、结构简单、可靠性好,是激光陀螺的发展趋势。 汽车级陀螺仪能提供精确的测量结果,可大幅提升汽车导航仪和远端资讯处理系统的航位推算(Dead-ReckoNIng)和/或地图对照(Map-Matching)功能。在全球卫星定位系统(GPS)卫星讯号很差的室内和高楼林立的区域,航位推算系统可弥补讯号消失的影响,代替卫星检测物体的动作和高度。陀螺仪的精确测量资料还能提高地图对照准确度;地图对照是在数位地图的道路网路上描述卫星或感测器观测的用户位置的动作轨迹的过程,地图对照被用于各种导航定位系统,包括交通流量分析和车辆行驶方向。 在工程上,陀螺仪是一种能够精确地确定运动物体的方位的仪器,它是现代航空,航海,航天和国防工业中广泛使用的一种惯性导航仪器,它的发展对一个国家的工业,国防和其它高科技的发展具有十分重要的战略意义。传统的惯性陀螺仪主要是指机械式的陀螺仪,机械式的陀螺仪对工艺结构的要求很高,结构复杂,它的精度受到了很多方面的制约。自从上个世纪七十年代以来,现代陀螺仪的发展已经进入了一个全新的阶段。1976年美国Utah大学的Vali和Shorthill提出了现代光纤陀螺仪的基本设想,到八十年代以后,现代光纤陀螺仪就得到了非常迅速的发展。由于光纤陀螺仪具有结构紧凑,灵敏度高,工作可靠等等优点,所以光纤陀螺仪在很多的领域已经完全 2

取代了机械式的传统的陀螺仪,成为现代导航仪器中的关键部件。拥有很广泛的应用。 (1)课程设计任务 本次课程设计题目为:基于51单片机云台姿态测量系统。 内容:① 基于51单片机系统 ② 利用液晶显示屏显示出实际角度 ③ 具有三维空间的坐标显示 (2)课程设计的基本要求 ① 最终设计系统应安全,简单 ② 学会整理,收集与课程设计相关的信息资料 ③ 完成最初方案的设计 ④ 优化软硬件的设计 (3)课程设计的意义 本次课程设计是对单片机课程学习的实践环节,旨在通过本次课改加强同学们对单片机知识的巩固和提高,并且增强同学们的实际动手能力和团队合作意识。 在这次课程设计中本人主要负责软件部分的调试。 1.2方证 (1)整体设计思路 此次课程设计题目为云台方位测量显示系统,主要需攻克的是角度的测量与显示。角度的测量与显示,需要传感器采集模拟信号,并且转换为数字信号输入单片机,由单片机根据输入数据对显示屏进行写操作。 设计总体框架图如下: 3

L3D42OOD 三轴陀螺仪 STCC52 LCD1602 电源模块 图1.1 总体设计框架图 L3D42OOD三轴陀螺仪将信号采集并转化后送入STCC52单片机,再经过单片机的处理将陀螺仪转动的方向通过LCD1602显示出来。 4

二 硬件设计 2.1控制模块 最小系统模块由单片机、晶振。复位电路以及电源组成。常用的单片机有AT系列和STC系列,都能满足方案需求,AT单片机的下载串口软件没找到,STC有配套使用的各种软件,而且成本低,性价比高。综合考虑,为了方便编程调试与下载,选用STC系列。 可用的STC系列51单片机有C51和C52。功能一样的前提下,C52的ROM更大,故最终选择STCC52单片机。 最小系统模块的主要的功能是让单片机工作,STCC52单片机有40个管脚,其中需要用到I/0接口有P0.0-P0.7,P1.0,P1.1。18,19管脚接时钟信号(片内震荡),本次课设采用11.0592MHZ的晶振。9管脚接复位输入端RST,由电容,电阻构成的上电复位电路。20管脚接GND,40管脚接VCC(+5V)电源。 图2.1 STCC52管脚图 5

图2.2 51单片机最小系统图 2.2显示模块 市面上显示屏种类繁多,有LCD1602,12232,128,Nokia5110等一系列显示屏,综合分析比较,本次课设,只需要显示三轴的角度值,简单的ASC2码字符显示,1602显示屏很好的满足的需求,而且操作简单,成本低廉,性价比极高。因此最终选取LCD1602用来显示。 图2.3 LCD1602显示屏管脚图 6

本设计采用的是液晶显示LCD1602。LCD1602内部的字符已经储存了不同的字符形式,每一个字符都有一个固定的代码,其代码与标准的ASCII字符代码一致。因此只要写入显示字符的ASCII码即可,这种标准化的设计给使用带来很大的方便。比如英文字母“C”的ASCII代码是01000011(43H),显示时单片机往液晶模块写入显示指令,模块就会把地址为43H中的点阵字符图形识别出,并会在液晶屏相应位置上看到字母“C”。 LCD1602液晶显示与单片机的连接可以分为两种方式:总线方式和模拟口线方式。在实验中,我们常采用模拟口线连接方式。 目前市场字符液晶绝大多数是基于HD44780的液晶芯片,控制原理是完全相同的,因此基于HD44780的写控制程序可以很容易地应用到市场上大部分的字符液晶。LCD1602液晶的几个特性:+5V电压、对比度可调、内含复位电路;提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能;有80字节显示数据存储器DDRAM;内建有160个5X7点阵的字型的字符发生器CGROM 8个可由用户自定义的5X7的字符发生器CGRAM。 LCD1602采用标准的16脚接口,其中VSS为地电源,VDD接5V正电源,VEE为液晶显示器。RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。RW为读写信号线,高电平1时进行读操作,低电平0时进行写操作。E端为使能端。D0~D7为8为双向数据线。 编号 1 2 3 4 5 6 7 8 符号 VSS VDD VEE RS R/W E D0 D1 引脚说明 电源地 电源正极 液晶显示偏压信号 数据/命令选择端(H/L) 读写选择端(H/L) 使能信号 Data I/O Data I/O 编号 符号 9 10 11 12 13 14 15 16 D2 D3 D4 D5 D6 D7 BLA BLK 引脚说明 Data I/O Data I/O Data I/O Data I/O Data I/O Data I/O 背光源正极 背光源负极 表2.1 LCD1602液晶屏引脚说明

7

图2.4 LCD1602实物图 2.3传感器模块 传感器的选择: 方案一:使用ENC-03陀螺仪进行方位测量,工作电压为2.7-5.3V。配合AD转换芯片ADC0804进行采样的模拟量转化为数字量,再传给单片机进行数据处理。 方案二:使用L3G4200D三轴陀螺仪进行方位测量,其内部自带AD转换,直接输出数字信号,工作电压为2.4-3.6V。 比较:方案一需要在转轴部分安装传感器,并且采集的是模拟量,需要外加ADC芯片进行转换,比较麻烦和不稳定。相比之下,方案二传感器有丰富资源,安装方便,并且电路简单,性能稳定,不用增加复杂的外围电路,利于达到最终的设计目的。 综合考虑,选用方案二。 本次课程设计采用的是L3G4200D三轴陀螺仪。该传感器是一种低功耗三轴陀螺仪,提供三个不同的±250/±500/±2000 dps,它包括一个传感元件和一个IC接口能够提供角速度的检测外部世界,通过一个数字接口(IIC/SPI).传感元件是采用专门微细加工工艺,而IC接口技术实现了用CMOS允许设计一个专门的电路,以更好的匹配传感元件的特点。 特点: ① IIC/SPI数字输出接口 ② 两个数字输出线 ③ 宽电压,2.4到3.6V ④ 高冲击生存能力,稳定 ⑤ 工作温度:-40°— +85° 8

⑥ 省电和睡眠模式 ⑦ 16比特率值的数据输出 图2.5 L3G4200D三轴陀螺仪

9

三 软件设计 本次课程设计单片机的软件设计,采用的是C语言,编译环境是keil4,串口下载使用STC-ISP-V483。 设计流程如下: 开 始 液晶初始化 传感器初始化 读取角速度 单片机处理 LCD显示 结 束 系统上电液晶屏初始化显示X:000 ,Y:000 ,Z:000,传感器的位置初始化,即初始位置为X:000 ,Y:000 ,Z:000。当传感器检测到角度改变时,传感器将角速度信号传给单片机处理,通过单片机内部的处理转换再通过LCD显示器显示出角度的变化。 10

3.1 系统初始化 delay(500); //上电延时 InitLcd(); //液晶初始化 InitL3G4200D(); //初始化L3G4200D while(1) //循环 { display_x(); //---------显示X轴 //display_y(); //---------显示Y轴,不稳定,屏蔽 display_z(); //---------显示Z轴 delay(100); //延时 } } 3.2 显示程序 (1)写命令操作和写数据操作分别用两个的函数完成,函数内部唯一的区别就是液晶数据命令选择端的电平,具体操作如下: Void write_com(uchar com) { lcdrs=0; //选择写命令模式 P0=com; //将要写的命令字送到数据总线上 delay(5); //稍作延时以待数据稳定 lcern=1; //使能端给一高脉冲,因为初始化函数中已经将lcden置为0 delay(5); //稍作延时 lcden=0; //将使能端置0已完成高脉冲 } (2)初始化函数中几个命令的解释请对照前面的指令码及功能说明。 write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口 write_com(0x0c); //设置开显示,不显示光标

11

write_com(0x06); //写一个字符后地址指针自动加1 write_com(0x01); //显示清零,数据指针清0 (3)进入主函数,执行完初始化函数后,用“write_com(0x80);”命令先将数据指针定位到第一行第一个字处,然后写完第一行要显示的字,在每两个字之间做简短延时,提高稳定性。 (4)当写第二行时需要重新定位数据指针:write_com(0x80+0x40)。 3.3 传感器控制部分 三轴陀螺仪L3G4200D用来检测云台的姿态,它所采集的模拟量经过内部自带AD转换为数字量,使用I/O端口P1.0和P1.2进行IIC时钟定义。同时把角加速度的数字量通过积分变化,得到角度值。 sbit SCL=P1^0; sbit SDA=P1^1; *****显示x轴为例 void display_x() { BUF[0]= Single_ReadL3G4200D(OUT_X_L); BUF[1]= Single_ReadL3G4200D(OUT_X_H); //读取X轴数据 dis_data=(BUF[1]<<8)+BUF[0]; //合成数据 temp=(float)dis_data*0.07; dis_data=(int)temp; lcd_printf(dis, dis_data); //转换数据显示 DisplayListChar(2,0,dis,4); //启始列,行,显示数组,显示长度 }

12

四 系统调试 4.1硬件调试 在搭建硬件时,最初选择了最小系统板用烙铁焊,显示模块和传感器模块用杜邦线拔插,在时间使用中发现,杜邦线拔插虽然方便,但也带来了不少的麻烦和不理想的空间。杜邦线要在板子上焊针管,增加工作量。而且杜邦线过长,如果全部使用杜邦线扩展,电路板看起来非常不美观,给人零乱的感觉,有时会导致出现拔插失误而影响最终测量结果。使用一段时间后,我选择用焊锡和导线把显示屏与单片机端口固定,因为所需I/O口不多,所以这样固定以后大大提高系统板的稳定性,减少拔插带来的失误。同时,我们也保留了杜邦线的便捷性,将传感器部分用杜邦线进行连接,这样可以适应不同的环境,也可以随时卸下传感器进行单独测试。 最初为了简化电路,我们舍弃了最小系统板的复位电路,这在后面的调试中带来了一些不必要麻烦,每次的初始化,都必须通过断电上电,用电池开关来进行系统的初始化,综合考虑,最后,我们觉得加上复位电路部分,提高系统的可操作便捷性。 4.2软件调试 软件设计完成之后基本可以实现测量角度以及正常的显示,测量数据如下: X 轴 1 Y 轴 Z 轴 X 轴 2 Y 轴 Z 轴 由采样数据计算: 实际角度 45° 45° 45° -90° -90° -90° 测量角度 40° 49° 39° -82° -97° -82° 13

误差:x1=11.1%,x2=8.9% y1=8.9%,y2=7.8% z1=13%, z2=8.9% 平均误差:x=10% Y=8.3% Z=11% 综上数据结果显示误差超过允许范围。属于不正常情况,因此要进一步提高精度,所采取的方案是,软件数据补偿,在程序设计的过程中加入补偿算法,来提高精度。 具体算法如下: /* 以X轴为例 */ temp=(float)dis_data*0.07; jiaodu_x=jiaodu_x+temp*0.56; if (jiaodu_x>0) { jiaodu_x=jiaodu_x-0.8;//x轴正向补偿 } if(jiaodu_x<0); { jiaodu_x=jiaodu_x+0.1; //x轴负方向补偿 } dis_data=(int)jiaodu_x; 14

X 轴 1 Y 轴 Z 轴 2 由以上数据计算可得; 平均误差:x=4% Y=3.8% Z=3.6% 经过补偿程序的改进以后,有效的解决了误差偏大的问题,提高了该系统的精度和稳定度,同时也体现了该系统的使用价值 X 轴 Y 轴 Z 轴 实际角度 45° 45° 45° 90° 90° 90° 测量角度 43° 46° 44° ° 91° 87° 15

五 总结 经过四周的努力,课程设计终于顺利完成,在设计初期遇到了很多问题,方案的选择与确定,传感器的选择,一次次的讨论与协商,大家查询大量的资料,最终确立了方案。虽然过程没有我们想象中那么一帆风顺,电路板的焊接有虚焊现象,某个元器件的管脚没有导通,但组员们互相理解,团结合作,克服了这些困难。我们课程设计小组的四个人各有分工,中也使我们的同学关系更进一步了,同学之间互相帮助,有什么不懂的大家在一起商量,听听不同的看法对我们更好的理解知识。在做团体项目的时候,队员的交流是非常重要的,是很关键的部分。这次的课程设计也让我看到了团队的力量,我认为我们的工作是一个团队的工作,团队需要个人,个人也离不开团队,必须发扬团结协作的精神。刚开始的时候,大家就分配好了各自的任务,大家有的绘制原理图,进行仿真实验,有的积极查询相关资料,并且经常聚在一起讨论各个方案的可行性。在课程设计中只有一个人知道原理是远远不够的,必须让每个人都知道,否则一个人的错误,就有可能导致整个工作失败,团结协作是我们成功的一项非常重要的保证。 在本次的课程设计中,我们应用学过的知识做出具体的实物,并实现其功能。在这过程中,我们学会了如何应用我们的知识去制作和创造,以及克服各种实际性问题的方法。通过本次的单片机课程设计,我们具体操作,将课本上的文字转变为实物,将理论得以实践,通过具体的操作,更加深刻的学习和理解了我们所学过的知识。从而明白如何将理论和实践相结合,以及动手实践的重要性。这种经历会对我以后的学习方式以及思维方式起到很大的帮助。 最后,非常感谢课程设计的指导教师×老师的指导。

16

参考文献 [1]郭天祥. 《51单片机C语言教程》. 北京:电子工业出版社 2009 [2] 李叶紫,王喜斌,胡辉,孙东辉.《MCS-51单片机应用教程》.北京:清华大学出版社 2004:29-35. [3] 夏路易,石宗义.《电路原理图与电路板设计教程》.北京:北京希望电子出版社 2004: [5] 李华,《MCS-51系列单片机使用接口技术》.北京航空航天大学出版社,1990 [6] 兰吉昌,《51单片机应用设计百例》.北京:化学工业出版社,2009:220-230 [7] 曹素芬,《单片微型计算机原理与接口技术》.沈阳:东北大学出版社,1995. [8] 于永,戴佳,刘波.《51单片机C语言常用模块与综合设计实例精讲》.北京:电子工业出版社,2008 第二版. [9] 意法爱立信.Inc,《L3G4200D三轴陀螺仪技术文档》 17

附录 附录A:元器件清单 名称 单片机 传感器 液晶显示 芯片底座 排阵 排阻 电阻 电容 洞洞板 晶振 电位器 轻触开关 导线 数量 1 1 1 1 1 1 2 2 1 1 1 若干 STCC52 L3G4200D LCD1602 10k 5.1 30pf 11.0592MHZ 10k 备注

18

附录B:电路设计图 附录B图 总体电路设计图

19

附录C:C程序源代码 //*************************************** // GY-50 L3G4200D 测量程序 // 使用单片机STCC52 // 晶振:11.0592M // 显示:LCD1602 // 编译环境 Keil uVision4 // 作者:山聪,马萌 //**************************************** #include #include //Keil library #include //Keil library #include #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命令端口 //**********L3G4200D内部寄存器地址********* #define WHO_AM_I 0x0F #define CTRL_REG1 0x20 #define CTRL_REG2 0x21 #define CTRL_REG3 0x22

20

#define CTRL_REG4 0x23 #define CTRL_REG5 0x24 #define REFERENCE 0x25 #define OUT_TEMP 0x26 #define STATUS_REG 0x27 #define OUT_X_L 0x28 #define OUT_X_H 0x29 #define OUT_Y_L 0x2A #define OUT_Y_H 0x2B #define OUT_Z_L 0x2C #define OUT_Z_H 0x2D #define FIFO_CTRL_REG 0x2E #define FIFO_SRC_REG 0x2F #define INT1_CFG 0x30 #define INT1_SRC 0x31 #define INT1_TSH_XH 0x32 #define INT1_TSH_XL 0x33 #define INT1_TSH_YH 0x34 #define INT1_TSH_YL 0x35 #define INT1_TSH_ZH 0x36 #define INT1_TSH_ZL 0x37 #define INT1_DURATION 0x38 //**************************************** #define SlaveAddress 0xD2 //定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改 typedef unsigned char BYTE; typedef unsigned short WORD; 21

uchar dis[4]; //显示数组 BYTE BUF[8]; //接收数据缓存区 uchar ge,shi,bai,qian,wan; //显示变量 int dis_data; //变量 float temp; int N; void delay(unsigned int k); void InitLcd(); //初始化lcd1602 void InitL3G4200D(); //初始化L3G4200D void WriteDataLCM(uchar dataW); void WriteCommandLCM(uchar CMD,uchar Attribc); void DisplayOneChar(uchar X,uchar Y,uchar DData); void DisplayListChar(uchar X,uchar Y,uchar *DData,L); void conversion(uint temp_data); void Single_WriteL3G4200D(uchar REG_Address,uchar REG_data); //单个写入数据 uchar Single_ReadL3G4200D(uchar REG_Address); //单个读取内部寄存器数据 void time(void) ; //------------------------------------ void Delay5us(); void L3G4200D_Start(); void L3G4200D_Stop(); void L3G4200D_SendACK(bit ack); bit L3G4200D_RecvACK(); void L3G4200D_SendByte(BYTE dat); BYTE L3G4200D_RecvByte(); 22

void L3G4200D_ReadPage(); void L3G4200D_WritePage(); void display_x(); void display_y(); void display_z(); float jiaodu_x=0,jiaodu_y=0,jiaodu_z=0; float buchang_x=0,buchang_y=0,buchang_z=0; /*******************************/ void lcd_printf(uchar *s,int temp_data) { if(temp_data<0){ temp_data=-temp_data; *s='-'; } else *s=' '; *++s =temp_data/100+0x30; temp_data=temp_data%100; //取余运算 *++s =temp_data/10+0x30; temp_data=temp_data%10; //取余运算 *++s =temp_data+0x30; } /*******************************/ void delay(unsigned int k) { unsigned int i,j; for(i=0;ifor(j=0;j<121;j++) {;}} } /*******************************/ void WaitForEnable(void) { DataPort=0xff; LCM_RS=0;LCM_RW=1;_nop_(); LCM_EN=1;_nop_();_nop_(); while(DataPort&0x80); LCM_EN=0; } /*******************************/ void WriteCommandLCM(uchar CMD,uchar Attribc) { if(Attribc)WaitForEnable(); LCM_RS=0;LCM_RW=0;_nop_(); DataPort=CMD;_nop_(); LCM_EN=1;_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_();LCM_EN=0; } /***********************************/ 24

void InitLcd() { WriteCommandLCM(0x38,1); WriteCommandLCM(0x08,1); WriteCommandLCM(0x01,1); WriteCommandLCM(0x06,1); WriteCommandLCM(0x0c,1); DisplayOneChar(0,0,'x'); DisplayOneChar(1,0,':'); //DisplayOneChar(0,1,'y'); //DisplayOneChar(1,1,':'); DisplayOneChar(9,0,'z'); DisplayOneChar(10,0,':'); } /***********************************/ void DisplayOneChar(uchar X,uchar Y,uchar DData) { Y&=1; X&=15; if(Y)X|=0x40; X|=0x80; WriteCommandLCM(X,0); WriteDataLCM(DData); } //******************************************* void DisplayListChar(uchar X,uchar Y,uchar *DData,L) { uchar ListLength=0; 25

Y&=0x1; X&=0xF; while(L--) { DisplayOneChar(X,Y,DData[ListLength]); ListLength++; X++; } } /************************************** 延时5微秒(STC90C52RC@12M) 不同的工作环境,需要调整此函数,注意时钟过快时需要修改 当改用1T的MCU时,请调整此延时函数 **************************************/ void Delay5us() { _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); } /************************************** 起始信号 **************************************/ void L3G4200D_Start() { 26

SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 0; //产生下降沿 Delay5us(); //延时 SCL = 0; //拉低时钟线 } /************************************** 停止信号 **************************************/ void L3G4200D_Stop() { SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 1; //产生上升沿 Delay5us(); //延时 } /************************************** 发送应答信号 入口参数:ack (0:ACK 1:NAK) **************************************/ void L3G4200D_SendACK(bit ack) { SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(); //延时 27

SCL = 0; //拉低时钟线 Delay5us(); //延时 } /************************************** 接收应答信号 **************************************/ bit L3G4200D_RecvACK() { SCL = 1; //拉高时钟线 Delay5us(); //延时 CY = SDA; //读应答信号 SCL = 0; //拉低时钟线 Delay5us(); //延时 return CY; } /************************************** 向IIC总线发送一个字节数据 **************************************/ void L3G4200D_SendByte(BYTE dat) { BYTE i; for (i=0; i<8; i++) //8位计数器 { dat <<= 1; //移出数据的最高位 SDA = CY; //送数据口 28

SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } L3G4200D_RecvACK(); } /************************************** 从IIC总线接收一个字节数据 **************************************/ BYTE L3G4200D_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; } //单字节写入******************************************* 29

void Single_WriteL3G4200D(uchar REG_Address,uchar REG_data) { L3G4200D_Start(); //起始信号 L3G4200D_SendByte(SlaveAddress); //发送设备地址+写信号 L3G4200D_SendByte(REG_Address); //内部寄存器地址,请参考中文pdf22页 L3G4200D_SendByte(REG_data); //内部寄存器数据,请参考中文pdf22页 L3G4200D_Stop(); //发送停止信号 } //单字节读取***************************************** uchar Single_ReadL3G4200D(uchar REG_Address) { uchar REG_data; L3G4200D_Start(); //起始信号 L3G4200D_SendByte(SlaveAddress); //发送设备地址+写信号 L3G4200D_SendByte(REG_Address); //发送存储单元地址,从0开始 L3G4200D_Start(); //起始信号 L3G4200D_SendByte(SlaveAddress+1); //发送设备地址+读信号 REG_data=L3G4200D_RecvByte(); //读出寄存器数据 L3G4200D_SendACK(1); L3G4200D_Stop(); //停止信号 return REG_data; } //***************************************************************** //初始化L3G4200D,根据需要请参考pdf进行修改************************ void InitL3G4200D() 30

{ Single_WriteL3G4200D(CTRL_REG1, 0x0f); // Single_WriteL3G4200D(CTRL_REG2, 0x00); // Single_WriteL3G4200D(CTRL_REG3, 0x08); // Single_WriteL3G4200D(CTRL_REG4, 0x30); //+-2000dps Single_WriteL3G4200D(CTRL_REG5, 0x00); } //*********************************************************************** //显示x轴 void display_x() { BUF[0]= Single_ReadL3G4200D(0x28); BUF[1]= Single_ReadL3G4200D(0x29); //读取X轴数据 dis_data=(BUF[1]<<8)+BUF[0]; //合成数据 temp=(float)dis_data*0.07; // 数据手册 第9页,2000度/秒量程 jiaodu_x=jiaodu_x+temp*0.56; if (jiaodu_x>0) { jiaodu_x=jiaodu_x-0.8; } if(jiaodu_x<0); { jiaodu_x=jiaodu_x; } 31

dis_data=(int)jiaodu_x; lcd_printf(dis, dis_data); //转换数据显示 DisplayListChar(2,0,dis,4); //启始列,行,显示数组,显示长度 } //*********************************************************************** //显示y轴 void display_y() { BUF[2]= Single_ReadL3G4200D(0x2a); BUF[3]= Single_ReadL3G4200D(0x2b);//读取Y轴数据 dis_data=(BUF[3]<<8)+BUF[2]; //合成数据 temp=(float)dis_data*0.07; // 数据手册 第9页,2000度/秒量程 jiaodu_y=jiaodu_y+temp*0.56; if (jiaodu_y>0) { jiaodu_y=jiaodu_y-0.8; } if(jiaodu_y<0); { jiaodu_y=jiaodu_y; } dis_data=(int)jiaodu_y; lcd_printf(dis, dis_data); //转换数据显示 DisplayListChar(2,1,dis,4); //启始列,行,显示数组,显示长度 32

} //*********************************************************************** //显示z轴 void display_z() { BUF[4]= Single_ReadL3G4200D(OUT_Z_L); BUF[5]= Single_ReadL3G4200D(OUT_Z_H);//读取Z轴数据 dis_data=(BUF[5]<<8)+BUF[4]; //合成数据 temp=(float)dis_data*0.07; // 数据手册 第9页,2000度/秒量程 jiaodu_z=jiaodu_z+temp*0.56;//角度补偿 if (jiaodu_z>0) { jiaodu_z=jiaodu_z-0; } if(jiaodu_z<0); { jiaodu_z=jiaodu_z+0.65; } dis_data=(int)jiaodu_z; lcd_printf(dis, dis_data); //转换数据显示 DisplayListChar(11,0,dis,4); //启始列,行,显示数组,显示长度 } void time() { TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; 33

EA=1; ET0=1; TR0=1; } //********************************************************* //******主程序******** //********************************************************* void main() { uchar Temperature; delay(500); //上电延时 time(); InitLcd(); //液晶初始化 InitL3G4200D(); //初始化L3G4200D Temperature=Single_ReadL3G4200D(OUT_TEMP); //读取角度 while(1) //循环 { //---------显示Z轴 //delay(500); //延时 } } void T0_time()interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; N++; if(N==10) { 34

N=0; display_x(); //---------显示X轴 //display_y(); //---------显示Y轴 display_z(); } } 35

36

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务