今天各種事情比較多.......技術活時間略少,就搞了這一項~
52832的ADC和之前51822系列還是有蠻大差別的:
1、支持差分輸入方式,測量結果為兩輸入端口電壓差的轉換的有符號數值,這個功能對於啥橋式傳感器的數據采集真是太爽了,可以省一個電平平移放大電路
2、原始分辨率最高提升到12位,14位那個過采樣方式實現的,使用限制很多,不能掃描,還不如自己軟件解決要多少位有多少位。
3、新增“通道”概念,每個通道可以選定使用的+-信號源,轉換是以通道為個體進行的,如果使能多個通道,則一次觸發完成全部通道的掃描轉換。
4、自帶EasyDMA,可以直接把數據打到RAM內,但不能像STM32那樣支持循環傳輸,復位指針只能靠手動
5、取消了外部電壓參考輸入,這個其實有點蛋疼,在測量端供電和MCU供電之間存在變動情況下可能會引入誤差,對於低頻信號,可以用軟件進行補償,但也還有點蛋疼
6、可以自主配置采樣時間,端口負載電阻之類參數
先上調試通過的代碼,這里實現了5個通道的轉換,其中兩個差分通道,三個單端通道,以手動方式觸發,在線程中每100mS觸發一次,數據保存在m_buffer_pool數組中。
這幾點關注:
1、官方庫挺不錯了,提供了一個默認的端口配置的宏定義,很方便,然而實際上還是蠻多東西需要修改的,但這個方法挺可以借鑒
ADC這塊總的來講還是提升蠻大,不過和我希望的還是有蠻大差距。最重要的,即使使用TIMER+PPI觸發,結合EasyDMA來傳輸數據,依舊存在一個缺陷,不能循環方式緩存,導致最終還是需要CPU的參與來維持正常的轉換,一定程度上會減少CPU睡眠時間比例和持續長度。而且,使用庫函數似乎並沒有辦法關掉ADC的中斷,初始化的event_handler必須提供,且每次轉換完成都會產生中斷,勢必喚醒CPU。這樣的話,就導致使CPU在ADC連續采集一段時間之后,再批處理數據不太好實現了。
於是我也照着醬紫自己定義了兩種我常用的端口配置的方式,代碼可以少不少了。這里MCU我用供電是1.8V,所以1/3的增益就夠完成全量程范圍的數據的轉換了。
nrf_drv_saadc_buffer_convert()
這個函數實際是用來配置EasyDMA用的,也就是指定打到內存的位置和限制,但並不會開啟轉換。並且EasyDMA的指針是雙buffer形式的,可以在前一個在使用的情況下直接更新。
不過這里的size這個參量的說明,Buffer size in words,看的有點暈吖,以字為單位的大小??每次轉換結果都是半字大小,以字為單位,掃描通道數目必須是偶數啦?而且也不能代表轉換次數的單位啊。如果是以字方式存放,那就是個廢話,這里填的就應該是項數的2倍,但是例程里面填的又是5........懶得看源碼了,反正我就直接填了個數組項數,每次傳輸完都會復位指針,也不至於溢出了。先就醬紫吧。
nrf_drv_saadc_sample_convert()
這個函數嘛,block方式的轉換,反正我是不會用的,浪費CPU時間浪費電
nrf_drv_saadc_sample()
這個就是正經開啟一次轉換的函數了。轉換完成后,會自動在中斷程序里面調用初始化時候配置的回調函數,並且會得到相關中斷的事件的信息。

ADC這塊總的來講還是提升蠻大,不過和我希望的還是有蠻大差距。最重要的,即使使用TIMER+PPI觸發,結合EasyDMA來傳輸數據,依舊存在一個缺陷,不能循環方式緩存,導致最終還是需要CPU的參與來維持正常的轉換,一定程度上會減少CPU睡眠時間比例和持續長度。而且,使用庫函數似乎並沒有辦法關掉ADC的中斷,初始化的event_handler必須提供,且每次轉換完成都會產生中斷,勢必喚醒CPU。這樣的話,就導致使CPU在ADC連續采集一段時間之后,再批處理數據不太好實現了。
對於此,一種方案就是自己繞過庫函數自己造輪子,編寫相關代碼,也是可以實現得了的。另一種方式,如果采集頻率高於CPU處理頻率唯一目的是更好進行軟件濾波減少誤差,也可以通過提高外圍硬件的濾波性能,取代軟件濾波,原先批處理時候才進行采樣轉換,在同一個時間點多次采樣減少這次時間點的誤差,而軟件濾波就完全由硬件代勞了。