由于保密原因,不能上傳我這邊的代碼,我所用的開發環境是IAR, 下邊轉載別的博主的文章,他用的是MDK
下文的博主給了你一個很好的思路,特此提出表揚
最下方是我做的一些手冊批注,方便大家了解這個東西
原文鏈接:https://blog.csdn.net/wmdscjhdpy/article/details/111288961
前言
本文章本來是作為ADIS16470的測評報告的,寫于2018年,近期整理數據的時候發現這篇文章,而與此同時網上還沒有太多的相關的資料,因此整理一下發到本博客上。鑒于當時水平不足,完成度只做到了驅動起來讀出簡單整理的數據。例程見github:項目鏈接
另外由于傳感器比較新,基本上主要資料都是來源于datasheet,下文中大量圖片也是引用datasheet,如有需要可以先行下載datasheet再跟著思路走可能會更清晰一些:數據手冊下載地址數據手冊下載地址
附當時使用的評測板子圖:
16470
16500
評測正文
基本程序設置與電路搭建
通過數據手冊可以知道,ADIS16470是通過SPI的方式來與主設備的通信的,組成SPI通信需要CLK時鐘線,MOSI輸出線,MISO輸入線與NSS片選線。我手頭上就只有一個STM32F439IGT6核心板,所以我的工程選用了該板來建立工程。
在STM32CubeMX中建立STM32F439IGT6的工程后,建立工程后首先設定好時鐘頻率和調試方式,然后啟用一個SPI和一個普通GPIO作為NSS片選線,如圖:
然后是配置SPI和GPIO方式,作為SPI信號線,GPIO建議設置為開漏輸出模式
SPI的配置方式要根據數據手冊來決定,查閱數據手冊可以發現,CPOL應為1,CPHA應為1,在Cube中即設置Polarity=HIGH, Phase=2Edge(這個問題在剛開始弄的時候一不小心弄錯了 折騰了很久才弄出來)。同時因為ADIS16470傳輸數據是以16bits為一個單位的,可以在Cube中設置SPI的Data Size=16。然后還要調整SPI的Prescaler以降低波特率以保證不超過2Mb/s(使用BurstRead時不能超過1Mb/s)
當以上配置都完成之后可以生成工程,然后根據陀螺儀的數據手冊中的引腳定義,進行核心板和陀螺儀的接線。這里有一點其實我聽迷惑的,就是這里J1的序號并不是從上到下排序的,而是按照行來進行編號的,這一點大家要注意,別一不小心誤操作就把這貴重的陀螺儀給燒了!上千塊的玩意
以BurstRead方式讀取原始數據
該陀螺儀的讀取數據的方式有很多種,而BurstRead就是其中一種方式,它的特點是讀取簡單,連續讀取,一步到位獲得三軸加速度和三軸角速度值。在對精度要求不是很高要求快速上手的情況下,BurstRead方式是一個不錯的選擇。
查閱技術手冊可以得到BurstRead方式的操作時序圖,在啟動的時候將CS線拉低,隨后發送一個字0x6800,然后連續讀取SPI數據,就能得到按照一定順序排列的傳感器數據了。
根據數據手冊上數據的排列,可以定義一個結構體用于存放數據:
然后就可以在程序中做一個循環讀取,讀取前先發BurstRead前置指令,然后將剩下讀到的數據放到結構體內即可。為了保證數據可靠性,每一幀數據都存在一個校驗字節可用于保證幀完整性和可靠性。在每次接收完完整的一幀之后,可以進行數據校驗,僅當校驗成功時保留數據。以下為讀取出來的傳感器值(原始數據值):
通過單獨讀取寄存器來獲得傳感器數據
在大部分時候,BurstRead可以滿足基本上的需求,可是ADIS16470擁有更精準的32位精度的數據,在我們有更高要求的時候,通過讀取其寄存器可以得到非常高的精度的傳感器數據。
下圖則為其角速度的32位數據精度,為655360LSB每度每秒,可以說是十分嚇人了:
所以,當我們有高精度需求的時候,就需要單獨的去讀取它的寄存器了。讀取寄存器的時序如下:
可以看到,每次發送需要讀取的寄存器的時候,讀取結果會在SPI傳輸的下一個時序中返回。為了提高讀取效率,可以將需要讀取的寄存器地址連續發送,然后在接收時加上偏移即可。
在讀取完畢之后,將兩個16位數據合成一個32位的數據(根據手冊,按照小端模式,低位低地址高位高地址合并),這樣就得到了32位的原始數據。僅僅得到原始數據還不夠,根據如上圖的表格得到原始數據到標準單位的關系進行換算,最終得到三軸角速度以及三軸加速度值。
在取到三軸角速度和三軸加速度后,我們還有一個經常使用的值,就是三軸的姿態角。很多時候對于普通陀螺儀我們都是直接取速度的積分作為角度值,這樣存在一定的偏差。為了解決積分的準確度,ADIS16470還提供了角度差數據。這個數據提供一定時間區間內的角度差,默認值為1/2000秒的角度差。在做機器人控制系統的時候,我們一般不需要用到這么高的數據頻率,因此我們需要提高積分的時間,即降低數據頻率。ADIS16470中提供了一個寄存器用來控制積分時間,如果這個寄存器為x的話,數據頻率就為2000/(x+1)Hz。該寄存器的默認值為0,所以默認頻率為2000Hz。在控制系統的用途中,我們把數據頻率控制到500Hz就可以獲得較佳的控制效果了。因此我們需要寫入該寄存器為0x03把積分時間提升到1/500s。
當我們的控制周期為500Hz時,每次讀取角度差值并進行積分,此時積分的結果就是較為精確的角度值,不會因為控制頻率的降低而損失精度。 最終的所有數據如下:
簡單的數據處理
從剛剛我們已經得到了所有的數據,不過數據還是不大穩定,這時候還需要做一些處理。
陀螺儀由于其硬件限制,會存在零點漂移,也就是說當真實的某軸角速度為0的時候,其輸出的值并不是0而是一個接近0的數,也就是說它的零點發生了偏移。ADIS16470內部提供了零點校準的寄存器值,其工作的原理如下:
也就是說,確定好了合適的零點偏移量后,每次陀螺儀的數據都會經過偏移量的修正從而得到較為準確的數據。一般常用確定零點漂移量的方法是在程序啟動的一段時間內保持陀螺儀不發生運動,采集一段時間的數據,然后用得到的角度除以自檢的時間得到偏移角速度,然后將其取負號作為零點漂移修正值。在進行零點修正后,陀螺儀就能讀出更穩定的數據了。
當然影響陀螺儀的準確度的因素遠不止這一種,還有很多諸如隨機漂移,高頻振動等各種影響陀螺儀準確度的因素,不過因為ADIS16470的各個方面的性能都很出色,把像隨機漂移和高頻振動帶來的偏移這種較難處理的誤差降到很低,所以簡單處理就能得到較好的數據。除了零點修正外,ADIS16470還內置了巴特沃斯濾波器,可以根據需求通過配置寄存器可以開啟濾波器得到更準確的數據。如果還需要更精確的數據還可以考慮數據融合算法,在此不再贅述。
關于細節可以參考我做的一些批注,用的是16500,如下
https://download.csdn.net/download/weixin_44057803/88226636
其實16470的手冊我感覺比16500更專業,而且解釋更專業
下邊這個16500手冊都寫錯了