LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

ZL27ARM: obsługa czujnika MEMS do pomiaru ciśnienia – BMP085

Funkcja: BMP085_ReadShort(adres) odczytuje dwa kolejne bajty z czujnika ciśnienia z czego jako argument przyjmuje adres pierwszego bajtu (MSB), adres drugiego bajtu (LSB) jest o 1 większy od adresu podanego funkcji. Na podstawie dwóch 8 bitowych liczb stworzona zostaje liczba 16 bitowa która zostaje zwrócona przez funkcję:

    data = msb << 8;
    data |= lsb;
    return data;

Po odczycie i zapisaniu tych danych do odpowiednich zmiennych program w nieskończonej pętli wywołuje odpowiednie funkcje:

	while(1)
	{
	//Oblicz temp, cisnienie, wysokosc
	BMP085_Convert(&temperature,&pressure,&altitude);		

	//PrzeksztaBcanie liczb na stringa
	sprintf((char *)Tekstalt,"%5d.%02dm \0",altitude/100,altitude-((altitude/100)*100));
	sprintf((char *)Teksttemp,"%4d\0",temperature);
	sprintf((char *)Tekstpres,"%7d\0",pressure);	
 	
	//Wyswietlenie danych
	LCD_WriteTextXY(Tekstalt,7,1);
	LCD_WriteTextXY(Teksttemp,2,0);
	LCD_WriteTextXY(Tekstpres,10,0);

	//Zmiana stanu LED8 na ZL27ARM
	GPIO_WriteBit(GPIOB, GPIO_Pin_15, (BitAction)
	(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_15)));		
	}

Najważniejsza: BMP085_Convert(short* temperature, long* pressure, long* altitude);
wygląda jak poniżej:

const unsigned char OSS = 3;
void BMP085_Convert(short* temperature, long* pressure, long* altitude)
{
  unsigned short ut;
  unsigned long up;
  float dp, wyk, alt;
  short x2, b5, b6, x3;
  long x1, p,b3;
  unsigned long b4;
  unsigned long b7;
  extern short ac1, ac2, ac3, b1, b2, mc, md;
  extern unsigned short ac4, ac5, ac6;

  //Odczyt temperatury bezposrednio z czujnika
  ut = BMP085_ReadTemp();   

  //Odczyt cisnienia bezposrednio z czujnika	
  up = BMP085_ReadPressure();
  //Obliczanie temperatury
  x1 = (((short)ut - (short)ac6) * (short)ac5) >> 15;
  x2 = ((short) mc << 11) / (x1 + md);
  b5 = x1 + x2;
  *temperature = (((b5 + 8) >> 4))/10;

  //Obliczanie ciśnienia
  b6 = b5 - 4000;
  x1 = (b2 * (b6 * b6) >> 12) >> 11;
  x2 = (ac2 * b6) >> 11;
  x3 = x1 + x2;
  b3 = (((((short)ac1)*4 + x3)<>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;	
  *pressure = p;

  //Obliczanie wysokości	
  dp=((float)p)/101325;
  wyk=1/5.25588;
  alt=1-(pow(dp,wyk));
  alt=alt*4433000;
  *altitude=(long)alt;
}

Na początku w funkcji BMP085_ReadTemp () odczytywany jest rejestr 0xF6 czujnika celem zapisania jego wartości do zmiennej ut:

unsigned short BMP085_ReadTemp(void)
{
	
    BMP085_WriteRegister(0xF4, 0x2E);
    delay_ms(50);    // max time is 4.5ms
    return BMP085_ReadShort(0xF6);
}