Hi3518EV200平台ADC多通道采樣流程
Hi3518EV200 ADC
本文針對Hi3518EV200平台處理器,通過ADC單次采樣方式,實現對多通道(1~4通道)ADC進行采樣控制。本文僅僅是對Hi3518EV200芯片ADC的用法的介紹,不涉及ADC具體的工作原理、轉換原理等細節內容。廢話不多說,直入正題!
Hi3518EV200芯片ADC模塊簡介:
特性:
電源電壓:3.3V
掃描頻率不能高於200K/s
獨立通道:4路
特點:
支持單次啟動,每次掃描一個通道,不濾毛刺,提供中斷以及查詢。
支持連續掃描功能:
根據ch_vld自動輪詢各通道
根據Tscan(掃描間隔)啟動連續查詢
根據Tglitch進行濾毛刺,完成對毛刺的有效判定
上報LSADC轉換結果、對應的通道號
上報中斷:有按鍵中斷,按鍵有變化中斷(此部分不太明白,是筆誤寫成了按鍵還是另有深意,不太清楚)
以上特性和特點摘自Hi3518EV200芯片手冊,文章還會摘取Hi3518EV200芯片手冊的部分寄存器截圖以作介紹。
ADC的實現方法簡述:
Hi3518EV200平台的ADC模塊支持4個通道,分兩種模式采樣:
第一種是單次掃描模式,支持多通道掃描;
第二種是連續Scan掃描模式,支持多通道掃描(測試驗證未成功,在此處就不多說了)
單次掃描模式的工作實現方法
- 打開ADC時鍾
- 各個控制寄存器配置(參考手冊流程配置,含采樣值位數,通道使能,單次掃描,不支持powerdown等)
- 使用request_irq注冊ADC中斷,中斷號19
以上配置封裝成Init函數,模塊加載時初始化ADC模塊使用
ADC開始采樣
具體操作函數封裝為ADC_Start(),包含以下工作:
- 判斷需要采樣的通道和上次工作的通道是否為同一個通道(為什么要這么做,在下面內容會有說明)
- Disable中斷,停止ADC,清空所有通道中斷,清空通道使能,使能需要采樣的通道,備份該通道等下次采樣判斷
- 如果1中的判斷是同一個通道,就忽略2中操作
- 開始ADC采樣,使能ADC中斷
- 備份本次采樣的通道號,以備下次采樣時在1中進行判斷
中斷處理函數的工作
- 判斷使能的是哪個通道
- 判斷該使能的通道的中斷標志是否置位(即該通道轉換是否完成,一般都會完成)
- 獲取該通道轉換后的值
- 如果注冊了其他對該數據操作的函數,就執行
- 清空該通道的中斷標志位(此處需要小心操作,不然會引起不可知現象,詳細見下文說明)
注:
需要在中斷處理函數中設置ADC轉換狀態,在調用開始ADC轉換的地方,判斷ADC采樣是否正在進行,如果ADC正在使用(即ADC轉換已經開始,轉換完成中斷還未發生),就延時等待,直到該中斷完成之后再開啟ADC轉換。
ADC采樣具體實現:
通過配置ADC模塊的相關配置寄存器使ADC正常工作。


ADC時鍾:
打開ADC時鍾:
ADC時鍾配置在PERI_CRG31寄存器(參考下圖),要打開ADC的時鍾,需要將[1]置1。
ADC軟復位:
這里的ADC軟復位是指SAR_ADC的軟復位請求,在PERI_CRG31寄存將[2]置1表示復位,置0表示撤銷復位。

ADC參數配置:
ADC參數配置部分需要設置LSADC_CTRL0配置寄存器。


在初始化ADC時需要將ADC復位(為何要先復位,不太清楚,感覺這樣做對設備來說更安全),設置ADC進入復位狀態需要設置配置寄存器,把[15]置1即可。
ADC時鍾撤銷復位:將時鍾寄存器PERI_CRG3的[2]置0,通上述打開ADC時鍾。
ADC退出復位狀態:將LSADC_CTRL0配置寄存器的[15]置0。
ADC通道使能,選擇需要使用的ADC通道使能,將相應的位置1相應通道有效,置0則相應通道無效。
0通道 [8]置1
1通道 [9]置1
2通道 [10]置1
3通道 [11]置1
ADC轉換精度設置:
[31:24] 設為0xFF 表示8bit精度,即采樣范圍:0~255
ADC掃描模式選擇:
[13] 0 單次掃描模式
ADC的PowerDown支持選擇:
[14] 0 不支持
到這里,ADC的復位和初始化工作完成,具體的初始化操作ADC單次采樣流程可以參考下圖流程。每次復位都需要重新設置初始化參數。


ADC中斷設置
需要注冊ADC中斷,在ADC采樣完成時發出中斷,開始記錄采樣值。中斷流程和別的中斷處理類似(比如按鍵中斷),ADC的中斷號是19。具體中斷細節此處省略。
開始ADC采樣:
開始ADC采樣的一些操作步驟:
- 先要判斷ADC當前的采樣通道和要采樣的通道是否相同,如果ADC當前的采樣通道和要采樣的通道不相同,需要進行一些操作使ADC通道切換到需要采樣的通道。(這一步不是必須,如果要多路采樣,建議加上該部分,具體原因下文介紹)
- 將ADC的中斷使能關閉,即將中斷使能寄存器LSADC_CTRL4的[0]置0
- 停止ADC采樣,即將Stop配置寄存器LSADC_CTRL8的[31:0]寫入任意值就可以實現停止ADC采樣,比如寫入1
- 將ADC要采樣的通道的中斷清除,設置中斷清除寄存器LSADC_CTRL6的[3:0]位,將通道號相對應的位置1
- 關閉ADC各通道使能,在配置寄存器LSADC_CTRL0的[11:8]位全部清零
- 單獨使能要進行采樣的通道,設置配置寄存器LSADC_CTRL0的[11:8]位將相應通道使能,如將[8]置1使能A通道
- 備份本次采樣通道號,用來在開始工作時判斷通道是否相同時(第1步)使用
- 如果ADC當前的采樣通道號和要采樣的通道相同,就可以跳過第2.3.4.5.6.7直接啟動ADC采樣
- 啟動ADC采樣,設置Start配置寄存器LSADC_CTRL7的[31:0]位,寫入任意值就可以啟動ADC采樣,比如寫入1
- 最后要使能ADC采樣中斷,采樣完成后發出中斷,將中斷使能寄存器LSADC_CTRL4的[0]位置1
以上的ADC采樣操作可以用簡單的方法,只需第2.3.4.5.6.9.10步即可,如果只使用單通道采樣,只需要將這幾步操作放到ADC初始化操作中執行一次就可以,不用每次開始ADC采樣都設置。至於為什么比較麻煩,是為了應對多路采樣時,有的通道采樣時間間隔比較小,有的通道采樣時間間隔比較大,造成的重復無意義的操作。
舉例說明:ADC要采樣的是光照、溫度數據,在采樣時間間隔不多的時候,比如光敏一秒一次,溫度三秒一次,這樣的情況是沒有什么差別的,但是如果時間間隔差的很多,比如光敏一秒一次,溫度30秒一次,這樣的情況,在兩次溫度采樣間隔內的30秒,光敏要采樣30次,就要初始化30次,這是沒有必要的。所以就需要加上第1步的判斷邏輯,如果需要采樣的通道和上次采樣的通道是同一個通道,就免去了重復初始化同一個通道的操作,減輕處理負擔。
ADC中斷處理函數:
在中斷發生時需要做的工作:
- 逐個判斷各通道是否有效,也可以獲取配置寄存器LSADC_CTRL0的[11:8]位來確定當前采樣通道。
因為使用的是單個通道逐個采樣的方法,所以同一時刻只有一個通道在工作,通過在中斷函數中檢測哪個通道被使能可以得到是由哪個通道采樣發生的中斷。 - 檢查中斷狀態寄存器,判斷相應通道的掃描值是否有效
檢查中斷狀態寄存器LSADC_CTRL5的[3:0]位是否被置1,置1則相應通道的掃描值有效,否則無效。 - 如果中斷狀態有效,就可以讀取ADC采樣值
直接讀取數據保持寄存器LSADC_CTRL3:
[7:0] 通道A掃描值
[15:8] 通道B掃描值
[23:16] 通道C掃描值
[31:24] 通道D掃描值 - 清除中斷狀態標志
設置中斷清除寄存器LSADC_CTRL6的[3:0]位,將相應的位置1,清除相應通道的中斷 - 需要添加保險機制,在中斷發生后即第1步之后,如果2、3步判斷失敗,就沒法進行4步的清中斷,這將導致ADC采樣卡死(不采樣也不運行中斷)
此時的解決方法就是復位ADC,但是這樣做有點粗暴,比較好的方法還是避免出現這種卡死現象,比如添加第5步的保險機制,即判斷中斷都沒有執行時就清除4步寄存器中的對應通道中斷,或者清除所有通道中斷。
之后就是對獲取到的ADC采樣值進行處理了,略。
總結
至此,ADC通過單次采樣的方式對多通道采樣的方法介紹完畢,通過這種方法就能通過單次采樣的方式對多個通道的數據進行輪流采樣了,采樣獲取到的數據是在前邊設置的采樣精度范圍內,根據實際需要進行處理。有必要提醒下,實時采樣得到的數據會存在一些漂移,可以通過硬件濾波使數據穩定,或者在軟件中添加濾波算法,對采樣得到的數據進行濾波處理。如果朋友們有更好的實現方法,還請指教一二,歡迎相互交流心得。
附:數據手冊上的ADC相關配置寄存器截圖









附:ADC采樣支持連續掃描處理
連續掃描處理過程在驗證時沒有得到想要的效果,在這里不便多說,下面僅列出文檔中連續掃描處理流程參考。


