基于STM32平台的BMP180测试(模拟IIC)
来源:互联网 发布:python 捕捉ctrl c 编辑:程序博客网 时间:2024/06/15 21:35
1.测试描述:
使用模拟IIC,从BMP180中获取ID号、温度值、气压值以及计算海拔高度。
2.测试准备:
硬件平台:原子战舰V3开发板
测试工具:逻辑分析仪、串口调试工具
3.数据手册解读:
(1) 首先是多个字节的读取时序图,从这里也可以看出BMP180芯片的地址+写信号是0xEE,地址+读信号为0xEF,当然手册前面也有提到过,有兴趣的可以自己去查看一下手册。
(2) 然后本人测试时默认使用的是下图画横线部分的部分,也就是气压这块使用的是低功耗模式。OSS的值要注意,因为后期的计算需要这个,并且读取UT值时也要做对应的处理。
(3) 下图就是手册里给出的利用BMP180里的参数计算气压和温度的流程图。特别注意流程里的OSS,由于本测试使用的OSS = 0,所以在实际代码中省去了这一部分。
4.测试代码:
由于本工程是直接使用原子战舰的标准例程-库函数版本\实验23 IIC实验源码改过来的,所以模拟IIC部分使用的原子这块的代码。BMP180部分由本人编写。
(1) 首先是BMP180.C的代码片
#include "bmp180.h"#include "delay.h"#include "math.h"//存储BMP180数据的结构_bmp180 bmp180;//BMP180初始化//对使用的IIC端口进行初始化void BMP_Init(void){ IIC_Init();}//写一个数据到BMP180void BMP_WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite){ IIC_Start(); IIC_Send_Byte(0xEE); IIC_Wait_Ack(); IIC_Send_Byte(WriteAddr); IIC_Wait_Ack(); IIC_Send_Byte(DataToWrite); IIC_Wait_Ack(); IIC_Stop();}//从BMP180读一个字节数据uint8_t BMP_ReadOneByte(uint8_t ReadAddr){ uint8_t data = 0; IIC_Start(); IIC_Send_Byte(0xEE); IIC_Wait_Ack(); IIC_Send_Byte(ReadAddr); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(0xEF); IIC_Wait_Ack(); data = IIC_Read_Byte(1); IIC_Stop(); return data;}//从BMP180读一个16位的数据short BMP_ReadTwoByte(uint8_t ReadAddr){ short data; uint8_t msb,lsb; IIC_Start(); IIC_Send_Byte(0xEE); IIC_Wait_Ack(); IIC_Send_Byte(ReadAddr); IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(0xEF); IIC_Wait_Ack(); msb = IIC_Read_Byte(1); lsb = IIC_Read_Byte(0); IIC_Stop(); data = msb*256 + lsb; return data;}//从BMP180的获取计算参数void BMP_ReadCalibrationData(void){ bmp180.AC1 = BMP_ReadTwoByte(0xAA); bmp180.AC2 = BMP_ReadTwoByte(0xAC); bmp180.AC3 = BMP_ReadTwoByte(0xAE); bmp180.AC4 = BMP_ReadTwoByte(0xB0); bmp180.AC5 = BMP_ReadTwoByte(0xB2); bmp180.AC6 = BMP_ReadTwoByte(0xB4); bmp180.B1 = BMP_ReadTwoByte(0xB6); bmp180.B2 = BMP_ReadTwoByte(0xB8); bmp180.MB = BMP_ReadTwoByte(0xBA); bmp180.MC = BMP_ReadTwoByte(0xBC); bmp180.MD = BMP_ReadTwoByte(0xBE);}//从BMP180读取未修正的温度long BMP_Read_UT(void){ long temp = 0; BMP_WriteOneByte(0xF4,0x2E); delay_ms(5); temp = (long)BMP_ReadTwoByte(0xF6); return temp;}//从BMP180读取未修正的大气压long BMP_Read_UP(void){ long pressure = 0; BMP_WriteOneByte(0xF4,0x34); delay_ms(5); pressure = (long)BMP_ReadTwoByte(0xF6); //pressure = pressure + BMP_ReadOneByte(0xf8); pressure &= 0x0000FFFF; return pressure;}//用获取的参数对温度和大气压进行修正,并计算海拔void BMP_UncompemstatedToTrue(void){ bmp180.UT = BMP_Read_UT();//第一次读取错误 bmp180.UT = BMP_Read_UT();//进行第二次读取修正参数 bmp180.UP = BMP_Read_UP(); bmp180.X1 = ((bmp180.UT - bmp180.AC6) * bmp180.AC5) >> 15; bmp180.X2 = (((long)bmp180.MC) << 11) / (bmp180.X1 + bmp180.MD); bmp180.B5 = bmp180.X1 + bmp180.X2; bmp180.Temp = (bmp180.B5 + 8) >> 4; bmp180.B6 = bmp180.B5 - 4000; bmp180.X1 = ((long)bmp180.B2 * (bmp180.B6 * bmp180.B6 >> 12)) >> 11; bmp180.X2 = ((long)bmp180.AC2) * bmp180.B6 >> 11; bmp180.X3 = bmp180.X1 + bmp180.X2; bmp180.B3 = ((((long)bmp180.AC1) * 4 + bmp180.X3) + 2) /4; bmp180.X1 = ((long)bmp180.AC3) * bmp180.B6 >> 13; bmp180.X2 = (((long)bmp180.B1) *(bmp180.B6*bmp180.B6 >> 12)) >>16; bmp180.X3 = ((bmp180.X1 + bmp180.X2) + 2) >> 2; bmp180.B4 = ((long)bmp180.AC4) * (unsigned long)(bmp180.X3 + 32768) >> 15; bmp180.B7 = ((unsigned long)bmp180.UP - bmp180.B3) * 50000; if(bmp180.B7 < 0x80000000) { bmp180.p = (bmp180.B7 * 2) / bmp180.B4; } else { bmp180.p = (bmp180.B7 / bmp180.B4) * 2; } bmp180.X1 = (bmp180.p >> 8) * (bmp180.p >>8); bmp180.X1 = (((long)bmp180.X1) * 3038) >> 16; bmp180.X2 = (-7357 * bmp180.p) >> 16; bmp180.p = bmp180.p + ((bmp180.X1 + bmp180.X2 + 3791) >> 4); bmp180.altitude = 44330 * (1-pow(((bmp180.p) / 101325.0),(1.0/5.255))); }
(2) 然后是BMP180.H部分
#ifndef _BMP180_H_#define _BMP180_H_#include "myiic.h"typedef struct __BMP180{ 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; long UT; long UP; long X1; long X2; long X3; long B3; unsigned long B4; long B5; long B6; long B7; long p; long Temp; float altitude;}_bmp180;extern _bmp180 bmp180;void BMP_Init(void);uint8_t BMP_ReadOneByte(uint8_t ReadAddr);void BMP_WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite);short BMP_ReadTwoByte(uint8_t ReadAddr);void BMP_ReadCalibrationData(void);long BMP_Read_UT(void);long BMP_Read_UP(void);void BMP_UncompemstatedToTrue(void);#endif
由于是测试,所以将所有的参数都建了一个结构体,方便DEBUG时通过WATCH窗口查看,实际使用当中可以将一些非必要的参数做成临时变量。
5.测试时遇到的问题:
在BMP_UncompemstatedToTrue函数中,开头时首先读取UT和UP的值。开始时两者都只是读取一次,测算时发现UT值并未正确读出,为0,从而导致算出来的实际温度值在-71度左右,海拔在2500多米。通过逻辑分析仪监测,发现在第一次读取数据时,模拟IIC部分发出的数据是错误的。如下图画线处所示:
但是从图中可以看出,后面部分是正常的。针对这个现象我对延时、底层驱动模块都做了改变和测试,没有任何的改观。所以后面将UT值读取两次,就是为了消除这个错误,这也是一个折中的办法。经修改后实测读取正常。
6.测试结果:
本人在上海,平均海拔在4m的样子,温度值基本一致。由于海拔、温度、气压三者之间的联系,所以该气压也大致可以认定为测算出的实际大气压。
7.测试源码:
链接:http://pan.baidu.com/s/1gfH2SXd 密码:zr7g
- 基于STM32平台的BMP180测试(模拟IIC)
- AT24C02的Stm32模拟读写IIC程序(续)
- 关于STM32模拟IIC的理解
- AT24C02的Stm32模拟读写IIC程序
- 关于STM32 的 硬件IIC和 模拟IIC理解学习
- STM32模拟 IIC
- STM32软件模拟IIC
- STM32模拟IIC
- STM32模拟IIC
- STM32模拟IIC读写AT24CXX
- STM32 IO 模拟IIC I2C
- IIC总线从零梳理(结合STM32平台)
- STM32的IIC
- STM32 IIC的学习
- stm32的IIC知识点
- STM32 模拟IIC主设备 非IIC静默模式
- STM32硬件IIC与51模拟IIC通信
- STM32模拟IIC读写24CXX
- 微信蓝牙BLE接入调试指引
- Java类加载器总结
- 系统启动流程(七)
- FPGA资料
- windows下Solr安装
- 基于STM32平台的BMP180测试(模拟IIC)
- Select模型设计200人服务器
- 指针函数与函数指针的指导
- SCI论文发表心得
- [book]《智能时代》
- Mac安装nltk后在python 3的IDLE中import nltk报错
- opentsdb部署与安装
- 学习mysql数据库
- 纯js实现拖拽功能