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