eagler8 发表于 2019-7-25 11:50:32

/*
【Arduino】66种传感器模块系列实验(68)
实验六十八:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
程序之二,气温、气压与海拔值可以调整并校准
*/

#include <Wire.h>
#define BMP180ADD 0x77   
                                 
unsigned char OSS;                           

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;            
float temperature;
double pressure;   
double pressure2;
long b5;         
double altitude;



void setup()
{
Serial.begin(9600);
Wire.begin();
OSS = 2;
BMP180start();
}

void loop()
{
calculate();
show();
delay(1000);
}

void calculate()
{
temperature = bmp180GetTemperature(bmp180ReadUT());
temperature = temperature*0.0137;
pressure = bmp180GetPressure(bmp180ReadUP());
pressure2 = pressure/115325;
pressure2 = pow(pressure2,0.29029496);
altitude = 39*(1+pressure2);                           
}


void show()
{
Serial.print("气温: ");
Serial.print(temperature, 1);                           
Serial.println(" C");
Serial.print("气压: ");
Serial.print(pressure, 0);                              
Serial.println(" Pa");
Serial.print("海拔:");
Serial.print(altitude);
Serial.println("m");
}

void BMP180start()
{                     
ac1 = bmp180ReadDate(0xAA);                     
ac2 = bmp180ReadDate(0xAC);
ac3 = bmp180ReadDate(0xAE);
ac4 = bmp180ReadDate(0xB0);
ac5 = bmp180ReadDate(0xB2);
ac6 = bmp180ReadDate(0xB4);
b1= bmp180ReadDate(0xB6);
b2= bmp180ReadDate(0xB8);
mb= bmp180ReadDate(0xBA);
mc= bmp180ReadDate(0xBC);
md= bmp180ReadDate(0xBE);
}

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);                           
}

long bmp180GetPressure(unsigned long up)
{
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;

b6 = b5 - 4000;

x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

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;
}

int bmp180Read(unsigned char address)
{
unsigned char data;

Wire.beginTransmission(BMP180ADD);
Wire.write(address);
Wire.endTransmission();

Wire.requestFrom(BMP180ADD, 1);
while(!Wire.available());
   
return Wire.read();
}

int bmp180ReadDate(unsigned char address)
{
unsigned char msb, lsb;
Wire.beginTransmission(BMP180ADD);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP180ADD, 2);
while(Wire.available()<2);
msb = Wire.read();
lsb = Wire.read();
return (int) msb<<8 | lsb;
}

unsigned int bmp180ReadUT()
{
unsigned int ut;
Wire.beginTransmission(BMP180ADD);
Wire.write(0xF4);                     
Wire.write(0x2E);                     
Wire.endTransmission();
delay(5);                              
ut = bmp180ReadDate(0xF6);               
return ut;
}

unsigned long bmp180ReadUP()
{
unsigned char msb, lsb, xlsb;
unsigned long up = 0;

Wire.beginTransmission(BMP180ADD);
Wire.write(0xF4);                        
Wire.write(0x34 + (OSS<<6));            
Wire.endTransmission();
delay(2 + (3<<OSS));                     

Wire.beginTransmission(BMP180ADD);
Wire.write(0xF6);                        
Wire.endTransmission();

Wire.requestFrom(BMP180ADD, 3);
while(Wire.available() < 3);            
msb = Wire.read();
lsb = Wire.read();
xlsb = Wire.read();
up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);//16 to 19 bit
return up;
}

eagler8 发表于 2019-7-25 11:52:53

eagler8 发表于 2019-7-25 12:13:41

/*
【Arduino】66种传感器模块系列实验(68)
实验六十八:BMP180 新款 BOSCH温度模块气压传感器(代替BMP085)
程序之三,温度、实时气压、已知海拔计算的海平面的气压、已知海平面气压计算的高度
只是算法有点烂,做做实验而已
*/

#include <SFE_BMP180.h>
#include <Wire.h>

SFE_BMP180 pressure;

#define ALTITUDE 255.0

unsigned long gpstimes;

void setup()
{
Serial.begin(9600);

pressure.begin();

}

void loop()
{
gpstimes=millis();

char status;
double T,P,p0,a;

status = pressure.startTemperature();
delay(status);
status = pressure.getTemperature(T);
delay(status);

Serial.print("temperature: ");
Serial.print(T,2);
Serial.println(" deg C, ");



status = pressure.startPressure(3);
delay(status);

status = pressure.getPressure(P,T);

// Print out the measurement:
Serial.print("absolute pressure A: ");
Serial.print(P,2);
Serial.println(" mb, ");

p0=1013.2;

a = pressure.altitude(P,p0);
Serial.print("computed altitude A: ");
Serial.print(a,0);
Serial.println(" meters, ");

T=25.00;
status = pressure.getPressure(P,T);

Serial.print("absolute pressure B: ");
Serial.print(P,2);
Serial.println(" mb, ");

p0=1013.2;

a = pressure.altitude(P,p0);
Serial.print("computed altitude B: ");
Serial.print(a,0);
Serial.println(" meters, ");

gpstimes=millis()-gpstimes;
Serial.print("gpstimes=");
Serial.println(gpstimes);
Serial.println();
delay(2000);
}

eagler8 发表于 2019-7-25 12:52:36

eagler8 发表于 2019-7-25 13:47:48

实验六十九: AT24C256 I2C接口 EEPROM 存储模块 IIC

AT24C256
是ATMEL公司256kbit串行电可擦的可编程只读存储器,8引脚双排直插式封装,具有结构紧凑、存储容量大等特点,可以在2线总线上并接4片该IC,特别适用于具有高容量数据储存要求的数据采集系统。AT24C256采用SOP-8封装。

eagler8 发表于 2019-7-25 14:29:23

芯片参数
芯片有3种工作电压;
  5.0V(VCC=4.5V~5.5V)
  2.7V(VCC=2.7V~5.5V)
  1.8V(VCC=1.8V~3.6V)
特性:
  内部可以组成32k×8存储单元
  2线串行接口
  斯密特触发,滤波输入抑制噪声
  双向数据传送协议
  硬件写保护引脚和软件数据保护功能
  具有64字节页写模式

eagler8 发表于 2019-7-25 14:31:31

eagler8 发表于 2019-7-25 14:46:05

A0、A1:地址选择输入端。在串行总线结构中,可以连接4个AT24C256IC。用A0、A1来区分各IC。A0、A1悬空时为0。
SCL:串行时钟输入。上升沿将SDA上的数据写入存储器,下降沿从存储器读出数据送SDA上。
SDA:双向串行数据输入输出口。用于存储器与单片机之间的数据交换。
WP:写保护输入。此引脚与地相连时,允许写操作;与VCC相连时,所有的写存储器操作被禁止。如果不连,芯片内部下拉到地。
VCC:电源。
GND:地。
NC:空。

eagler8 发表于 2019-7-25 15:21:33

AT24C256的工作原理
AT24C256内部有512页,每一页为64字节,任一单元的地址为15位。地址范围0000H~7FFFH。
芯片工作状态
1)时钟和数据传送
一般情况下,SDA被外部的设备拉到高,只有当SCL为低电平时,SDA上的数据变化,表示要传送数据。SCL为高时SDA变化表示状态变化。
2)开始状态(START)
当SCL为高时,SDA由高到低表示数据传送开始,这一状态必须在所有命令之前。
3)结束状态(STOP)
当SCL为高时,SDA由低到高表示数据传送结束状态。
4)应答状态(ACK)
所有的地址和数据都是以8位的形式串行传送给存储器或从存储器读出的。存储器在第9个时钟周期SDA发零信号表示已经收到8位数据。见图总线协议图。

eagler8 发表于 2019-7-25 15:35:13

AT24C256 I2C接口 EEPROM 存储模块


eagler8 发表于 2019-7-25 15:39:21

1.板载芯片AT24C256进口芯片;
2.板载I2C通讯所需的上拉电阻;
3.所有管脚均引出并标注;
4.PCB板子尺寸:1.9(CM)x1.1(CM)

eagler8 发表于 2019-7-25 15:46:25

模块电原理图

eagler8 发表于 2019-7-25 17:17:49

/*
【Arduino】66种传感器模块系列实验(69)
实验六十九: AT24C256 I2C接口 EEPROM 存储模块
*/

#include <Wire.h>

#define ADDRESS_AT24C256 0x50

word wordAddress = 0x0F00;
char str[] = "This is ZLBG.";
byte buffer;

int i;

void setup()
{
    Wire.begin();
    Serial.begin(9600);

    //write
    Wire.beginTransmission(ADDRESS_AT24C256);
    Wire.write(highByte(wordAddress));
    Wire.write(lowByte(wordAddress));
    for (i = 0; i < sizeof(str); i++)
    {
      Wire.write(byte(str));
    }
    Wire.endTransmission();   

    delay(10);
}

void loop()
{
   
    Wire.beginTransmission(ADDRESS_AT24C256);
    Wire.write(highByte(wordAddress));
    Wire.write(lowByte(wordAddress));
    Wire.endTransmission();
    Wire.requestFrom(ADDRESS_AT24C256, sizeof(str));
    if(Wire.available() >= sizeof(str))
    {
      for (i = 0; i < sizeof(str); i++)
      {
            buffer = Wire.read();
      }
    }

   
    for(i = 0; i < sizeof(str); i++)
    {
      Serial.print(char(buffer));
    }
    Serial.println();

    delay(2000);
}

eagler8 发表于 2019-7-25 17:20:28

eagler8 发表于 2019-7-25 17:40:47

/*
【Arduino】66种传感器模块系列实验(69)
实验六十九: AT24C256 I2C接口 EEPROM 存储模块
程序之二
*/

#include <Wire.h>
#define EEPROM_ADDR 0x50   
      
void setup()
{
Wire.begin();                        
Serial.begin(9600);

// TESTS FOR EACH FUNCTION BEGIN HERE
Serial.println("Writing Test:");
for (int i=0; i<20; i++){            
    i2c_eeprom_write_byte(EEPROM_ADDR,i,i+65);   
    Serial.print(". ");
    delay(10);                        
}
Serial.println("");
delay(500);

Serial.println("Reading Test:");
for (int i=0; i<20; i++){            
    Serial.write(i2c_eeprom_read_byte(EEPROM_ADDR, i));
    Serial.print(" ");
}

byte PageData;                  
byte PageRead;                  
for (int i=0; i<30; i++){            
    PageData = 0;
    PageRead = 0;
}
Serial.println("");
for (int i=0; i<30; i++) PageData = i+33;
Serial.println("Writing Page Test:");
i2c_eeprom_write_page(EEPROM_ADDR, 100, PageData, 28 );
Serial.println("Reading Page Test:");
i2c_eeprom_read_buffer( EEPROM_ADDR, 100, PageRead, 28);
for (int i=0; i<28; i++){
    Serial.write(PageRead);   
    Serial.print(" ");
}
}

void loop()
{
}

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data )
{
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8));   
Wire.write((int)(eeaddress & 0xFF));
Wire.write(rdata);
Wire.endTransmission();
}


void i2c_eeprom_write_page
( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length )
{
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddresspage >> 8));
Wire.write((int)(eeaddresspage & 0xFF));
byte c;
for ( c = 0; c < length; c++)
    Wire.write(data);
Wire.endTransmission();
delay(10);                           
}

byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress )
{
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8));   
Wire.write((int)(eeaddress & 0xFF));
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}

void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length )
{
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8));   
Wire.write((int)(eeaddress & 0xFF));
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);

for ( int c = 0; c < length; c++ )
    if (Wire.available()) buffer = Wire.read();
}
页: 75 76 77 78 79 80 81 82 83 84 [85] 86 87 88 89 90 91 92 93 94
查看完整版本: 【Arduino】108种传感器模块系列实验(资料+代码+图形+仿真)