/*********************
BMP180驱动程序
2014-12-19
Leven
主要函数为BMP180_getdat();
两种读取方法:
可以函数直接输出32位的数据
也可以直接调用全局变量,bmp180_temp,bmp180_press分别是温度和压强
说明:
压强数据最后两位是小数,单位是帕斯卡,数据大约是10170000
温度数据单位没留意,不过也用不上。。。。
温度和压强分别引入一阶和二阶低通滤波,压强的低通是分段的低通,当接近目标值时将上限截止频率降低
不想用滤波也可以将滤波的部分注释掉
*********************/
#include "bmp180.h"
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;
s32 bmp180_temp,bmp180_press;
/***********
本程序用到的延时(4.5ms)
一共用了两次
***********/
void BMP180_delay(void)
{
u32 count=200000;
while(count--);
}
/****************
IIC与BMP180通讯驱动
****************/
/*
u8 Read_BMP180(u8 REG_Address)
{
u8 REG_data;
IIC_Start(); //起始信号
IIC_Send_Byte(BMP180_Address); //发送设备地址+写信号
IIC_Wait_Ack();
IIC_Send_Byte(REG_Address); //发送存储单元地址,从0开始
IIC_Wait_Ack();
IIC_Start(); //起始信号
IIC_Send_Byte(BMP180_Address+1); //发送设备地址+读信号
IIC_Wait_Ack();
REG_data=IIC_Read_Byte(0); //读出寄存器数据
IIC_Stop(); //停止信号
return REG_data;
}
*/
void Multiple_read_BMP180(u8 add,u8*BUF,u16 num)
{
u8 i;
IIC_Start(); //起始信号
IIC_Send_Byte(BMP180_Address); //发送设备地址+写信号
IIC_Wait_Ack();
IIC_Send_Byte(add); //发送存储单元地址
IIC_Wait_Ack();
IIC_Start(); //起始信号
IIC_Send_Byte(BMP180_Address+1); //发送设备地址+读信号
IIC_Wait_Ack();
for (i=0; i<num; i++) //连续读取num个地址数据,存储中BUF
{
if (i == num-1)
{
BUF[i] = IIC_Read_Byte(0); //最后一个数据需要回NOACK
}
else
{
BUF[i] = IIC_Read_Byte(1); //返回ACK
}
}
IIC_Stop(); //停止信号
}
void Write_BMP180(u8 add, u8 da)
{
IIC_Start(); //起始信号
IIC_Send_Byte(BMP180_Address); //发送设备地址+写信号
IIC_Wait_Ack();
IIC_Send_Byte(add); //内部寄存器地址,请参考中文pdf
IIC_Wait_Ack();
IIC_Send_Byte(da); //内部寄存器数据,请参考中文pdf
IIC_Wait_Ack();
IIC_Stop(); //发送停止信号
}
/*
void Multiple_write_BMP180(u8 add,u8*BUF,u16 num)
{
while(num--)
{
Write_BMP180(add++, *BUF++);
}
}
*/
/***************
上面是读取数据的驱动
下面开始读取数据
***************/
/*******************
读取补偿数据
*******************/
void Read_calibration(void)
{
u8 buf[2];
Multiple_read_BMP180(0xaa,buf, 2);
ac1 = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xac,buf, 2);
ac2 = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xae,buf, 2);
ac3 = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xb0,buf, 2);
ac4 = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xb2,buf, 2);
ac5 = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xb4,buf, 2);
ac6 = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xb6,buf, 2);
b1 = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xb8,buf, 2);
b2 = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xba,buf, 2);
mb = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xbc,buf, 2);
mc = buf[0] << 8 |buf[1];
Multiple_read_BMP180(0xbe,buf, 2);
md = buf[0] << 8 |buf[1];
}
/*********************
获取压强数据
*********************/
s32 BMP180_getdat(void)
{
long x1,x2,x3,b3,b5,b6,b7,UP,press,UT,temp;
unsigned long b4;
u8 ReadBuffer[3];
char oss = 0; //这个值在读气压时可以置进寄存器
static float press_fliter=101700,press_q=0.1,temp_fliter=20000,temp_q=0.1;//低通滤波&初值
//读取补偿数据
Read_calibration();
//读取原始温度数据
Write_BMP180(0xf4,0x2e);
BMP180_delay(); //delay 4.5ms
Multiple_read_BMP180(0xf6,ReadBuffer,2);
UT = ReadBuffer[0] << 8 | ReadBuffer[1];
//读取原始压强数据
Write_BMP180(0xf4,(0x34 +(oss<<6)));
BMP180_delay(); //delay 4.5ms
Multiple_read_BMP180(0xf6,ReadBuffer,3);
UP = ((ReadBuffer[0] << 16)+(ReadBuffer[1] << 8)+ReadBuffer[2]) >> (8 - oss);
//温度换算
x1 = ((UT - ac6) * ac5) >> 15;
x2 = ((long) mc << 11) / (x1 + md);
b5 = x1 + x2;
temp = ((b5 + 8)*100) >> 4;//*100是为了增加两位,temp即为读出数据
//开始滤波算法
temp_fliter = temp_fliter*(1-temp_q)+(float)temp*temp_q;
bmp180_temp=temp_fliter;
//压强换算
b6 = b5 - 4000;
x1 = (b2 * ((b6 * b6) >> 12)) >> 11;
x2 = (ac2 * b6) >> 11;
x3 = x1 + x2;
b3 = ((((long)ac1 * 4 + x3) << oss) + 2) / 4;
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)
press = (b7 * 2) / b4;
else
press = (b7 / b4 ) * 2;
x1 = ((press) >> 8) * ((press) >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * press) >> 16;
press = press + (((x1 + x2 + 3791)) >> 4);//press即为读出的数据
//开始滤波算法
if(fabs(press_fliter-press)<100)press_q=fabs(press_fliter-press)/1000;
else press_q=0.1;
press_fliter = press_fliter*(1-press_q)+(float)press*press_q;
bmp180_press = press_fliter*100;
return bmp180_press;
}
柳风V
- 粉丝: 7
- 资源: 9
最新资源
- 信息安全与加密技术基础教程
- 五相电机svpwm控制Matlab仿真
- 模块化多电平流器MMC-HVDC,PSCAD仿真 21电平,内附说明文档 需要PSCAD安装包的可以提供4.6.2版本,含安装教程
- 项目源码管理与协作基础教程
- 光伏+电池协调控制,平滑输出的相关simulink MATLAB仿真模型 光伏+电池并网控制等仿真模型 光伏给电池优化的充电控制器建模 三种工作模式: 1.光伏给电池充电给负载供电 2.负载增大
- comso多层膜石墨烯传感
- 微信小程序开发入门基础教程
- comsol岩石压裂损失模型,附带视频和原模型
- 三相电压源逆变器模型预测电流控制 滑膜扰动观测器 电流环无模型滑模控制smo
- 光伏储能并网VSG同步机一次调频matlab simulink,可分析不同惯量J,不同阻尼D对系统频率的影响 光伏直流侧并入电池储能,通过逆变器连接交流电网,逆变器采用VSG同步机控制〔也可替成风光
- MATLAB仿真 基于IEEE33潮流计算的加入风光储能主动配电网优化 采用IEEE33节点配电网进行仿真,搭建了含风光,储能,柴油发电机和燃气轮机的配电网经济调度模型,程序内带有风电、光伏和储能的潮
- 基于yolov5的钢板表面缺陷检测(包含源码和数据集以及训练好的权重文件) 夹杂、划痕、压入氧化皮、裂纹、麻点、斑块6种缺陷
- 五电平无刷直流电机BLDC矢量控制仿真模型,给定转速1000r min,运行良好; 三电平,两电平均可做,可调参数; matlab simulink模型
- 电力系统励磁涌流有关的问题分析 可以通过MATLAB中m文件便编写产生励磁涌流,也可以通过simulink仿真出励磁涌流 可以仿真分析影响励磁涌流的因素,以及抑制励磁涌流的措施 可以研究识别励磁
- MCGS仿真画圆程序,通过输入圆的半径即可仿真模拟画出圆的轨迹 可画多个圆 并显示当前X轴和Y轴实时位置和圆的角度,可随时清除重新画
- 高仿正浩创新图腾柱PFC抖频技术,逃逸检测窗,实际应用确实大幅度提高EMC通过率
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈