ADC即模數轉換器,能把模擬量(電壓)轉換為數字量。
這一節我們講講stm32的ADC用法,stm32自帶的ADC有四種用法:輪詢、中斷、DMA、定時器觸發。
1)ADC輪詢的用法
我們在之前的串口中斷工程上修改,以便於打印數值查看。
使用cubemx打開串口中斷的工程,然后另存為ADC工程,增加如下設置,啟用ADC及其中斷:
可以看到選擇ADC1,勾選IN0后,右側PA0引腳自動配置成了ADC輸入;在NVIC選項卡下勾選ADC中斷使能,這樣我們可以在這個工程里演示輪詢和中斷模式。
到時鍾設置選項卡下,更改ADC時鍾,因為我們使用的主時鍾是72M,ADC的時鍾不能太高,所以要分頻,如下是分到12M:
然后生成工程代碼,在keil中打開,我們先試驗輪詢模式,即軟件開始ADC轉換后,一直等到轉換完成后,才向后執行,代碼如下:
這個代碼在初始化ADC之后執行一次校准(不執行這一步也可以,但精度可能會低一些);然后就可以使用ADC輪詢轉換了,只需要三步:啟動轉換、等待轉換完成、讀取轉換數據,即可完成一次ADC轉換。
這里將轉換結果通過串口發出來了,可以看到右下角的串口調試助手的結果顯示。Stm32的adc是12位,這里拆成兩個字節發送。
2)ADC中斷用法
仍然使用上述代碼工程,添加中斷方式的代碼:
在主循環前,啟動一次中斷轉換;然后在主循環中檢查標志位,是否已經完成轉換(ADC轉換完成中斷);如果已經轉換完成,則讀取結果,上傳;再啟動下一次中斷轉換:
回調函數中,只修改標志位,使得主循環中可以檢測到已發生了轉換完成中斷:
注意上面的主函數里,使用了一個100ms的延時;主要是因為stm32的ADC轉換是很快的,如果不使用延時,會有大量數據通過串口上傳,不方便觀察。
3)ADC的DMA多通道轉換
仍然使用上面的cubemx工程,這次我們配置多個AD通道,使用DMA連續傳輸。
如下圖,選擇IN0和IN1兩個通道,並啟用DMA循環模式:
由於ad值為12位,所以這里DMA傳輸半字就可以了;當然也可以傳輸整個字。
然后設置ADC的通道,如下圖:
解釋一下需要修改的地方:
scan conversion mode是使能掃描模式,因為我們開了兩個通道IN0和IN1,兩個通道都要有轉換;
continuous conversion mode是設置連續轉換,即一次完成以后,自動進行下一次轉換;
Number of conversion設置為2,因為我們有兩個通道;
兩個Rank下面設置通道號,因為我們有兩個通道IN0和IN1,所以一個rank下選通道0,另一個rank下選擇通道1。
Sampling time采樣時間,如果資源允許可以選長一點的時間,轉換結果更准確。
然后就可以生成工程代碼了。
在keil中打開工程,主函數中添加代碼如下:
注意這里的HAL_ADC_Start_DMA(&hadc1, ADC_Value, 16); 最后這個參數16,表示的是DMA搬移數據的次數;向ADC_Value及其之后的地址搬移16個數據;我們這里設置了2個通道,所以從首地址開始填入的是交替的兩個通道的數據:ADC0、ADC1、ADC0、ADC1…一共16個數。
這里設置為16,是因為太小的數值很快就會執行完一個循環,產生DMA傳輸中斷,時間太短的話會頻繁產生中斷,導致一直在中斷中執行,沒有時間執行主循環中的語句。這里是增加搬移數據的次數;也可以設置AD采樣時間長一些,那么每次的轉換時間變長,也不會產生過多的中斷。
另外這里的校准函數一定要放在啟動ADC、DMA之前,否則會占用一個通道,之后的AD通道順序會有問題。
4)定時器觸發ADC采樣
顧名思義,就是由定時器設定時間,到點就啟動ADC采樣,這樣可以精確控制采樣率。
首先設置定時器的計時參數,這里設置為1s(可以不開啟定時器中斷):
ADC的設置中,要關閉連續轉換模式,並且設置為定時器觸發:
這里如果連續轉換不關閉,會自動連續運行,不受定時器觸發的控制。所以要disable。
最后,還要開啟ADC中斷。
設置好之后就可以生成工程代碼了。
在keil中打開工程,重寫ADC中斷的回調函數,以指示ADC轉換好:
main函數中添加如下代碼,檢測是否轉換好,並讀取AD值回傳:
下載到板子運行,可以看到每1s輸出一個ad值,說明實現了定時器觸發adc轉換的功能。
好了,這一節的內容基本講完了。
歡迎關注我的公眾號,可留言“資料”獲取相關資料和軟件: