概述
本文介紹了一種加速嵌入式系統設計原型的方法,重點在於將與硬體無關的驅動程式與感測器結合使用,從而簡化元件選擇。文章中提到的IMU感測器(慣性測量單元)及其應用,並提供了相關的技術細節。隨後的文章”利用與硬體無關的方法簡化嵌入式系統設計:驅動程序實現“將進一步詳細說明執行情況。
介紹
使用與硬體無關的驅動程式,設計人員可以自由選擇微控制器或處理器來管理感測器,無需依賴特定的硬體。這種方法的優勢在於可以在基本軟體層之上添加額外的軟體層,進一步簡化感測器的集成。文章以(IMU)感測器為例,並使用C程式設計語言進行配置。
元件選擇
選擇的IMU感測器為ADIS16500,適合用於運動檢測,並能提供精確的多軸慣性感測。主要應用包括人形機器人、導航、無人機、無人駕駛、智慧農業、智慧工廠等。
圖 1.ADIS16500評估板。
主要應用有:
-
無人機、無人船
-
導航、穩定和儀錶
-
無人駕駛和自動駕駛汽車
-
智慧農業和工程機械
-
工廠/工業自動化、機器人
-
虛擬/增強現實
-
移動物聯網
該ADIS16500是一種精密、微型微機電系統 (MEMS) IMU,嵌入了三軸陀螺儀、三軸加速度計和溫度感測器。參見圖 2。它針對靈敏度、偏置、對準、線性加速度(陀螺儀偏置)和衝擊點(加速度計位置)進行了工廠校準。這意味著感測器測量在廣泛的條件下都是準確的。
圖 2.ADIS16500框圖。
該介面允許微控制器寫入和讀取使用者控制寄存器,以及讀取輸出數據寄存器,從中獲取加速度計、陀螺儀或溫度感測器數據。因此,管理介面所需的所有軟體和固件都已開發完畢。圖2顯示了數據就緒(DR)引腳。該引腳是一個數位信號,指示何時可以從感測器讀取新數據。DR 引腳可以由微控制器輕鬆管理,因為它可以被視為通過通用輸入/輸出 (GPIO) 埠的輸入。
從硬體角度來看,IMU感測器和微控制器將使用SPI介面連接,SPI介面是一個由nCS、SCLK、DIN和DOUT引腳組成的4線介面。DR 引腳應連接到微控制器的 GPIO 之一。IMU 感測器還需要 3 V 至 3.6 V 之間的電壓電源,因此 3.3 V 就足夠了。
瞭解嵌入式系統的典型軟體結構
瞭解嵌入式系統的通用軟體和韌體結構對於與感測器驅動程式連接至關重要。這將幫助設計人員構建一個靈活且易於集成到任何專案中的軟體模組。此外,驅動程式必須以模組化方式實現,以便設計人員可以依賴現有功能添加更高級別的功能。
嵌入式系統的軟體結構如圖 3 所示。在圖 3 中,層次結構從應用程式層開始,這是編寫應用程式代碼的地方。應用層包括主檔、依賴於感測器的應用程式模組以及依賴於管理處理器配置的週邊設備驅動程式的模組。此外,在應用層中,有與微控制器必須處理的任務相關的所有模組。例如,這包括管理具有中斷或輪詢的任務的所有軟體、狀態機等。該層級別會根據項目類型而有所不同,因此不同的專案在其中實現了不同的代碼。在應用層中,系統的所有感測器都根據其數據表進行初始化和配置。感測器驅動程式提供的所有公共功能都是可調用的。例如,讀取可以輸出資料的寄存器,或寫入將更改設置/校準的寄存器的程式。
圖 3.嵌入式系統的SW/FW結構。
應用層下方是感測器的驅動層,它有兩種類型的介面。在此級別,實現可從應用程式層調用的所有函數。此外,函數的原型插入到驅動程式頭檔 (.h) 中。因此,通過查看感測器驅動程式的頭檔,您可以了解驅動程式的介面,從而瞭解其從更高級別調用的函數。較低級別的層將與特定且依賴於管理感測器的微控制器的外設驅動程序連接。外設驅動程式包括管理微控制器外設(如SPI、I²C、UART、USB、CAN、SPORT等)的所有模組,或管理處理器內部模組(如定時器、記憶體、ADC等)的模組。它們可以稱為低級函數,因為它們與硬體嚴格相關。例如,考慮到不同的微控制器,每個 SPI 驅動器都是不同的。讓我們以ADIS16500為例。介面是 SPI,因此其驅動程式將與微控制器的 SPI 驅動程式包裝。對於不同的感測器和不同的介面,這將是相同的。例如,如果另一個感測器具有 I²C 介面,則類似地,在感測器的初始化過程中將與微控制器的 I²C 驅動程序進行包裝。
感測器的驅動器級別下方是週邊驅動器,每種類型的微控制器都不同。在圖3中,外設驅動器和低電平驅動器之間存在分離。從本質上講,外圍驅動程式通過可用的通信協定提供讀寫功能。由於低級驅動程式將管理信號的物理層,因此對設計人員使用的硬體有很強的依賴性。通常,外設和低級驅動程式層是從微控制器的集成開發環境 (IDE) 通過可視化工具生成的,具體取決於安裝微控制器的評估板。
驅動程序實現
與硬體無關的方法允許在不同的應用程式中使用相同的驅動程式,從而使用不同的微控制器或處理器。此方法取決於驅動程序的實現方式。為了了解驅動程序實現,首先,我們將查看介面,或感測器的頭檔 (adis16500.h),如圖 4 所示。
圖 4.ADIS16500標頭檔 (adis16500.h) 中顯示的巨集。
頭檔包含有用的公共巨集。這包括寄存器的位址、SPI最大速度、默認輸出數據速率(ODR)、位掩碼以及加速度計、陀螺儀和溫度感測器的輸出靈敏度,這些靈敏度與表示數據的位數(16或32)有關。這些巨集如圖 4 所示。僅顯示了幾個寄存器的位址以提供範例。本文引用的代碼可在附錄.
圖 3 中的附錄顯示每個模組可以使用的所有公共變數和公共類型聲明,包括阿迪斯16500.h.在這裡,定義了新類型以更有效地管理數據。舉個例子,ADIS16500_XL_OUT類型定義為包含三個浮點數的結構,每個軸(x、y 和 z)一個。還有一個枚舉,允許以不同的方式配置感測器,使設計人員能夠靈活地選擇最適合其需求的配置。這裡最有趣的部分是使驅動程式與硬體無關的部分。在公共變數部分的開頭(附錄中的圖 3),有三個關鍵的類型定義:指向三個基本函數的指標,或 SPI 傳輸和接收函數以及兩個 SPI 訪問之間產生正確停頓時間所需的延遲函數。這些代碼行還顯示了可以指向的函數的原型。SPI 傳輸函數將指向要傳輸的值的指標作為輸入,並返回可以檢查該值以查看傳輸是否成功。對於 SPI 接收函數也是如此,該函數將指向變數的指標作為輸入,其中將存儲接收中讀取的值。延遲函數將浮點數作為輸入,表示設計人員想要等待的微秒數,並且沒有返回(無效).這樣,設計人員就可以在應用層(例如在主檔中)使用這些特定的原型聲明這三個函數。聲明后,他們可以將這三個函數分配給ADIS16500_INIT私人結構。為了更好地理解最後一步,附錄中的圖 2 提供了一個示例。
SPI 發送器、接收器功能和延遲功能在主檔中聲明為靜態,因此在應用程式級別。它們依賴於週邊驅動程式功能,因此對硬體的依賴性在感測器驅動程式之外。這三個函數被分配給此變數的欄位,這些字位是指向函數的指標。這樣,設計人員可以在不修改感測器驅動程式代碼的情況下包裝感測器和微控制器。如果設計人員更換微控制器,他們只需調整主檔,將三個靜態函數中的低級函數替換為新微控制器的適當函數。這種方法使驅動程式硬體無關,因為設計人員不需要更改感測器的驅動程序代碼。低級函數,例如spiSelect,spi接收,spi取消選擇,chThdSleep微秒等,通常已經從微控制器的 IDE 中獲得。在該特定情況下,使用的微控制器評估板是SDP-K1型,它嵌入了一個STM32F469NIH6 Cortex-M4® 微控制器。IDE 確實是ChibiOS,這是一個免費的 Arm® 開發環境。
圖 4 在附錄顯示了應用程式級別的可調用函數的原型。這些原型位於感測器驅動程式 (adis16500.h),以及附錄圖 2 和圖 3 中討論的所有其他軟體和固件。首先,是初始化函數(adis16500_init),它採用指向ADIS16500_INIT結構作為輸入,並返回一個狀態代碼,指示初始化是否成功。初始化函數的實現是在源檔 (阿迪斯16500.c) 的感測器驅動器。附錄中的圖 5 顯示了adis16500_init功能。首先,一種名為ADIS16500_PRIV定義,其中至少包含ADIS16500_INIT結構,然後是一個名為_adis16500_priv聲明了該類型的。在初始化函數中,所有欄位ADIS16500_INIT應用層傳遞的結構將被分配給私有變數的欄位_adis16500_priv.這意味著對感測器驅動程式的任何後續調用都將使用應用程式層傳入的 SPI 寫入和讀取函數以及處理器延遲函數。這是一個關鍵點,因為它使感測器驅動程式與硬體無關。如果設計人員想要更改微控制器,他們只需要更改他們傳遞給adis16500_init功能。它們不需要修改感測器驅動程序代碼本身。在初始化函數的開頭,初始化欄位_adis16500_priv變數設置為 false,因為初始化過程尚未完成。在函數結束時,返回之前,它將被設置為 true。每次設計器調用另一個公共函數(附錄中的圖 4)時,都會執行以下檢查:如果_adis16500_priv.初始化為 true,則可以繼續,如果為 false,它將立即返回一個名為ADIS16500_RET_VAL__ERROR.這是為了防止使用者在未先初始化感測器驅動程序的情況下調用函數。繼續初始化函數討論,執行以下步驟:
-
通過讀取ADIS16500_REG_PROD_ID寄存器來檢查先驗已知的產品ID。
-
通過將ADIS16500_REG_MSC_CTRL寄存器寫入相應的位字段,使用從應用層傳遞的值(main.c)來設置數據就緒(DR)引腳極性。
-
通過將ADIS16500_REG_MSC_CTRL寄存器寫入相應的位字段來設置同步模式,並將值從應用層(main.c)傳遞。
-
通過寫入ADIS16500_REG_DEC_RATE寄存器來設置抽取率,使用從應用層(main.c)傳遞的值。
初始化函數依賴於讀寫寄存器函數(圖 6 中的附錄).這就是為什麼上述四個例程是在分配給_adis16500_priv變數。否則,當調用讀或寫寄存器函數時,它們將不知道要使用哪個SPI發送器、接收器和處理器延遲函數。
參考圖 4 中的附錄,在初始化函數之後可以調用其他公共函數。下面給出了已實現例程的功能描述,顯示了低級例程。本文的第二部分將詳細介紹其他驅動程序實現的功能。以下所有函數只能在初始化函數之後調用。因此,將在每個功能的開始時進行雙重檢查,以查看感測器是否已初始化。如果答案是否定的,則該過程會立即返回錯誤。
- adis16500_rd_reg_16
該函數用於讀取16位寄存器。其實現在圖 6 中可用附錄.輸入是廣告,即uint8_t變數表示要讀取的寄存器的位址,以及*p_reg_val這是指向變數uint16_ttype,表示將分配讀取值的位置。要通過SPI協定讀取寄存器,需要兩次SPI訪問;第一個傳輸位址,第二個讀回尋址寄存器的值。在兩次訪問之間需要一個停頓時間,這就是需要延遲功能的原因。在第一次訪問期間,我們傳輸讀/寫位,在這種情況下為 1 (R = 1, W = 0),寄存器位址在 0 處移動 8 位加 8 位,因此順序如下:
反光 |西元6號 |西元5號 |西元 4 |西元3號 |西元2號 |西元1號 |西元 0 |0 |0 |0 |0 |0 |0 |0 |0 |
其中 AD 代表位址,R/W 是讀/寫位。
延遲後,該函數通過 SPI 讀取值並將其傳遞給輸入指標。ADIS16500的寄存器具有包含高值(8 個最高有效位)的高位址和包含低值(8 個低有效位)的低位址。為了獲得16位的整個值(低和高),使用低位址作為廣告就足夠了,因為低位址和高位址是連續的。
- adis16500_wr_reg_16
該函數用於寫入16位寄存器。其實現在圖 6 中可用附錄.輸入是廣告,即uint8_ttype 變數表示要寫入的寄存器的位址,以及reg_val那是一個uint16_ttype 變數,表示要寫入寄存器的值。至於讀取功能,需要考慮低位址和高位址和值。因此,根據數據手冊,寫入ADIS16500寄存器需要在傳輸中進行兩個SPI訪問。第一個將發送等於 0 的 R/W 位,然後是低寄存器地址,然後是低值,因此順序如下:
反光 |西元6號 |西元5號 |西元 4 |西元3號 |西元2號 |西元1號 |西元 0 |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |
其中 D 代表數據。
第二個SPI發送器接入將發送等於0的R/W位,後跟高寄存器位址,後跟高值,因此順序如下:
反光 |西元14 |西元13 |西元12 |西元 11 |西元 10 |西元 9 |西元8號 |D15 |D14 |D13 |D12 |D11 |D10 |D9 |D8 |。
寫寄存器和讀寄存器函數實際上也可以定義為私有,因此無法從驅動程式軟體模組外部可見和調用。將它們定義為公共的原因是啟用調試。這允許設計人員快速訪問感測器中的任何寄存器進行讀取或寫入,這有助於解決問題。
- adis16500_rd_acc
該函數從輸出數據寄存器讀取 x、y、z 加速度數據,並返回它們的值(以 [m/sec2].其實現在圖 7 中可用附錄.輸入是指向ADIS16500_XL_OUT結構,它簡單地嵌入了三個字段:x、y、z 加速度,表示為浮點類型。所有三個軸的加速度讀取方式都是相同的,唯一的區別是要讀取的寄存器。每個軸都有自己的:x軸必須在x加速度輸出數據寄存器上讀取,y軸和z軸相應地讀取。加速度值將用 32 位值表示,因此要讀取的寄存器是兩個。一個用於最高有效 16 位,一個用於最低有效 16 位。出於這個原因,查看代碼,有兩個寄存器讀取訪問具有適當的移位和 OR 位運算。這些作允許將整個二進位值存儲在int32_t變數調用_臨時.此時將發生二進位到雙補碼的轉換。轉換后,雙補碼值除以以 [LSB/(m/sec2),因此最終值將是以 [m/sec2].此值將註冊在指向已作為輸入傳遞的結構的指標的 x、y 或 z 字段中。
- adis16500_rd_gyro
陀螺儀讀取功能與加速度讀取功能完全相同。顯然,它將讀取以 [°/sec] 表示的 x、y、z 陀螺儀數據。它的實現如圖 8 所示附錄.對於加速度情況,該函數的輸入是指向ADIS16500_GYRO_OUT結構嵌入 X、Y 和 Z 陀螺儀數據,表示為浮點類型。讀取的寄存器是陀螺儀輸出數據寄存器。二進位值將用 32 位表示,需要與加速相同的步驟才能達到 2 補碼值。在二進位到雙補碼轉換后,該值將除以以 [LSB/(°/sec)] 表示的靈敏度,以便最終值將以 [°/sec] 表示,並將其註冊到指向已作為輸入傳遞的結構的指標的 x、y 或 z 字段中。
結論
本文介紹了嵌入式系統的典型軟體/固件堆棧。介紹了IMU感測器的驅動器實現。與硬體無關的方法為各種感測器或元件提供了一種可重複的方法,即使介面(SPI、I2C、UART 等)是不同的。隨後的文章”利用與硬體無關的方法簡化嵌入式系統設計:驅動程序實現“進一步詳細解釋了感測器驅動程序的實現。
關於作者
賈科莫·派特尼亞尼
Giacomo Paterniani 在博洛尼亞大學獲得生物醫學工程學位。他在摩德納大學和雷焦艾米利亞大學完成了電子工程碩士學位。畢業后,他花了一年時間...Giacomo Paterniani 在博洛尼亞大學獲得生物醫學工程學位。他在摩德納大學和雷焦艾米利亞大學完成了電子工程碩士學位。畢業后,他花了一年時間...是摩德納大學和雷焦艾米利亞大學的研究員。2022 年 4 月,他作為研究生現場應用工程師加入 ADI 公司的研究生專案。2023年4月,他成為FAE。
安馳科技 FAE support. Please e-mail
► Marketing.anstek@macnica.com
► 或加 安馳科技 LINE 洽詢
► 追蹤 安馳科技 Facebook
► 請加入 安馳YouTube頻道
► 立即填寫料號 申請樣品
洽詢更新產品、技術與安馳抽獎活動