Freescale Semiconductor MPL115: cyfrowy barometr MEMS
Moduły KAmodBAR są dostępne w dwóch wersjach, różniących się między sobą typem zastosowanego czujnika MEMS i wynikającym z tego rodzajem interfejsu komunikacyjnego:
|
Najpierw poprzez magistralę I2C wysłany zostaje do układu MPL115A2 rozkaz inicjujący pomiar bieżącego ciśnienia i temperatury. Efektem pomiaru są dwie 10-bitowe wartości.
W następnym kroku oprogramowanie odczytuje z wewnętrznych rejestrów MPL115A2 skonwertowane 10-bitowe wartości ciśnienia i temperatury oraz dodatkowe rejestry, w których umieszczone jest 96 bitów korekcyjnych. Po zakończeniu odczytu z kolejnych 16 rejestrów MPL115A2 następuje przeliczenie odczytanych danych na wartość rzeczywistego ciśnienia w kilopaskalach, korzystając z opublikowanego przez producenta układu wzoru:
Pcomp = a0 + (b1 + c11*Padc + c12*Tadc) * Padc + (b2 + c22*Tadc) * Tadc
Pod poszczególne składniki wzoru podstawiane są odczytane z układu wartości ciśnienia, temperatury i wyrażeń korekcyjnych. W oprogramowaniu demonstracyjnym wyliczeniem rzeczywistej wartości ciśnienia zajmuje się procedura int32_t Konwersja_Danych_Na_Wartosc_Cisnienia(char *p_bufor_odczytu).
Parametrem wejściowym jest wskaźnik do 16-bajtowej tablicy w której znajdują się dane odczytane z rejestrów MPL115A2 (od adresu 0x00 do 0x0F). Procedura zwraca wartość typu float będącą wartością ciśnienia w kilopaskalach. Poniżej listing wspomnianej procedury:
//procedura konwersji danych odczytanych z MPL115A2 na wartość ciśnienia w kPa int32_t Konwersja_Danych_Na_Wartosc_Cisnienia(char *p_bufor_odczytu) { uint16_t uiPadc, uiTadc, u16_tmp; int16_t sia0, sib1, sib2, sic12, sic11, sic22; int32_t lt1, lt2, lt3, si_c11x1, si_a11, si_c12x2, si_a1, si_c22x2, si_a2, si_a1x1, si_y1, si_a2x2; int32_t siPcomp; float decPcomp; //normalizacja surowych danych ciśnienia uiPadc =*(p_bufor_odczytu+0); uiPadc =uiPadc <<8; uiPadc =uiPadc + *(p_bufor_odczytu+1); uiPadc =uiPadc >>6; //normalizacja surowych danych temperatury uiTadc =*(p_bufor_odczytu+2); uiTadc =uiTadc <<8; uiTadc =uiTadc + *(p_bufor_odczytu+3); uiTadc =uiTadc >>6; //formowanie 16 bitowych wartości danych kompensujących //coeff a0 u16_tmp =*(p_bufor_odczytu+4); u16_tmp =u16_tmp <<8; u16_tmp =u16_tmp + *(p_bufor_odczytu+5); sia0=u16_tmp; //coeff b1 u16_tmp =*(p_bufor_odczytu+6); u16_tmp =u16_tmp <<8; u16_tmp =u16_tmp + *(p_bufor_odczytu+7); sib1=u16_tmp; //coeff b2 u16_tmp =*(p_bufor_odczytu+8); u16_tmp =u16_tmp <<8; u16_tmp =u16_tmp + *(p_bufor_odczytu+9); sib2=u16_tmp; //coeff c12 u16_tmp =*(p_bufor_odczytu+10); u16_tmp =u16_tmp <<8; u16_tmp =u16_tmp + *(p_bufor_odczytu+11); sic12 =u16_tmp; //coeff c11 u16_tmp =*(p_bufor_odczytu+12); u16_tmp =u16_tmp <<8; u16_tmp =u16_tmp + *(p_bufor_odczytu+13); sic11=u16_tmp; //coeff c22 u16_tmp =*(p_bufor_odczytu+14); u16_tmp =u16_tmp <<8; u16_tmp =u16_tmp + *(p_bufor_odczytu+15); sic22=u16_tmp; //obliczanie skompensowanej wartości ciśnienia zgodnie z formułą: // Pcomp = a0 + (b1 + c11*Padc + c12*Tadc) * Padc + (b2 + c22*Tadc) * Tadc //krok 1: c11x1= c11 * Padc lt1 = sic11; lt2 = uiPadc; lt3 = lt1 * lt2; si_c11x1 = lt3; //krok 2: a11= b1 + c11x1 lt1 = sib1; lt1 = lt1<<14; lt2 = si_c11x1; lt3 = lt1 + lt2; si_a11 = lt3>>14; //krok 3: c12x2= c12 * Tadc lt1 = sic12; lt2 = uiTadc; lt3 = lt1 * lt2; si_c12x2 = lt3; //krok 4: a1= a11 + c12x2 lt1 = si_a11; lt1 = lt1<<11; lt2 = si_c12x2; lt3 = lt1 + lt2; si_a1 =lt3>>11; //krok 5: c22x2= c22 * Tadc lt1 = sic22; lt2 = uiTadc; lt3 = lt1 * lt2; si_c22x2 = lt3; //krok 6: a2= b2 + c22x2 lt1 = sib2; lt1 = lt1<<15; lt2 = si_c22x2>>1; lt3 = lt1+lt2; si_a2 = lt3>>16; //krok 7: a1x1= a1 * Padc lt1 = si_a1; lt2 = uiPadc; lt3 = lt1 * lt2; si_a1x1 = lt3; //krok 8: y1= a0 + a1x1 lt1 = sia0; lt1 = lt1<<10; lt2 = si_a1x1; lt3 = lt1 + lt2; si_y1 = lt3>>10; //krok 9: a2x2= a2 *Tadc lt1 = si_a2; lt2 = uiTadc; lt3 = lt1 * lt2; si_a2x2 = lt3; //krok 10: pComp = y1 +a2x2 lt1 = si_y1; lt1 = lt1<<10; lt2 = si_a2x2; lt3 = lt1 + lt2; //stałoprzecinkowy rezultat obliczeń siPcomp = lt3>>13; siPcomp =siPcomp & 0xFFFF; //ciśnienie dl zakresu 50 to 115kPa decPcomp = ((65.0/1023.0)*siPcomp)+50; return decPcomp; }
Otrzymana wartość steruje świeceniem diod LED. Dla wartości mniejszych lub równych 100kPa świeci się dioda D0. Przy odczycie ciśnienia o większej wartości zapalają się kolejne diody, sygnalizując zmianę ciśnienia 1 kPa/LED.
Przy opracowaniu procedury korzystano z noty aplikacyjnej AN3785 Rev.5 opublikowanej przez Freescale Semiconductors autorstwa Johna Younga.
Ryszard Szymaniak, Aries RS