2014年7月1日 星期二

BMP180 模組使用提示 - 單晶片接線與程式測試

網頁最後修改時間:2016/08/03

網頁中所使用的零件可至露天賣場訂購:
I2C 電壓轉換電路請參照下面網頁的說明
BMP180 的晶片使用說明與溫度、氣壓和海拔高度的計算,請參考下面網頁中的說明
    單晶片的配置是最小可動作的線路,接線電路圖可在上述零件購買之後所提供的資料連結的雲端硬碟資料夾 ( schematics\8051_燒錄器.pdf  )中找到,照著電路圖接就可以了。

    如果沒有購買賣場的 BMP180 數位氣壓感測器模組,在沒有賣場提供的程式碼之下,這網頁中的內容就對你幫助不大。

    AT89S52 + I2C 電壓準位轉換電路 + BMP180 數位氣壓感測模組 + {5V}整合型 1602 LCD @ I2C Mode

    這篇網頁主要是說明如何 BMP180 數位氣壓感測模組與 AT89S52 的接線,並且使用 Bit-Banging 的方式模擬 I2C 通訊,讀取與控制 BMP180 與 整合型 1602 LCD,接線與程式測試的結果就如上圖所示。


    電路接線圖:

    因為主控制器與 BMP180 數位氣壓感測模組通訊接腳是不同電壓,因此在單晶片電路上多了I2C 電壓準位轉換電路,可以讓單晶片 @5V 與 BMP180 @3V3 兩者進行 I2C 通訊 ,更可以讓單片機使用 3V3 與 5V 的整合型 1602 LCD。

    注意到!使用 I2C 電壓準位轉換電路,3V3 電源的輸入可以直接使用 BMP180 數位氣壓感測模組的 3V3 輸出接腳,但是因為轉換輸出的電流不大,不能直接用來驅動 { 3V3 } 整合型 1602 LCD,所以建議使用 { 5V } 整合型 1602 LCD 就不需要在另外準備 3V3 的電源。

    BMP180 - AT89S52 電路接線圖
    感謝網友 Tad Chu 的提醒,修正 Q1 和 Q2 的接腳錯位問題
    在電路圖中,I2C 電壓穩位轉換電路左右兩邊各標示 ASDA、ASCL 和 BSDA、BSCL,分別接 5V 與 3V3 系統。資料使用整合型 1602 LCD 顯示,因為電路中有電壓轉換電路,因此提供 { 5V } 與 { 3V3 } 兩種版本的接線在左上兩個框框中。由於計算溫度、大氣壓力與海拔高度使用到較多的運算,因此單純使用 AT89S51 記憶體會不夠用 ( 除非捨棄一些計算 ),建議使用 AT89S52 ( 256 RAM, 8K Flash Memory ) 或其他較大記憶體空間的單晶片。


    程式測試:

    進入到零件的雲端硬碟,在 codes/AT89S52/KeilC 目錄下就會看到所有的程式。其中,display_lcd+bmp180.cmain 函式所在的檔案,display_lcd+bmp180.hex 是其編譯好的燒錄檔;bmp180.* 是 BMP180 數位氣壓感測器模組的溫度、大氣壓力、海拔高度還有用到的函式的標頭檔以及實作原始碼;I2C.* 就是 bit-banging 的 I2C 的標頭檔與實作原始碼;mydelay.* 顧名思義,是程式中使用到的延遲程式宣告與實作原始碼。


    * 程式基本參數修改
    在程式中,BMP180 與 LCD 都是使用 I2C 通訊,預設是使用 P1.6 ( SCL)P1.7 ( SDA ) 兩支接腳。若要使用不同接腳,就修改 I2C.c 檔案 line 5 與 line6

    I2C.c
    5 sbit SCL = P1^7;
    6 sbit SDA = P1^6;
    

    而兩個裝置的 I2C 位址設定在 display_lcd+bmp180.c 的 line 19 和 line 20,若裝置沒有做什麼變動,就維持原樣就好。

    dispaly_lcd+bmp180.c
    19 #define IIC_LCD_ADDR 0x78
    20 #define IIC_BMP180_ADDR 0xEE
    

    最後一個重要參數,就是海平面壓力的設定,預設是設定為 1013.25 hPa,但這個值並非固定值且會影響到海拔高度的計算,所以若是需要修正,請修改 bmp180.c line 12 中的定義。

    bmp180.c
    12 #define SEALEVEL_PRESSUREHPA   1013.25     // 1013.25 hPa
    

    一定上面的參數設置完畢,就可以重新編譯專案檔,產生新的燒錄檔 display_lcd+bmp180.hex


    * bmp180.c 使用說明
    進入到 main() 中,一開始就是 LCD 與 BMP180 的初始化。BMP180 初始化需要兩個參數,第一個是其 I2C 位址,第二個是 oversampling_setting ( oss )。

    dispaly_lcd+bmp180.c
    79  // BMP180 初始化
    80  /*-------------------------------
    81   ULTRA_LOW_POWER         = 0
    82   STANDARD                = 1
    83   HIGH_RESOLUTION         = 2
    84   ULTRA_HIGH_RESOLUTION   = 3 
    85  --------------------------------*/
    86  BMP180_init( IIC_BMP180_ADDR, 0 );
    

    BMP180 可以讓外界呼叫的函式只有三個,除了 BMP180_init() 之外,BMP180_alive() 是用來確認 I2C 通訊的,可用可不用。而 BMP180_getPTA() 就是在初始化之後,會被主程式重複呼叫來顯示溫、大氣壓力與高度的函式

    bmp180.h
    27 void BMP180_init( unsigned char i2cadddr,  bmp_mode_t bmpmode );
    28 
    29 bit  BMP180_alive();
    30 
    31 void BMP180_getPTA( float pta[3] );
    

    繼續回到主程式 main()。BMP180 初始化之後先確認主控制器與 BMP180 之間的通訊,成功或失敗都會顯示在 LCD 上面 2 秒鐘 ( line 87 ... line 94 )。

    一旦通訊確認 OK 之後,就可以一直重複的讀取經過計算之後所得到的現處環境的溫度、大氣壓力和海拔高度( line 99 ),這些資料都會經過重新組合顯示在 LCD 螢幕上(  line101... line 112 ),每一秒鐘更新一次數據。

    dispaly_lcd+bmp180.c
     87  if( BMP180_alive() )
     88   displayCharAtLCD( 1, 1, "BMP180 Connected", 16);
     89  else 
     90  {
     91   displayCharAtLCD( 1, 1, "XXXXX", 5 );
     92   return;
     92  } 
     93  
     94  delay(2000);
     95  
     96  for( ;; ) 
     97  { 
     98   // BMP180, digital pressure sensor
     99   BMP180_getPTA( pta );
    100   
    101   // 顯示溫度
    102   sprintf( chrbuf, "T:%2.1f%cC", pta[0], 0xdf );
    103   displayCharAtLCD( 2, 1, chrbuf, 8 );
    104   
    106   // 顯示壓力
    107   sprintf( chrbuf, "P:%4.2f hPa   ", pta[1] );
    108   displayCharAtLCD( 1, 1, chrbuf, 16 );
    109   
    110   // 使用溫度做補償,再利用測得的壓力值計算出距離水平面的高度
    111   sprintf( chrbuf, "A:%2.2fM", pta[2] );
    112   displayCharAtLCD( 2, 9, chrbuf, 8 );
    113   
    114   delay(1000); // 0.991015 sec, @ AT89S52, 12MHz
    115  }
    116 } // end of main()
    

    基本的介紹之後,進入到整個程式的主軸 bmp180.c ( 這程式的流程,請至 "如何使用 Bosch BMP180 數位氣壓感測器模組計算溫度、大氣壓力與海拔高度 ?" 了解 ),程式碼的說明請參照括號中的網頁。

    每一個 BMP180 晶片裡面都存有不同的校正係數 ( Calibration Coefficients ),用來計算出溫度與大氣壓力 ( 海拔高度是利用公式另外算出 ),但因為計算的過程非常攏長,除非已經有原始碼,不然重新撰寫或改寫這部分計算的程式 ( 尤其是在程式移值的過程 ) 時,因為資料型態宣告或是資料型態轉換錯誤的關係造成計算結果產生錯誤,除錯過程會非常麻煩且耗時間。因此,在 BMP180 資料手冊上 Page 18 使用了固定的校正係數、原生溫度數據和原生壓力數據,將一系列的計算過程展示出來,利用這些固定的數據,可以幫助程式設計者撰寫這部分計算的程式碼以及驗證用,在 bmp180.c 程式碼中,提供這一個參數 ( BMP_USE_DATASHEET_VALUES  ) 作為切換是否使用資料手冊中的數據做為計算或是由 BMP180 晶片中讀取這些數據,預設是 0 ( 由 BMP180 晶片讀取;1 : 使用資料手冊上的數據 )

    bmp180.c
    10 #define BMP_USE_DATASHEET_VALUES    0
    

    為了確認每一個計算式都是正確的,在 bmp180.c 裡面避掉了一些除錯的程式碼,因此若是要輸出每一個算式的計算結果,首先我們必須決定是要使用資料手冊上面的數據還是要讀取 BMP180 裡的數據 ( BMP_USE_DATASHEET = 1 或 = 0 ),然後去除掉框住 line 67 ... line 85 之間的程式碼 ( 在 line 66 與 line 86 前面加入兩個 // 斜線 ),這樣就可以顯示計算過程中的數據在 LCD 螢幕中。

    bmp180.c
    65 // 列印參數做測試時使用下面框住的程式碼
    66 /**********************************
    67 idata unsigned char chrbuf[17];
    68 
    69 static void display( int line, int column, const unsigned char *dp, unsigned char len )
    70 {
    71  unsigned char i;
    72  
    73  I2CStart();
    74  
    75  I2CSendByte( 0x78 );
    76  I2CSendByte( 0x80 );
    77  I2CSendByte( 0x80 + ( line - 1 ) * 0x40 + ( column - 1 ) );
    78  I2CSendByte( 0x40 );
    79  for( i = 0; i < len; i++)
    80  {
    81   I2CSendByte( *dp++ );
    82  }
    83  
    84  I2CStop();
    85 }
    86 **********************************/
    

    但 LCD 螢幕顯示的數據數目有限,因此數據必須分段解開再顯示在 LCD 上

    Part 1,
    bmp180.c, BMP180_getPTA():X1, X2, X5, Real Temperature
    222  
    223  /********************************
    224  // 列印 X1, X2, B5 確認
    225  sprintf( chrbuf, "X1:%5ldX2:%5ld", X1, X2 );
    226  display( 1, 1, chrbuf, 16);
    227  sprintf( chrbuf, "B5:%5ld", B5 );
    228  display( 2, 1, chrbuf, 8);
    229  
    230  
    231  // 顯示溫度
    232  sprintf( chrbuf, "T:%2.1f%cC", pta[0], 0xdf );
    233  display( 2, 9, chrbuf, 8 );
    234  
    235  ********************************/
    236     
    

    Part 2,
    bmp180.c, BMP180_getPTA():Real Pressure
    264  
    265  /********************************
    266  
    267  // 顯示壓力
    268  sprintf( chrbuf, "P:%4.2f hPa   ", pta[1] );
    269  display( 1, 1, chrbuf, 16 );
    270  
    271  ********************************/
    272  
    

    Part 3,
    bmp180.c, BMP180_getPTA():Altitude
    295  
    296  /********************************
    297  
    298  // 使用溫度補償,再利用測得的壓力值計算出距離水平面的高度
    299  sprintf( chrbuf, "A:%2.2fM", pta[2] );
    300  display( 2, 9, chrbuf, 8 );
    301  
    302  ********************************/ 
    303 } // end of BMP180_getPTA
    

    依照上面的字串組成與顯示方法,可以自行再增加顯示的部分,但編譯時必須注意輸出訊息,要確認 Program Size 的 data 和 code ( < 8192, @ AT89S52 )大小不要超過晶片的限制,若編譯出現 Memory Space ... 什麼的錯誤訊息,但 data 的大小還未超過 256,將其中一些變數宣告為 idata 可解決這問題 ( 在 display_lcd+bmp180.c 程式碼裡面找一下 idata 作參考 )。


    結論:

    使用單晶片讀取 BMP180 要注意撰寫程式碼值必須注意變數的宣告,若想要使用 AT89S51 來做也是可行的,只不過需要捨棄一些程式碼將程式的大小 ( code ) 壓在 4K 以下,data 不要大於 120;使用 AT89S52,data 大小超過 120 要使用 idata 宣告變數為間接尋址,但不可超過 247
    ,code 要壓在 8K 以下。

    BMP180 的程式不論是在單晶片、Arduino 或是樹莓派的處理方式極盡相同,若是對於程式碼有所問題,可以先去參考為其他控制器所撰寫的程式或先上網找資料,當然也可以發信或是上 google+ 來作討論。

    玩得愉快 !!!


    << BMP180 數位氣壓感測器系列文章 >>
    • 使用 N-Channel MOSFET 做 I2C 電壓準位轉換電路
    • 簡易但是很好用的 3V3 <--> 5V,  I2C 電壓準位 ( Level Shifter ) 轉換電路,這電路會用在 BMP180 與單晶片、Arduino 或是任何 3V3 系統程式測試上。

    • 如何使用 Bosch BMP180 數位氣壓感測器模組計算溫度、大氣壓力與海拔高度 ?
    • 要得到模組顯處環境的溫度、大氣壓力和海拔高度,單純讀取 BMP180 的資料是不夠的,還必須經過一長串的計算過程,讓此篇網頁帶使用者進入 BMP180 的世界,並了解這些數據的運算過程。

    • BMP180 模組使用提示 - Arduino 接線與程式測試
      這篇網頁主要針對兩個賣場提供的 Arduino 做使用說明。主要是說明如何 BMP180 數位氣壓感測模組與 Arduino 的接線與程式測試,使用 Arduino 本身硬體 I2C 做通訊,並且將輸出結果直接輸出到 Serial Port 上,所有計算過程與結果可直接輸出到其 Arduino Monitor 或是 Serial Port 軟體上。

    • BMP180 模組使用提示 - Raspberry Pi 接線與程式測試
    • 這篇網頁主要說明如何使用賣場所提供的樹莓派 ( Raspberry Pi ) BMP180 程式。這程式只包含一個檔案,所有 BMP180 的操作、溫度、大氣壓力、海拔高度,以及反算海平面壓力與大氣壓力都在其中,經由檔案開頭處的參數設定,就可以很方便操控整個程式 !

    2 則留言:

    1. 請問範例程式能分享嗎?

      回覆刪除
      回覆
      1. 如果沒有購買賣場的 BMP180 數位氣壓感測器模組,在沒有賣場提供的程式碼之下,這網頁中的內容就對你幫助不大。

        刪除

    留言屬名為"Unknown"或"不明"的用戶,大多這樣的留言都會直接被刪除掉,不會得到任何回覆!

    發問問題,請描述清楚你(妳)的問題,別人回答前不會想去 "猜" 問題是什麼?

    不知道怎麼發問,請看 [公告] 部落格提問須知 - 如何問問題 !