本文針對Hi3518EV200平臺處理器,通過ADC單次採樣方式,實現對多通道(1~4通道)ADC進行採樣控制。本文僅僅是對Hi3518EV200晶元ADC的用法的介紹,不涉及ADC具體的工作原理、轉換原理等細節內容。 ...
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採樣支持連續掃描處理
連續掃描處理過程在驗證時沒有得到想要的效果,在這裡不便多說,下麵僅列出文檔中連續掃描處理流程參考。
Over!