/* 从BMP180传感器读取温度与气压数据。 通过Serial.print命令以9600波特率发送至串口监视器。 */ #include #define BMP180_ADDRESS 0x77 // BMP180的I2C地址 const unsigned char OSS = 0; // 采样设置 // 校准值 int ac1; int ac2; int ac3; unsigned int ac4; unsigned int ac5; unsigned int ac6; int b1; int b2; int mb; int mc; int md; // b5用于计算bmp180GetTemperature(...),它也同时用于bmp180GetPressure(...) // 所以Temperature(...)必须在Pressure(...)之前声明 long b5; short temperature; long pressure; void setup() { Serial.begin(9600); Wire.begin(); bmp180Calibration(); } void loop() { temperature = bmp180GetTemperature(bmp180ReadUT()); pressure = bmp180GetPressure(bmp180ReadUP()); Serial.print("Temperature: "); Serial.print(temperature, DEC); Serial.println(" *0.1 deg C"); Serial.print("Pressure: "); Serial.print(pressure, DEC); Serial.println(" Pa"); Serial.println(); delay(1000); } // 存储所有的BMP180的校准值到全局变量 // 校准值用来计算温度与气压 // 这个函数应该放在程序的开头 void bmp180Calibration() { ac1 = bmp180ReadInt(0xAA); ac2 = bmp180ReadInt(0xAC); ac3 = bmp180ReadInt(0xAE); ac4 = bmp180ReadInt(0xB0); ac5 = bmp180ReadInt(0xB2); ac6 = bmp180ReadInt(0xB4); b1 = bmp180ReadInt(0xB6); b2 = bmp180ReadInt(0xB8); mb = bmp180ReadInt(0xBA); mc = bmp180ReadInt(0xBC); md = bmp180ReadInt(0xBE); } // 计算温度赋值给变量ut // 返回值的精度在0.1摄氏度 short bmp180GetTemperature(unsigned int ut) { long x1, x2; x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; x2 = ((long)mc << 11)/(x1 + md); b5 = x1 + x2; return ((b5 + 8)>>4); } // 计算压力 // 校准值必须是已知的 // B5在bmp180GetTemperature(...)需要使用,所以必须先调用。 // 返回值以Pa为单位 long bmp180GetPressure(unsigned long up) { long x1, x2, x3, b3, b6, p; unsigned long b4, b7; b6 = b5 - 4000; // 计算B3 x1 = (b2 * (b6 * b6)>>12)>>11; x2 = (ac2 * b6)>>11; x3 = x1 + x2; b3 = (((((long)ac1)*4 + x3)<>2; // 计算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; p += (x1 + x2 + 3791)>>4; return p; } // 在BMP180的'address'中读取一个字节 char bmp180Read(unsigned char address) { unsigned char data; Wire.beginTransmission(BMP180_ADDRESS); Wire.write(address); Wire.endTransmission(); Wire.requestFrom(BMP180_ADDRESS, 1); while(!Wire.available()) ; return Wire.read(); } // 从BMP180读取两个字节 // 第一个字节是从'address' // 第二个字节是从'address'+1 int bmp180ReadInt(unsigned char address) { unsigned char msb, lsb; Wire.beginTransmission(BMP180_ADDRESS); Wire.write(address); Wire.endTransmission(); Wire.requestFrom(BMP180_ADDRESS, 2); while(Wire.available()<2); msb = Wire.read(); lsb = Wire.read(); return (int) msb<<8 | lsb; } // 读取未补偿的温度值 unsigned int bmp180ReadUT() { unsigned int ut; // 在寄存器0xF4写入0x2E // 这个用来请求进行温度读取 Wire.beginTransmission(BMP180_ADDRESS); Wire.write(0xF4); Wire.write(0x2E); Wire.endTransmission(); // 至少等待4.5ms delay(5); // 从寄存器0xF6与0xF7读取两个字节 ut = bmp180ReadInt(0xF6); return ut; } // 读取未补偿的压力值 unsigned long bmp180ReadUP() { unsigned char msb, lsb, xlsb; unsigned long up = 0; // 写入0x34+(OSS<<6)到寄存器0xF4 // 请求气压数据读取 Wire.beginTransmission(BMP180_ADDRESS); Wire.write(0xF4); Wire.write(0x34 + (OSS<<6)); Wire.endTransmission(); // 等待转换,延迟时间依赖于OSS delay(2 + (3<> (8-OSS); return up; }