仿正點原子驅動BMP280氣壓傳感器實例

文章目錄

前言

一、寄存器頭文件定義

二、設備樹文件中添加節點

?三、驅動文件編寫

四、編寫驅動測試文件并編譯測試

總結


前言

本文驅動開發仿照正點原子的iic驅動實現,同時附上bmp280的數據手冊,可訪問下面的鏈接:

BMP280_Bosch(博世)_BMP280中文資料_PDF手冊_價格-立創商城下載數據手冊。


一、寄存器頭文件定義

? ? ? ? 在查看數據手冊時,可發現bmp280器件對各個寄存器,如數據,校準,采樣,濾波等等寄存器進行定義,如下代碼所示:

#ifndef BMP280_H
#define BMP280_H#define BMP280_ADDR    	0x76	/* BMP280器件地址*//* BMP280寄存器 */
#define BMP280_ID_REG          0xD0  /* 芯片ID寄存器,值是0x58 */
#define BMP280_RESET_REG       0xE0  /* 復位寄存器 */
#define BMP280_STATUS_REG      0xF3  /* 狀態寄存器 */
#define BMP280_CTRL_MEAS_REG   0xF4  /* 測量控制寄存器 */
#define BMP280_CONFIG_REG      0xF5  /* 配置寄存器 *//* 數據寄存器 */
#define BMP280_PRESSURE_MSB    0xF7  /* 壓力數據高字節 */
#define BMP280_PRESSURE_LSB    0xF8  /* 壓力數據中字節 */
#define BMP280_PRESSURE_XLSB   0xF9  /* 壓力數據低字節 */
#define BMP280_TEMP_MSB        0xFA  /* 溫度數據高字節 */
#define BMP280_TEMP_LSB        0xFB  /* 溫度數據中字節 */
#define BMP280_TEMP_XLSB       0xFC  /* 溫度數據低字節 *//* 校準參數寄存器 - 存儲補償計算需要的出廠校準數據 */
#define BMP280_DIG_T1_LSB_REG  0x88
#define BMP280_DIG_T1_MSB_REG  0x89
#define BMP280_DIG_T2_LSB_REG  0x8A
#define BMP280_DIG_T2_MSB_REG  0x8B
#define BMP280_DIG_T3_LSB_REG  0x8C
#define BMP280_DIG_T3_MSB_REG  0x8D
#define BMP280_DIG_P1_LSB_REG  0x8E
#define BMP280_DIG_P1_MSB_REG  0x8F
#define BMP280_DIG_P2_LSB_REG  0x90
#define BMP280_DIG_P2_MSB_REG  0x91
#define BMP280_DIG_P3_LSB_REG  0x92
#define BMP280_DIG_P3_MSB_REG  0x93
#define BMP280_DIG_P4_LSB_REG  0x94
#define BMP280_DIG_P4_MSB_REG  0x95
#define BMP280_DIG_P5_LSB_REG  0x96
#define BMP280_DIG_P5_MSB_REG  0x97
#define BMP280_DIG_P6_LSB_REG  0x98
#define BMP280_DIG_P6_MSB_REG  0x99
#define BMP280_DIG_P7_LSB_REG  0x9A
#define BMP280_DIG_P7_MSB_REG  0x9B
#define BMP280_DIG_P8_LSB_REG  0x9C
#define BMP280_DIG_P8_MSB_REG  0x9D
#define BMP280_DIG_P9_LSB_REG  0x9E
#define BMP280_DIG_P9_MSB_REG  0x9F/* 復位值 */
#define BMP280_RESET_VALUE     0xB6/* 工作模式 */
#define BMP280_SLEEP_MODE      0x00
#define BMP280_FORCED_MODE     0x01
#define BMP280_NORMAL_MODE     0x03/* 過采樣設置 */
#define BMP280_OSRS_T_SKIP     0x00 /* 溫度測量跳過 */
#define BMP280_OSRS_T_X1       0x20 /* 溫度測量1倍過采樣 */
#define BMP280_OSRS_T_X2       0x40
#define BMP280_OSRS_T_X4       0x60
#define BMP280_OSRS_T_X8       0x80
#define BMP280_OSRS_T_X16      0xA0#define BMP280_OSRS_P_SKIP     0x00 /* 壓力測量跳過 */
#define BMP280_OSRS_P_X1       0x04 /* 壓力測量1倍過采樣 */
#define BMP280_OSRS_P_X2       0x08
#define BMP280_OSRS_P_X4       0x0C
#define BMP280_OSRS_P_X8       0x10
#define BMP280_OSRS_P_X16      0x14/* 濾波器設置 */
#define BMP280_FILTER_OFF      0x00
#define BMP280_FILTER_COEF_2   0x04
#define BMP280_FILTER_COEF_4   0x08
#define BMP280_FILTER_COEF_8   0x0C
#define BMP280_FILTER_COEF_16  0x10/* 待機時間設置 */
#define BMP280_STANDBY_0_5_MS  0x00
#define BMP280_STANDBY_62_5_MS 0x20
#define BMP280_STANDBY_125_MS  0x40
#define BMP280_STANDBY_250_MS  0x60
#define BMP280_STANDBY_500_MS  0x80
#define BMP280_STANDBY_1000_MS 0xA0
#define BMP280_STANDBY_2000_MS 0xC0
#define BMP280_STANDBY_4000_MS 0xE0/* 結構體定義 */
struct bmp280_calib_param {uint16_t dig_T1;int16_t  dig_T2;int16_t  dig_T3;uint16_t dig_P1;int16_t  dig_P2;int16_t  dig_P3;int16_t  dig_P4;int16_t  dig_P5;int16_t  dig_P6;int16_t  dig_P7;int16_t  dig_P8;int16_t  dig_P9;
};#endif 

二、設備樹文件中添加節點

? 在設備樹文件中的i2c1節點中添加子節點,如下:,其中bmp280的器件地址即reg定義為0x76,使用的引腳定義是SCL使用:MX6UL_PAD_UART4_TX_DATA__I2C1_SCL? SDA使用:MX6UL_PAD_UART4_RX_DATA__I2C1_SDA及完成設備樹的節點定義,加載到內核:

?查看節點:

?三、驅動文件編寫

(1)首先就是字符設備的結構體定義:添加了溫度和氣壓數據。

struct bmp280_dev {dev_t devid;               // 設備號struct cdev cdev;          // 字符設備結構體struct class *class;       // 類struct device *device;     // 設備struct device_node *nd;    // 設備樹節點int major;                 // 主設備號void *private_data;        // I2C客戶端指針int temperature;           // 溫度值(單位:0.01℃)int pressure;              // 氣壓值(單位:Pa)struct bmp280_calib_param calib_param; // 校準參數int32_t t_fine;            // 溫度補償中間值
};

?(2)接著完成對讀寄存器函數的編寫:,使用i2c_msg來加載數據,發送的數據是bmp280的器件地址以及加載要寫入的數據,并調用i2c_transfer來完成數據發送

?(3)寫寄存器:發送的數據位器件地址0x76+寄存器地址+數據

?(4)讀取寄存器的校準參數:從0x88開始兩個字節的讀,

(5)計算實際的溫度和氣壓值,參考數據手冊給出的計算公式和實現例程代碼,有興趣的話可以仔細看看手冊:

?仿照實現的計算函數:
?

static int32_t bmp280_compensate_temperature(struct bmp280_dev *dev, int32_t adc_T)
{int32_t var1, var2, temperature;var1 = ((((adc_T >> 3) - ((int32_t)dev->calib_param.dig_T1 << 1))) * ((int32_t)dev->calib_param.dig_T2)) >> 11;var2 = (((((adc_T >> 4) - ((int32_t)dev->calib_param.dig_T1)) * ((adc_T >> 4) - ((int32_t)dev->calib_param.dig_T1))) >> 12) * ((int32_t)dev->calib_param.dig_T3)) >> 14;dev->t_fine = var1 + var2;temperature = (dev->t_fine * 5 + 128) >> 8;return temperature;
}/** @description  : 計算實際氣壓值,避免使用64位除法* @param - dev  : bmp280設備* @param - adc_P: 原始氣壓ADC值* @return       : 實際氣壓值(Pa)*/
static uint32_t bmp280_compensate_pressure(struct bmp280_dev *dev, int32_t adc_P)
{int32_t var1, var2;uint32_t p;var1 = (((int32_t)dev->t_fine) >> 1) - (int32_t)64000;var2 = (((var1 >> 2) * (var1 >> 2)) >> 11) * ((int32_t)dev->calib_param.dig_P6);var2 = var2 + ((var1 * ((int32_t)dev->calib_param.dig_P5)) << 1);var2 = (var2 >> 2) + (((int32_t)dev->calib_param.dig_P4) << 16);var1 = (((dev->calib_param.dig_P3 * (((var1 >> 2) * (var1 >> 2)) >> 13)) >> 3) + ((((int32_t)dev->calib_param.dig_P2) * var1) >> 1)) >> 18;var1 = ((((32768 + var1)) * ((int32_t)dev->calib_param.dig_P1)) >> 15);if (var1 == 0)return 0; // 避免除零錯誤p = (((uint32_t)(((int32_t)1048576) - adc_P) - (var2 >> 12))) * 3125;if (p < 0x80000000)p = (p << 1) / ((uint32_t)var1);elsep = (p / (uint32_t)var1) * 2;var1 = (((int32_t)dev->calib_param.dig_P9) * ((int32_t)(((p >> 3) * (p >> 3)) >> 13))) >> 12;var2 = (((int32_t)(p >> 2)) * ((int32_t)dev->calib_param.dig_P8)) >> 13;p = (uint32_t)((int32_t)p + ((var1 + var2 + dev->calib_param.dig_P7) >> 4));return p;
}

(6) 實現讀取數據函數定義:從數據寄存器0xf7讀到0xfc

(7)剩下就是完成對bmp280初始化定義,設備文件的操作函數定義,如下所示即為,設備初始化代碼:,主要完成對設備的喚醒,校準以及采樣配置:

static int bmp280_init_sensor(struct bmp280_dev *dev)
{uint8_t chip_id;/* 1. 讀取芯片ID,確認設備存在 */chip_id = bmp280_read_reg(dev, BMP280_ID_REG);printk("BMP280 Chip ID: 0x%02X\n", chip_id);if (chip_id != 0x58) {//0x76地址存儲的是0x58printk("BMP280 Chip ID not matching, expected 0x58, got 0x%02X\n", chip_id);return -ENODEV;}/* 2. 軟復位 */bmp280_write_reg(dev, BMP280_RESET_REG, BMP280_RESET_VALUE);mdelay(10); // 等待復位完成/* 3. 讀取校準參數 */bmp280_read_calibration_data(dev);/* 4. 配置傳感器 * - 設置過采樣: 溫度16x,壓力16x* - 設置工作模式: 正常模式*/bmp280_write_reg(dev, BMP280_CONFIG_REG, BMP280_FILTER_COEF_16 | BMP280_STANDBY_500_MS);bmp280_write_reg(dev, BMP280_CTRL_MEAS_REG, BMP280_OSRS_T_X16 | BMP280_OSRS_P_X16 | BMP280_NORMAL_MODE);mdelay(100); // 等待配置生效return 0;
}

?如上即為主要關鍵驅動代碼的定義。

四、編寫驅動測試文件并編譯測試

類似正點原子的驅動測試文件:

打開設備并讀取到數據時,間隔2s打印一次數據

?編譯加載驅動文件和驅動測試文件:

測試結果:

?

能夠正確獲取數據并進行打印,完成驅動!!!


總結

通過對IIC驅動的學習測試以及完成對具體iic設備的驅動來獲取數據,對嵌入式linux的驅動了解更加深刻了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82879.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82879.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82879.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

論壇系統(中-1)

軟件開發 編寫公共代碼 定義狀態碼 對執?業務處理邏輯過程中可能出現的成功與失敗狀態做針對性描述(根據需求分析階段可以遇見的問題提前做出定義)&#xff0c;?枚舉定義狀態碼&#xff0c;先定義?部分&#xff0c;業務中遇到新的問題再添加 定義狀態碼如下 狀態碼類型描…

E+H流量計通過Profibus DP主站轉Modbus TCP網關與上位機輕松通訊

EH流量計通過Profibus DP主站轉Modbus TCP網關與上位機輕松通訊 在現代工業自動化的廣闊舞臺上&#xff0c;Profibus DP與Modbus TCP這兩種通信協議各領風騷&#xff0c;它們在不同的應用場景中發揮著舉足輕重的作用。但工業生產的復雜性往往要求不同設備、系統之間能夠順暢溝…

服務器中存儲空間不足該怎么辦?

服務器作為存儲數據信息的重要網絡設備&#xff0c;隨著企業業務的不斷拓展&#xff0c;所需要存儲的數據信息也在不斷增加&#xff0c;最終會導致服務器中存儲空間不足&#xff0c;這不僅會影響到服務器系統性能&#xff0c;還會造成業務無法正常執行&#xff0c;那么&#xf…

C++23 views::chunk_by (P2443R1) 詳解

文章目錄 引言C23 范圍庫概述范圍視圖&#xff08;Range Views&#xff09;范圍算法&#xff08;Range Algorithms&#xff09;范圍適配器&#xff08;Range Adapters&#xff09; std::views::chunk_by 介紹基本概念特性使用場景 示例代碼簡單示例自定義謂詞示例 總結 引言 在…

零碳園區能源系統-多能互補體系

構建以可再生能源為核心的零碳園區能源系統&#xff0c;需整合光儲直柔、光伏發電、微電網、氫能與儲能技術&#xff0c;通過多能協同與智能調控實現能源生產、存儲、消費全鏈條優化。以下是系統性實施方案&#xff1a; 一、系統架構設計 1. 多能互補體系 &#xff08;圖示&a…

elastic search學習

首先在自己電腦上安裝elastic search。安裝成功后&#xff0c;查看ES是否啟動成功。 安裝過程參考&#xff1a;ElasticSearch入門1: mac 安裝 - 霜井 - 博客園 安裝完成后&#xff0c;直接執行bin目錄中的elastic search命令后&#xff0c;就可以啟動成功&#xff01; 在網頁…

mysql8常用sql語句

查詢結果帶行號 -- 表名為 mi_user&#xff0c; 假設包含列 id &#xff0c;address SELECT ROW_NUMBER() OVER (ORDER BY id) AS row_num, t.id, t.address FROM mi_user t ; SELECT ROW_NUMBER() OVER ( ) AS row_num, t.id, t.address FROM mi_user t ; 更新某列數…

Memcached 服務搭建和集成使用的詳細步驟示例

以下是 Memcached 服務搭建和集成使用的詳細步驟示例&#xff1a; 一、搭建 Memcached 服務 安裝 Memcached Linux 系統 yum 安裝&#xff1a;執行命令 yum install -y memcached memcached-devel。源碼安裝 下載源碼&#xff1a;wget http://www.memcached.org/files/memcach…

2. 盒模型/布局模塊 - 響應式產品展示頁_案例:電商產品網格布局

2. 盒模型/布局模塊 - 響應式產品展示頁 案例&#xff1a;電商產品網格布局 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><style type"text/css">:root {--primary-color…

Go基于plugin的熱更新初體驗

背景 對于一個部署在生產環境的項目來說&#xff0c;我們希望當代碼出現bug的時候&#xff0c;可以不用重啟進程而達到動態修改代碼的目的—— 這就是代碼熱部署&#xff01; 使用java做游戲服務器&#xff0c;最大的好處是&#xff0c;當代碼出現bug&#xff0c;可以直接熱…

【RabbitMQ】工作隊列和發布/訂閱模式的具體實現

文章目錄 建立連接工作隊列模式實現創建隊列和交換機生產者代碼消費者代碼運行程序啟動消費者啟動生產者 發布/訂閱模式實現創建隊列和交換機生產者代碼創建交換機聲明兩個隊列綁定隊列和交換機發送消息完整代碼 消費者代碼完整代碼 運行程序啟動生產者啟動消費者 建立連接 我…

Codeforces Round 998 (Div. 3)

A. Fibonacciness 題目大意 給你四個數字abde&#xff0c;讓你找到一個中間值c&#xff0c;問 a b c a b c abc &#xff0c; b c d b c d bcd &#xff0c; c d e c d e cde 最多能有幾個式子成立 解題思路 顯然最多就六種情況&#xff0c;暴力枚舉即可 代…

火山引擎發展初始

火山引擎是字節跳動旗下的云計算服務品牌&#xff0c;其云服務業務的啟動和正式商業化時間線如下&#xff1a; 1. **初期探索&#xff08;2020年之前&#xff09;** 字節跳動在早期為支持自身業務&#xff08;如抖音、今日頭條等&#xff09;構建了強大的基礎設施和技術中…

【認知思維】光環效應:第一印象的持久力量

什么是光環效應 光環效應&#xff08;Halo Effect&#xff09;是指人們傾向于讓對某人或某物的一個顯著特質的印象影響對其他特質的評價的認知偏差。簡單來說&#xff0c;當我們對某人的一個特質&#xff08;如外表、智力或某項技能&#xff09;形成積極印象時&#xff0c;我們…

Java Solon v3.3.0 發布(國產優秀應用開發基座)

Solon 框架&#xff01; Solon 是新一代&#xff0c;Java 企業級應用開發框架。從零開始構建&#xff08;No Java-EE&#xff09;&#xff0c;有靈活的接口規范與開放生態。采用商用友好的 Apache 2.0 開源協議&#xff0c;是“杭州無耳科技有限公司”開源的根級項目&#xff…

力扣-104.二叉樹的最大深度

題目描述 給定一個二叉樹 root &#xff0c;返回其最大深度。 二叉樹的 最大深度 是指從根節點到最遠葉子節點的最長路徑上的節點數。 class Solution { public:int maxDepth(TreeNode* root) {if(!root){return 0;}return max(maxDepth(root->left), maxDepth(root->…

單反和無反(私人筆記)

① 單反相機&#xff1a; 定義&#xff1a; 單反相機&#xff08;Single-Lens Reflex&#xff0c;SLR&#xff09;是一種帶有反光鏡結構的數碼相機。光線通過鏡頭進入后&#xff0c;先被反光鏡反射到五棱鏡/五面鏡&#xff0c;再通過取景器進入人眼。按下快門時&#xff0c;反…

超詳細講解C語言轉義字符\a \b \r \t \? \n等等

轉義字符 C語言有一組字符很特殊&#xff0c;叫做轉義字符&#xff0c;顧名思義&#xff0c;改變原來的意思的字符。 1 \? ??)是一個三字母詞&#xff0c;在以前的編譯器它會被編譯為] (??會被編譯為[ 因此在以前輸入(are you ok ??)就會被編譯為are you ok ] 解決這個…

Java Spring MVC -01

SpringMVC 是一種基于 的實現 MVC 設計模式的請求驅動類型的輕量級 Web 框架&#xff0c;屬于 Spring FrameWork 的后續產品&#xff0c;已經融合在 Spring Web Flow 中。 First:SpringMVC-01-SpringMVC 概述 SpringMVC 是 Spring 框架的一個模塊&#xff0c;用于構建 Web 應…

Spring MessageSource 詳解:如何在國際化消息中傳遞參數

在開發多語言應用程序時,Spring 的 MessageSource 是處理國際化(i18n)文本的核心組件。它允許我們根據用戶的 Locale (區域設置) 顯示不同的消息。然而,很多時候我們的消息并不是靜態的,而是需要包含動態數據,比如用戶名、數量、文件名等。這時,我們就需要在獲取國際化消…