利用與硬件無關的方法簡化嵌入式係統設計:基本知識
發布時間:2025-02-24 來源:ADI公司 責任編輯:lina
【導讀】benwenjiangyanshiyizhongjiasuqianrushixitongshejiyuanxingjieduandefangfa,shuomingruhejiangyuyingjianwuguandequdongchengxuhechuanganqijieheshiyong,jianhuazhenggeqianrushixitongdeqijianxuanze。tongshihaijiangjieshaoqianrushixitongdeqijian、典型軟件結構以及驅動程序的實現。後續文章“利用與硬件無關的方法簡化嵌入式係統設計:驅動程序實現”將進一步探討執行過程。
摘要
benwenjiangyanshiyizhongjiasuqianrushixitongshejiyuanxingjieduandefangfa,shuomingruhejiangyuyingjianwuguandequdongchengxuhechuanganqijieheshiyong,jianhuazhenggeqianrushixitongdeqijianxuanze。tongshihaijiangjieshaoqianrushixitongdeqijian、典型軟件結構以及驅動程序的實現。後續文章“利用與硬件無關的方法簡化嵌入式係統設計:驅動程序實現”將進一步探討執行過程。
簡介
通(tong)過(guo)使(shi)用(yong)與(yu)硬(ying)件(jian)無(wu)關(guan)的(de)驅(qu)動(dong)程(cheng)序(xu),設(she)計(ji)人(ren)員(yuan)可(ke)以(yi)自(zi)由(you)選(xuan)擇(ze)微(wei)控(kong)製(zhi)器(qi)或(huo)處(chu)理(li)器(qi)的(de)類(lei)型(xing)來(lai)管(guan)理(li)傳(chuan)感(gan)器(qi),而(er)不(bu)受(shou)硬(ying)件(jian)的(de)限(xian)製(zhi)。這(zhe)種(zhong)方(fang)法(fa)的(de)優(you)勢(shi)在(zai)於(yu),除(chu)了(le)供(gong)應(ying)商(shang)提(ti)供(gong)的(de)基(ji)本(ben)軟(ruan)件(jian)層(ceng)外(wai),還(hai)可(ke)以(yi)添(tian)加(jia)額(e)外(wai)的(de)軟(ruan)件(jian)層(ceng),同(tong)時(shi)簡(jian)化(hua)傳(chuan)感(gan)器(qi)的(de)集(ji)成(cheng)。本(ben)文(wen)將(jiang)以(yi)慣(guan)性(xing)測(ce)量(liang)單(dan)元(yuan)(IMU)傳感器為例,說明如何實現與硬件無關的驅動程序,不過,這種方法同樣適用於其他類型的傳感器和器件。驅動程序采用C語言編寫,並在一款通用微控製器上進行了測試。
器件選擇
IMU傳感器主要用於運動檢測,以及通過加速度和角速度來測量運動強度。本示例選擇使用ADIS16500 IMU傳感器(圖1),因為與複雜且昂貴的分立設計方案相比,該傳感器能夠為精確的多軸慣性檢測與工業係統的集成提供簡單且經濟高效的方法。
圖1.ADIS16500評估板。
主要應用包括:
• 導航、穩定性和儀器儀表
• 無人機和自動駕駛車輛
• 智能農業和施工機械設備
• 工廠/工業自動化、機器人
• 虛擬/增強現實
• 運動物聯網
圖2.ADIS16500框圖。
ADIS16500是一款精密微型機電係統(MEMS) IMU,內置一個三軸陀螺儀、一個三軸加速度計和一個溫度傳感器。參見圖2。該IMU的靈敏度、偏置、對準、線性加速度(陀螺儀偏置)和坐標軸原點(加速度計位置)已在工廠校準。這意味著在各種條件下都能提供精確的傳感器測量。
通過該接口,微控製器可以寫入和讀取用戶控製寄存器,並讀取輸出數據寄存器,從而獲得加速度計、陀螺儀或溫度傳感器數據。為此,管理該接口所需的全部軟件和固件均已完成開發。圖2所示為數據就緒(DR)引腳。該引腳是一個數字信號,指示何時可從傳感器讀取新數據。DR引腳可被視為通過通用輸入/輸出(GPIO)端口的輸入,因此可通過微控製器輕鬆管理。
從硬件的角度來看,IMU傳感器和微控製器將使用SPI接口連接,該接口是由nCS、SCLK、DIN和DOUT引腳組成的4線接口。DR引腳應連接到微控製器的其中一個GPIO。此外,IMU傳感器需要3 V至3.6 V的電源電壓,因此3.3 V就足夠了。
了解嵌入式係統的典型軟件結構
圖3.嵌入式係統的軟件/固件結構。
了le解jie嵌qian入ru式shi係xi統tong的de通tong用yong軟ruan件jian和he固gu件jian結jie構gou對dui於yu與yu傳chuan感gan器qi驅qu動dong程cheng序xu連lian接jie至zhi關guan重zhong要yao。這zhe將jiang幫bang助zhu設she計ji人ren員yuan構gou建jian一yi個ge靈ling活huo且qie易yi於yu集ji成cheng到dao任ren何he項xiang目mu的de軟ruan件jian模mo塊kuai。此ci外wai,驅qu動dong程cheng序xu必bi須xu以yi模mo塊kuai化hua的de方fang式shi實shi現xian,以yi使shi設she計ji人ren員yuan能neng夠gou依yi賴lai於yu現xian有you函han數shu添tian加jia更geng高gao級ji的de函han數shu。
嵌入式係統的軟件結構如圖3所示。在圖3中,層次結構從應用層開始,應用代碼就是在這一層編寫的。應用層包括main文件、依yi賴lai於yu傳chuan感gan器qi的de應ying用yong模mo塊kuai,以yi及ji依yi賴lai於yu管guan理li處chu理li器qi配pei置zhi的de外wai設she驅qu動dong程cheng序xu的de模mo塊kuai。此ci外wai,在zai應ying用yong層ceng中zhong,還hai有you與yu微wei控kong製zhi器qi必bi須xu處chu理li的de任ren務wu相xiang關guan的de所suo有you模mo塊kuai。例li如ru,通tong過guo中zhong斷duan或huo輪lun詢xun、zhuangtaijidengguanlirenwudesuoyouruanjian。yingyongcengjibiegenjuxiangmudeleixingeryousuobutong,yincibutongxiangmuzhongshixiandedaimayebutong。zaiyingyongceng,xitongdesuoyouchuanganqigenjuqishujushoucejinxingchushihuahepeizhi。chuanganqiqudongchengxutigongdesuoyougonggonghanshujunketiaoyong。liru,duqufuzeshuchushujudejicunqi,huozhexieruyigejicunqiyigenggaishezhi/校準的程序。
應(ying)用(yong)層(ceng)下(xia)麵(mian)是(shi)傳(chuan)感(gan)器(qi)的(de)驅(qu)動(dong)層(ceng),這(zhe)一(yi)層(ceng)有(you)兩(liang)種(zhong)類(lei)型(xing)的(de)接(jie)口(kou)。可(ke)從(cong)應(ying)用(yong)層(ceng)調(tiao)用(yong)的(de)所(suo)有(you)函(han)數(shu)都(dou)在(zai)這(zhe)一(yi)層(ceng)實(shi)現(xian)。此(ci)外(wai),函(han)數(shu)的(de)原(yuan)型(xing)插(cha)入(ru)到(dao)驅(qu)動(dong)程(cheng)序(xu)標(biao)頭(tou)文(wen)件(jian)(.h)zhong。yinci,tongguozhakanchuanganqiqudongchengxudebiaotouwenjian,ninkeyilejiequdongchengxudejiekouyijikecongjiaogaocengjitiaoyongdehanshu。jiaodijibiedecengjiangyutedingwaishequdongchengxulianjie,zhexiewaishequdongchengxuyilaiyuguanlichuanganqideweikongzhiqi。waishequdongchengxubaokuoguanliweikongzhiqiwaishedesuoyoumokuai,liruSPI、I2C、UART、USB、CAN、SPORT等,或管理處理器內部模塊的模塊,例如定時器、內存、ADC等。由於它們與硬件緊密相關,因此稱為低級函數。例如,由於微控製器不同,因此每個SPI驅動程序都是不同的。我們以ADIS16500為例。接口是SPI,因此其驅動程序將與微控製器的SPI驅動程序封裝在一起。對於不同的傳感器和不同的接口也是如此。例如,如果另一個傳感器具有I2C接口,那麼同樣地,將在傳感器的初始化過程中與微控製器的I2C驅動程序封裝一起。
傳感器驅動程序的下層是外設驅動程序,各類微控製器的外設驅動程序各不相同。如圖3所(suo)示(shi),外(wai)設(she)驅(qu)動(dong)程(cheng)序(xu)和(he)低(di)級(ji)驅(qu)動(dong)程(cheng)序(xu)是(shi)分(fen)開(kai)的(de)。本(ben)質(zhi)上(shang),外(wai)設(she)驅(qu)動(dong)程(cheng)序(xu)通(tong)過(guo)可(ke)用(yong)的(de)通(tong)信(xin)協(xie)議(yi)提(ti)供(gong)讀(du)寫(xie)函(han)數(shu)。由(you)於(yu)低(di)級(ji)驅(qu)動(dong)程(cheng)序(xu)將(jiang)管(guan)理(li)信(xin)號(hao)的(de)物(wu)理(li)層(ceng),因(yin)此(ci)它(ta)非(fei)常(chang)依(yi)賴(lai)於(yu)設(she)計(ji)人(ren)員(yuan)所(suo)使(shi)用(yong)的(de)硬(ying)件(jian)。外(wai)設(she)和(he)低(di)級(ji)驅(qu)動(dong)層(ceng)往(wang)往(wang)通(tong)過(guo)可(ke)視(shi)化(hua)工(gong)具(ju)從(cong)微(wei)控(kong)製(zhi)器(qi)的(de)集(ji)成(cheng)開(kai)發(fa)環(huan)境(jing)(IDE)生成,具體取決於安裝微控製器的評估板。
驅動程序實現
與硬件無關的方法支持在不同應用、不bu同tong微wei控kong製zhi器qi或huo不bu同tong處chu理li器qi中zhong使shi用yong相xiang同tong的de驅qu動dong程cheng序xu。這zhe種zhong方fang法fa取qu決jue於yu驅qu動dong程cheng序xu的de實shi現xian方fang式shi。要yao了le解jie驅qu動dong程cheng序xu的de實shi現xian方fang式shi,首shou先xian要yao看kan接jie口kou,或huo圖tu4中的傳感器標頭文件(adis16500.h)。
標頭文件包含有用的公共宏。其中包括寄存器的地址、SPI最大速度、默認輸出數據速率(ODR)、位掩碼,以及加速度計、陀螺儀和溫度傳感器的輸出靈敏度,這些宏與用於表示數據的位數(16或32)有關。圖4顯示了這些宏,其中僅顯示了幾個寄存器的地址作為示例。本文引用的代碼可參見附錄。
圖4.ADIS16500標頭文件(adis16500.h)中顯示的宏。
附錄中的圖3顯示了包括adis16500.h在內的每個模塊均可使用的所有公共變量和公共類型聲明,其中定義了新的類型,以便更有效地管理數據。例如,ADIS16500_XL_OUT類型被定義為包含三個浮點的結構,每個軸(x、y和z)yigefudian。ciwai,haitongguomeijulaizhichibutongdechuanganqipeizhi,shishejirenyuannenggoulinghuodixuanzefuhezishenxuqiudepeizhi。zuizhideguanzhudeshishiqudongchengxuyuyingjianwuguandebufen。zaigonggongbianliangbufendekaitou(附錄中的圖3),有三個關鍵的類型定義:指向三個基本函數的指針,或者SPI發送和接收函數,以及為生成正確的停轉時間,兩次SPI訪問之間所需的延遲函數。這些代碼還顯示了可指向的函數的原型。SPI發送函數將指向待發送值的指針作為輸入,然後返回可供檢查的內容,以確定發送是否成功。SPI接jie收shou函han數shu也ye是shi如ru此ci,該gai函han數shu將jiang指zhi向xiang變bian量liang的de指zhi針zhen作zuo為wei輸shu入ru,這zhe個ge指zhi針zhen將jiang存cun儲chu接jie收shou時shi讀du取qu的de值zhi。延yan遲chi函han數shu以yi浮fu點dian數shu作zuo為wei輸shu入ru,表biao示shi設she計ji人ren員yuan想xiang要yao等deng待dai的de微wei秒miao數shu,不bu返fan回hui任ren何he內nei容rong(void)。通過這種方式,設計人員可以在應用層(例如在main文件中)利用這些特定的原型來聲明這三個函數。聲明後,他們可以將這三個函數賦值給ADIS16500_INIT私有結構的字段。附錄中的圖2列舉了一個示例,以幫助更好地理解最後一步。
SPI發送器、接收器函數和延遲函數在mainwenjianzhongshengmingweijingtaihanshu,yincishuyuyingyongceng。zhexiehanshuyilaiyuwaishequdongchengxuhanshu,yincichuanganqiqudongchengxubenshenyuyingjianwuguan。zhesangehanshubeifenpeigeiyigebianliangdeziduan,erzhexieziduanshizhixianghanshudezhizhen。zheyangyilai,shejirenyuankeyifengzhuangchuanganqiheweikongzhiqi,erwuxuxiugaichuanganqiqudongchengxudaima。ruguoshejirenyuangenghuanweikongzhiqi,tamenzhixujiangsangejingtaihanshuneidedijihanshutihuanweixinweikongzhiqidexiangyinghanshu,congertiaozhengmain文件。通過這種方法,驅動程序變得與硬件無關,因為設計人員不需要更改傳感器的驅動程序代碼。微控製器的IDE中通常包含spiSelect、spiReceive、spiUnselect、chThdSleepMicroseconds等低級函數。在本例中,所用的微控製器評估板是SDP-K1,它嵌入了STM32F469NIH6 Cortex®-M4微控製器。該IDE是ChibiOS,這是一個免費的Arm®開發環境。
附錄中的圖4顯示了應用級別的可調用函數原型。這些原型以及附錄中圖2和圖3討論的所有其他軟件和固件都可在傳感器驅動程序的標頭文件(adis16500.h)中找到。首先,初始化函數(adis16500_init)將指向ADIS16500_INIT結構的指針作為輸入,並返回狀態代碼,以指示初始化是否成功。初始化函數的實現在傳感器驅動程序的源文件(adis16500.c)中完成。附錄中的圖5所示為adis16500_init函數的代碼。首先,定義名為ADIS16500_PRIV的類型,其中至少包含ADIS16500_INIT結構的所有字段,然後聲明一個屬於該類型的私有變量_adis16500_priv。在初始化函數中,應用層傳遞的ADIS16500_INIT結構的所有字段將賦值給私有變量_adis16500_priv的字段。這意味著,對傳感器驅動程序的任何後續調用都將使用由應用層傳入的SPIduxiehanshuhechuliqiyanchihanshu。zheyidianhenguanjian,zhengyinruci,chuanganqiqudongchengxucainengyuyingjianwuguan。ruguoshejirenyuanxiangyaogenggaiweikongzhiqi,zhixugenggaichuandigeiadis16500_init函數的函數即可,不需要修改傳感器驅動程序代碼本身。在初始化函數開頭,_adis16500_priv變量的已初始化字段設置為false,因為初始化過程尚未完成。在該函數結束時,該字段將設置為true,然後返回。設計人員每次調用另一個公共函數(附錄中的圖4)時,都會執行以下檢查:如果_adis16500_priv.initialized為true,可以繼續;如果為false,將立即返回ADIS16500_RET_VALERROR錯誤。這是為了防止用戶在沒有先初始化傳感器驅動程序的情況下調用函數。繼續討論初始化函數,執行以下步驟:
1. 通過讀取ADIS16500_REG_ PROD_ID寄存器,檢查預先已知的產品ID。
2. 將應用層(main.c)傳遞的值寫入ADIS16500_REG_MSC_CTRL寄存器的相應位字段,設置數據就緒(DR)引腳極性。
3. 將應用層(main.c)傳遞的值寫入ADIS16500_REG_MSC_CTRL寄存器的相應位字段,設置同步模式。
4. 將應用層(main.c)傳遞的值寫入ADIS16500_REG_DEC_RATE寄存器,設置抽取率。
初始化函數取決於讀寫寄存器函數(附錄中的圖6)。因此,為_adis16500_priv變量賦值之後,需要完成上述四個例程。否則,在調用讀取或寫入寄存器函數時,它們不知道該使用哪個SPI發送器、接收器和處理器延遲函數。
參考附錄中的圖4,zaichushihuahanshuzhihou,haikeyitiaoyongqitagonggonghanshu。xiamianshiyishixianlichengdegongnengmiaoshu,suoshiweidijibielicheng。benwendedierbufenjiangxiangxijieshaoqudongchengxudeqitayishixianhanshu。yixiasuoyouhanshuzhinengzaichushihuahanshuzhihoutiaoyong。weici,jiangzaimeigehanshukaitouzaixijianzha,yiquedingchuanganqishifouyichushihua。ruguoweichushihua,chengxuhuilijifanhuicuowu。
u adis16500_rd_reg_16
該函數用於讀取16位寄存器。該函數實現可參見附錄中的圖6。輸入包括ad,這是一個uint8_t變量,表示要讀取的寄存器的地址,以及*p_reg_val,這是指向uint16_t類型變量的指針,表示讀取值將賦值的目標。要通過SPI協議讀取寄存器,需要訪問兩次SPI;diyicifangwenshiweilefasongdizhi,diercishiweileduhuibeixunzhijicunqidezhi。liangcifangwenzhijianxuyaoyoutingzhuanshijian,yincixuyaoyanchihanshu。zaidiyicifangwenguochengzhong,womenfasongdu/寫位,在本例中為1(R = 1,W = 0),寄存器地址移位8位,再補充8位0,因此序列如下:
R/W | AD6 | AD5 | AD4 | AD3 | AD2 | AD1 | AD0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
其中AD代表地址,R/W代表讀/寫位。
經過延遲後,函數通過SPI讀取值,並將該值傳遞給輸入指針。ADIS16500的寄存器具有一個包含高位值(8個最高有效位)的高地址和一個包含低位值(8個低有效位)的低地址。為了獲得16位的完整值(低位和高位),使用低地址作為ad已經足夠,因為低地址和高地址是連續的。
u adis16500_wr_reg_16
該函數用於寫入16位寄存器。該函數實現可參見附錄中的圖6。輸入包括ad,這是一個uint8_t類型變量,表示要寫入的寄存器的地址,以及reg_val,這是uint16_t類型變量,表示要寫入寄存器的值。對於讀取函數,需要考慮低地址和高地址以及低位值和高位值。因此,根據數據手冊,要想寫入ADIS16500的寄存器,需要在發送時訪問兩次SPI。第一次訪問將發送等於0的R/W位,接著是低寄存器地址,然後是低位值,因此序列如下:
R/W | AD6 | AD5 | AD4 | AD3 | AD2 | AD1 | AD0 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |,其中D代表數據。
第二次SPI發送器訪問將發送等於0的R/W位,接著是高寄存器地址,然後是高位值,因此序列如下:
R/W | AD14 | AD13 | AD12 | AD11 | AD10 | AD9 | AD8 | D15 | D14 | D13 | D12 | D11 | D10 | D9 | D8 |。
xieruheduqujicunqihanshushijishangyekeyidingyiweisiyou,yincicongqudongchengxuruanjianmokuaiwaibubukejian,yebuketiaoyong。jiangtamendingyiweigonggongshiweilenenggoutiaoshi。zheyangyilai,shejirenyuannenggoukuaisufangwenchuanganqizhongderenhejicunqiyijinxingduquhuoxieru,congerbangzhujiejuewenti。
u adis16500_rd_acc
該函數從輸出數據寄存器讀取x、y、z加速度數據,並返回它們的值,單位為[m/sec2]。該函數實現可參見附錄中的圖7。輸入是指向ADIS16500_XL_OUT結構的指針,它隻嵌入三個字段:以浮點類型表示的x、y、z加速度。在這三個軸上,讀取加速度的方式是相同的,唯一的區別在於要讀取的寄存器。每個軸有其各自要讀取的寄存器:x軸必須在x加速度輸出數據寄存器上讀取,y和z軸也在相應寄存器上讀取。加速度值將用32位值來表示,因此要讀取的寄存器有兩個。一個讀取高16位,一個讀取低16位。因此,通過查看代碼可知,將進行兩次寄存器讀取訪問,再加上適當的移位和OR位運算,得到整個二進製值並存儲在名為_temp的私有int32_t變量中。然後,數據將經過二進製轉二進製補碼的轉換。轉換後,用二進製補碼值除以靈敏度(單位為[LSB/(m/sec2)]),這樣最終將獲得以[m/sec2]為單位的加速度值。此值將記錄到指針的x、y或z字段,該指針指向已作為輸入傳遞的結構。
u adis16500_rd_gyro
陀螺儀讀取函數與加速度讀取函數的實現方法完全相同。毫無疑問,該函數將讀取x、y、z陀螺儀數據,單位為[°/sec]。其實現方法可參見附錄中的圖8。與加速度函數類似,函數的輸入是指向ADIS16500_GYRO_OUT結構的指針,該結構嵌入以浮點類型表示的x、y和z陀螺儀數據。讀取的寄存器是陀螺儀輸出數據寄存器。二進製值將用32位表示,要獲得二進製補碼值,需要完成與加速度函數相同的步驟。完成二進製到二進製補碼轉換後,用得到的值除以靈敏度(單位為[LSB/(°/sec)]),最終得到以[°/sec]為單位的值,然後該值將記錄到指針的x、y或z字段,該指針指向已作為輸入傳遞的結構。
結論
本文闡述了嵌入式係統的典型軟件/固件堆棧,介紹了IMU傳感器的驅動程序實現。與硬件無關的方法為各種傳感器或器件提供了可重複使用的方法,即使接口(SPI、I2C、UART等)不同也沒關係。後續文章“利用與硬件無關的方法簡化嵌入式係統設計:驅動程序實現”進一步詳細解釋了傳感器驅動程序的實現方法。
(來源:ADI公司,作者: Giacomo Paterniani,現場應用工程師)
免責聲明:本文為轉載文章,轉載此文目的在於傳遞更多信息,版權歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權問題,請聯係小編進行處理。
推薦閱讀:
- 噪聲中提取真值!瑞盟科技推出MSA2240電流檢測芯片賦能多元高端測量場景
- 10MHz高頻運行!氮矽科技發布集成驅動GaN芯片,助力電源能效再攀新高
- 失真度僅0.002%!力芯微推出超低內阻、超低失真4PST模擬開關
- 一“芯”雙電!聖邦微電子發布雙輸出電源芯片,簡化AFE與音頻設計
- 一機適配萬端:金升陽推出1200W可編程電源,賦能高端裝備製造
- 1200餘家企業齊聚深圳,CITE2026打造電子信息產業創新盛宴
- 掌握 Gemini 3.1 Pro 參數調優的藝術
- 築牢安全防線:電池擠壓試驗機如何為新能源產業護航?
- Grok 4.1 API 實戰:構建 X 平台實時輿情監控 Agent
- 電源芯片國產化新選擇:MUN3CAD03-SF助力物聯網終端“芯”升級
- 車規與基於V2X的車輛協同主動避撞技術展望
- 數字隔離助力新能源汽車安全隔離的新挑戰
- 汽車模塊拋負載的解決方案
- 車用連接器的安全創新應用
- Melexis Actuators Business Unit
- Position / Current Sensors - Triaxis Hall









