null

基于51的电压检测和气压高度检测和电子罗盘

  • 1星
  • 日期: 2015-07-26
  • 大小: 19.63KB
  • 所需积分:1分
  • 下载次数:0
  • favicon收藏
  • rep举报
  • 分享
  • free评论
标签: 气压模块电子罗盘电压检测

基于51IIC的简单程序。

文档内容节选

include REG52H include mathh include stdioh include INTRINSH include stdlibh define uchar unsigned char define uint unsigned int define DataPort P0 LCD1602数据端口 define DataPort1 P2 ADC0804数据端口 使用的端口,请按照以下接线 sbit SCLP10 IIC时钟引脚定义 电子罗盘iic引脚定义 sbit SDAP11 IIC数据引脚定义 sbit SCL1P12 IIC时钟引脚定义 气压模块iic引脚定义 sbit SDA1P13 IIC数据引脚定义 sbit LCMRSP35 LCD1602命令端口 sbit LCMRWP36 LCD1602命令端口 sbit LCMENP34 LCD1602命令端口 sbit adcsP32 AD 片选 sbit adrdP16 AD sbit adwrP15 AD ......

#include #include //#include #include //#include #define uchar unsigned char #define uint unsigned int #define DataPort P0 //LCD1602数据端口 #define DataPort1 P2 //ADC0804数据端口 //////////////////////////////////////////使用的端口,请按照以下接线 sbit SCL=P1^0; //IIC时钟引脚定义 电子罗盘iic引脚定义 sbit SDA=P1^1; //IIC数据引脚定义 sbit SCL1=P1^2; //IIC时钟引脚定义 气压模块iic引脚定义 sbit SDA1=P1^3; //IIC数据引脚定义 sbit LCM_RS=P3^5; //LCD1602命令端口 sbit LCM_RW=P3^6; //LCD1602命令端口 sbit LCM_EN=P3^4; //LCD1602命令端口 sbit adcs=P3^2; //AD 片选 sbit adrd=P1^6; // AD sbit adwr=P1^5; // AD #define SlaveAddress 0x3C //定义电子罗盘器件在IIC总线中的从地址 #define BMP085_SlaveAddress 0xee //定义气压模块器件在IIC总线中的从地址 写操作 0xEF 读操作 #define OSS 0 typedef unsigned char BYTE; // typedef unsigned short WORD; //相当于 define WORD unsigned short BYTE BUF[8]; //接收数据缓存区 uchar ge,shi,bai,qian,wan,shiwan; //显示变量 int dis_data; uint adval; //ADC 读值 short ac1; //变量 short ac2; short ac3; unsigned short ac4; unsigned short ac5; unsigned short ac6; short b1; short b2; short mb; short mc; short md; void delay(uint k); void InitLcd(); //初始化1602 void Init_HMC5883(void); //初始化5883 void Init_BMP085(); //初始化BMP085 void WriteDataLCM(uchar dataW); void WriteCommandLCM(uchar CMD,uchar Attribc); void DisplayOneChar(uchar X,uchar Y,uchar DData); void conversion(uint temp_data); ////////////// uint void conversionl(long temp_data); ///////////// long /////气压模块读写操作 //void Single_Write(uchar SlaveAddress,uchar REG_Address,uchar REG_data); //单个写入数据 //uchar Single_Read(uchar REG_Address); //单个读取内部寄存器数据 void Multiple_Read(uchar,uchar); //连续的读取内部寄存器数据 //////电子罗盘读写操作 void Single_Write_HMC5883(uchar REG_Address,uchar REG_data); //单个写入数据 ////////////////////HMC5883 //uchar Single_Read_HMC5883(uchar REG_Address); //单个读取内部寄存器数据 void Multiple_Read_HMC5883(); //连续的读取内部寄存器数据 //以下是模拟iic使用函数------------- void Delay5us(); void Delay5ms(); void HMC5883_Start(); void HMC5883_Stop(); void HMC5883_SendACK(bit ack); bit HMC5883_RecvACK(); void HMC5883_SendByte(BYTE dat); BYTE HMC5883_RecvByte(); void HMC5883_ReadPage(); void HMC5883_WritePage(); void BMP085_Start(); void BMP085_Stop(); void BMP085_SendACK(bit ack); bit BMP085_RecvACK(); void BMP085_SendByte(BYTE dat); BYTE BMP085_RecvByte(); void BMP085_ReadPage(); void BMP085_WritePage(); //----------------------------------- void conversionl(long temp_data) ///////////////////////////// { shiwan=temp_data/100000 ; temp_data=temp_data%100000; //取余运算 wan=temp_data/10000 ; temp_data=temp_data%10000; //取余运算 qian=temp_data/1000 ; temp_data=temp_data%1000; //取余运算 bai=temp_data/100 ; temp_data=temp_data%100; //取余运算 shi=temp_data/10 ; temp_data=temp_data%10; //取余运算 ge=temp_data+0x30; } //********************************************************* void conversion(uint temp_data) { ////////////////////////////// shiwan=temp_data/100000 ; temp_data=temp_data%100000; //取余运算 wan=temp_data/10000; temp_data=temp_data%10000; //取余运算 qian=temp_data/1000 ; temp_data=temp_data%1000; //取余运算 bai=temp_data/100 ; temp_data=temp_data%100; //取余运算 shi=temp_data/10 ; temp_data=temp_data%10; //取余运算 ge=temp_data+0x30; } /*******************************/ /*******************************/ void delay(uint k) { uint i,j; for(i=0;i> 15; x2 = ((long) mc << 11) / (x1 + md); b5 = x1 + x2; temperature = ((b5 + 8) >> 4); //************* conversionl(temperature); DisplayOneChar(8,0,'T'); //温度显示 DisplayOneChar(9,0,':'); DisplayOneChar(10,0,bai); DisplayOneChar(11,0,shi); DisplayOneChar(12,0,'.'); DisplayOneChar(13,0,ge); DisplayOneChar(14,0,0XDF); //温度单位 DisplayOneChar(15,0,'C'); //************* b6 = b5 - 4000; // Calculate B3 x1 = (b2 * (b6 * b6)>>12)>>11; x2 = (ac2 * b6)>>11; x3 = x1 + x2; b3 = (((((long)ac1)*4 + x3)<>2; // Calculate B4 x1 = (ac3 * b6)>>13; x2 = (b1 * ((b6 * b6)>>12))>>16; x3 = ((x1 + x2) + 2)>>2; b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; b7 = ((unsigned long)(up - b3) * (50000>>OSS)); if (b7 < 0x80000000) p = (b7<<1)/b4; else p = (b7/b4)<<1; x1 = (p>>8) * (p>>8); x1 = (x1 * 3038)>>16; x2 = (-7357 * p)>>16; pressure = p+((x1 + x2 + 3791)>>4); height =(1-pow((float)pressure/101325.0,0.190295))*44330 ; conversionl(height); DisplayOneChar(8,1,'H'); //显示高度 DisplayOneChar(9,1,':'); DisplayOneChar(11,1,qian); DisplayOneChar(12,1,bai); DisplayOneChar(13,1,shi); DisplayOneChar(14,1,ge); DisplayOneChar(15,1,'m'); } ////////////////////////////////////// ////////////////////////////////////// ////////////////////////////////////////电子罗盘 /************************************** 起始信号 **************************************/ void HMC5883_Start() { SDA = 1; //拉高数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 0; //产生下降沿 Delay5us(); //延时 SCL = 0; //拉低时钟线 } /************************************** 停止信号 **************************************/ void HMC5883_Stop() { SDA = 0; //拉低数据线 SCL = 1; //拉高时钟线 Delay5us(); //延时 SDA = 1; //产生上升沿 Delay5us(); //延时 } /************************************** 发送应答信号 入口参数:ack (0:ACK 1:NAK) **************************************/ void HMC5883_SendACK(bit ack) { SDA = ack; //写应答信号 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } /************************************** 接收应答信号 **************************************/ bit HMC5883_RecvACK() { SCL = 1; //拉高时钟线 Delay5us(); //延时 CY = SDA; //读应答信号 SCL = 0; //拉低时钟线 Delay5us(); //延时 return CY; } /************************************** 向IIC总线发送一个字节数据 **************************************/ void HMC5883_SendByte(BYTE dat) { BYTE i; for (i=0; i<8; i++) //8位计数器 { dat <<= 1; //移出数据的最高位 SDA = CY; //送数据口 SCL = 1; //拉高时钟线 Delay5us(); //延时 SCL = 0; //拉低时钟线 Delay5us(); //延时 } HMC5883_RecvACK(); } /************************************** 从IIC总线接收一个字节数据 **************************************/ BYTE HMC5883_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_HMC5883(uchar REG_Address,uchar REG_data) { HMC5883_Start(); //起始信号 HMC5883_SendByte(SlaveAddress); //发送设备地址+写信号 HMC5883_SendByte(REG_Address); //内部寄存器地址,请参考中文pdf HMC5883_SendByte(REG_data); //内部寄存器数据,请参考中文pdf HMC5883_Stop(); //发送停止信号 } //********单字节读取内部寄存器************************* //uchar Single_Read_HMC5883(uchar REG_Address) //{ // uchar REG_data; // HMC5883_Start(); //起始信号 // HMC5883_SendByte(SlaveAddress); //发送设备地址+写信号 // HMC5883_SendByte(REG_Address); //发送存储单元地址,从0开始 // HMC5883_Start(); //起始信号 // HMC5883_SendByte(SlaveAddress+1); //发送设备地址+读信号 // REG_data=HMC5883_RecvByte(); //读出寄存器数据 // HMC5883_SendACK(1); // HMC5883_Stop(); //停止信号 // return REG_data; //} //****************************************************** // //连续读出HMC5883内部角度数据,地址范围0x3~0x5 // //****************************************************** void Multiple_read_HMC5883(void) { uchar i; HMC5883_Start(); //起始信号 HMC5883_SendByte(SlaveAddress); //发送设备地址+写信号 HMC5883_SendByte(0x03); //发送存储单元地址,从0x3开始 HMC5883_Start(); //起始信号 HMC5883_SendByte(SlaveAddress+1); //发送设备地址+读信号 for (i=0; i<6; i++) //连续读取6个地址数据,存储中BUF { BUF[i] = HMC5883_RecvByte(); //BUF[0]存储数据 if (i == 5) { HMC5883_SendACK(1); //最后一个数据需要回NOACK } else { HMC5883_SendACK(0); //回应ACK } } HMC5883_Stop(); //停止信号 Delay5ms(); } void HMC5883Convert() { int x,y,z; double angle; Multiple_Read_HMC5883(); //连续读出数据,存储在BUF中 //---------------------------------------------------------------------------显示X轴 x=BUF[0] << 8 | BUF[1]; //Combine MSB and LSB of X Data output register z=BUF[2] << 8 | BUF[3]; //Combine MSB and LSB of Z Data output register y=BUF[4] << 8 | BUF[5]; //Combine MSB and LSB of Y Data output register angle= atan2((double)y,(double)x) * (180 / 3.14159265) + 180; // angle in degrees atan2(y,x) (-180,180) angle*=10; conversion(angle); //计算数据和显示 DisplayOneChar(0,0,'A'); DisplayOneChar(1,0,':'); DisplayOneChar(2,0,qian); DisplayOneChar(3,0,bai); DisplayOneChar(4,0,shi); DisplayOneChar(5,0,'.'); DisplayOneChar(6,0,ge); } /////////////////////////////// void Init_HMC5883() { Single_Write_HMC5883(0x02,0x00); } /////////////////////////////////// ADC0804 void ADC0804get() { adcs=0; adwr=0; //AD写入(随便写个什么都行,主要是为了启动AD转换) _nop_(); adwr=1; DataPort1=0xff; delay(10); delay(100); //需要注意的是ADC0804在写和读之间的时间间隔要足够长否则无法读出数据 adrd=0; //重新打开有AD片选信号锁存器的锁存端 _nop_(); adval=DataPort1; //AD数据读取赋给P1口 adrd=1; } /////////////////////////////// /////////////////////////////// void ADC0804convert() { uint i; ADC0804get(); i=adval; i*=196; conversion(i); DisplayOneChar(0,1,'U'); //显示电压 DisplayOneChar(1,1,':'); DisplayOneChar(2,1,shiwan); DisplayOneChar(3,1,wan); DisplayOneChar(4,1,'.'); DisplayOneChar(5,1,qian); DisplayOneChar(6,1,bai); DisplayOneChar(7,1,'V'); } //********************************************************* //主程序******** //********************************************************* void main() { delay(500); InitLcd(); Init_HMC5883(); //初始化HMC5883 Init_BMP085(); //初始化BMP085 while(1) //循环 { ADC0804convert(); HMC5883Convert(); bmp085Convert(); delay(100); } }
更多简介内容

推荐帖子

电路中电能传输方向
  如图(01)这个电路,有两个电池和一个电阻串联。这个电路中,是电池E1对电池E2充电,还是电池E2对电池E1充电?             图(01)   我们测量一下电压U1和电压U2。如果电压U1大于电压U2,就可以判断电阻R左端电位高于右端电位,显然电阻中电流方向是从左向右,如图(02)所示。此时我们就可以判断是电池E1对电池E2充电。当然,如果测量U1和U2结果相反,那就是E2
maychang 综合技术交流
【 ST NUCLEO-H743ZI测评】+ 开箱点灯
本帖最后由 sylar^z 于 2020-5-11 17:00 编辑          收到论坛评测的ST NUCLEO-H743ZI开发板了。感谢ST和EE提供的测评机会。     一、开箱上图。           NUCLEO-H743ZI开发板载ST-Link,只要连上一根USB线,就可以供电,并调试和下载程序了(这一步需要驱动,我之前装了KE
sylar^z 【stm32/stm8】
福禄克计量校准部邀请您来参加有奖问答啦!
在电学、温度、压力、射频和流量等领域提供范围广泛的校准器,标准器、软件、服务支持。 为各个行业的计量校准工程师,质量管控工程师、校准技术人员和计量学家提供各种标准,保证测量结果的可靠性和准确性。 为专业计量校准机构以及电力、过程、制造、控制等各行各业提供强大的技术支持和具有高精度等级以及性能良好和可靠性的仪器设备。 今天福禄克为大家带来一场线上互动小活动,还有精美礼品等你来拿,快快动手
EEWORLD社区 综合技术交流
边缘智能化为自主工厂提供动力
从传统的工业机器人系统到当今最新的协作机器人,各类机器人都依赖于能够生成和处理大量高度变化数据的传感器。这些数据可用于启用能够做出实时决策的自主机器人,从而实现更智能的事件管理,同时在动态的真实环境中保持生产力,如图1所示。 图1:毫米波(mmWave)传感有助于监控机器周围区域,实现实时事件管理 TI毫米波传感器如何在工厂实现高级智能化 德州仪器(TI)的毫米波(mmW
alan000345 【模拟与混合信号】
采用分级字线结构可提高SRAM读写速度及降低电路动态功耗
  采用分级字线结构的存储器将整个存储阵列划分为若干个相同的子阵列。与非分级字线结构相比,它需要采用多级的字线译码才能完成对存储单元的寻址。如图1所示,整个电路采用层次化字线的多分割阵列结构。     图1 分级字线结构   采用层次化字线分割结构不仅能提高工作速度,而且能大大降低功耗。这是因为字线分割结构使原本同时被激活的存储单元变为只有被选中的块内的存储单元
是酒窝啊 【其他嵌入式操作系统】
MSP430--低功耗模式
1.CPU的结构:16个寄存器R0-R15,16位算数逻辑单元ALU和一个指令控制单元。 2.寄存器中R4-R15是通用寄存器没有特殊功能。   R0-R3具有特殊性:   R0:程序计数器PC(Program counter),存放着下一条要从程序存储器中取出的指令的地址。   R1:堆栈指针SP(Stack Point),系统堆栈在系统调用子函数或者进入中断服务程序时,
Aguilera 【微控制器 MCU】

评论

登录/注册

意见反馈

求资源

回顶部

datasheet推荐 换一换

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版 版权声明

北京市海淀区知春路23号集成电路设计园量子银座1305 电话:(010)82350740 邮编:100191

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved
$(function(){ var appid = $(".select li a").data("channel"); $(".select li a").click(function(){ var appid = $(this).data("channel"); $('.select dt').html($(this).html()); $('#channel').val(appid); }) })