STM32使用HAL庫實現ADC單通道轉換

2022-06-27 04:57:09 字數 3420 閱讀 5855

好了,下面就開始說明怎麼用stm32cubemx實現adc單通道轉換吧。

利用中斷模式

1、配置adc引腳

2、開定時跟串列埠,定時器用來定時開啟adc轉換,這樣可以達到1s內控制adc轉換次數的目的,不過有個限制,這裡樣子控制adc轉換次數的話,如果取樣次數多,配置adc取樣速度時一定要夠  快,正常配置adc的取樣頻率可以通過改變其取樣速度來設定的,這裡我是為了方便處理,就直接用定時器去開啟了;而串列埠則是列印轉換後的電壓用的。

3、配置時鐘

4、配置adc設定

5、開啟中斷模式

6、串列埠配置預設即可

7、定時器配置,定時器配置的是進入定時器中斷的頻率,定時時間可以根據這個頻率換算出來,這裡定時器的頻率 = 72m / 72 /1000 =1000hz,所以定時時間為 t = 1s/f = 1s/1000 = 1ms,所以我這裡配置定時為1ms。

8、基本配置我們完成了,現在我們生成工程用keil5開啟

9、開啟工程,我們現在進入**部分

這裡我們只需要重寫定時器中斷**函式跟,adc轉換**中斷函式即可。在main檔案裡新增這下面這兩個函式

void hal_tim_periodelapsedcallback(tim_handletypedef *htim)    //

定時器中斷**

void hal_adc_convcpltcallback(adc_handletypedef* hadc) //

adc轉換完成**

到這裡就完成單通道adc中斷轉換的所有步驟啦,通過串列埠助手實測轉換結果誤差為0.0008v。

至於串列埠檢視資訊列印輸出重定向可以看我這篇文章:

不使用中斷模式

不使用中斷模式的情況下跟使用中斷的類似的,首先配置的過程中不需要開啟中斷,至於定時器開不開看個人需要,想利用定時器定時採集的可以開,不想的不用開,其他的配置一樣。生成**後,在main檔案的main函式中的while迴圈裡新增下面**:

/*

user code begin 3

*/for(char n=0;n<22;n++)

}max=value[0

]; min=value[0

];

for(char n=0;n<22;n++)//

取最大值、最小值

printf(

"pc0 adc : %.4f \r\n

",(float)((ad_value -max-min)/20)*(3.1/4096

));

ad_tr=(float)((ad_value -max-min)/20)*(3.1/4096); //

這裡我做了個去掉最大最小值後,取均值的軟體濾波

ad_value=0;

這裡面的一些變數就你們自己去定義了,我就不列出來了,實測誤差在0.001v以內。

補充注意事項:

1、adc初始化後要進行校準,使用下面函式校準,可以放在adc初始化函式後面校準

hal_adcex_calibration_start(&hadc2);    //

ad校準

2、傳入adc的電壓不可以超過3.3v,就是不可以超過你的參考電壓,不然結果不准,還有可能燒壞adc引腳

使用dma模式【**

再次寫寫stm32cubemx中ad採集的問題,這次不用while裡面的查詢,也不用中斷取樣了,直接用dma

先說下用dma的好處:無論是中斷取樣還是查詢取樣,都需要在主程式中占用好多時間出來,嗯,你可以這樣理解

那種取樣都需要呼叫hal_adc_getvalue()這個函式,,,就是要取得轉換後的值,中斷還好點,要是查詢的話,有可能會丟失資料啊. 用dma就可以避免了

dma用的事匯流排時間,無線cpu干預,額,這種說法貌似有點問題.管它呢

在ad轉換結束的時候自動連線你準備訪問的變數的位址,資料一步到位.額,省了多少事..

使用stm32cubemx對ad的配置

然後對她的dma配置,並開啟dma的中斷

然後生成**吧

開啟main.c檔案,在這個地方新增**

/[i] user code begin 0 [/i]/__io uint16_t uhadcxconvertedvalue = 0

;/[i] user code end 0 [/i]/

在main()函式裡新增

/[i] user code begin 2 [/i]/hal_adc_start_dma(&hadc1, (uint32_t*)&uhadcxconvertedvalue, 1

); /[i] user code end 2 [/i]/

意思是開啟dma傳輸,傳送乙個字的資料到uhadcxconvertedvalue這個變數裡面

然後再檔案的末尾處新增

/[i] user code begin 4 [/i]/

void hal_adc_convcpltcallback(adc_handletypedef*adchandle)

/[i] user code end 4 [/i]/

意思是ad轉換完成呼叫這個函式,函式裡使能led

也許,你會問,為毛是hal_adc_convcpltcallback()這個函式啊,這個函式不是當開啟ad的中斷的時候才呼叫的嗎?

嗯,對,這個函式是這樣的,但是你仔細去分析下開啟ad的dma中斷函式裡面,就會發現這個函式也在啊

如下圖.進入hal_adc_start_dma函式裡面,看到

在進入到圖中的adc_dmaconvcplt函式裡面看到

ok,疑問解決,

以後用到ad就可以直接呼叫這個call了,不要糾結了.

STM32的HAL庫初體會

最近有個小專案,通過串列埠發命令來控制電路板上繼電器動作。板子上的晶元是stm32f030。這款晶元以前用過一次,但是還是不熟悉。選它的原因是功能夠用,而且便宜,比經常用的stm32f103便宜好多。後來一想,可以用hal庫試試。然後在cube軟體上稍微操作一下,生成的 直接能跑,串列埠收發資料都正...

STM32使用HAL庫寫串列埠接收中斷

硬體 正點原子戰艦開發板 stm32f103zet6 軟體 mdk5,stm32cubemx 下面講解使用hal庫配置串列埠1,使串列埠1可以使用中斷接收位元組並原樣返回。uint8 t uart1 rxbuf 10 用於存放接收到的資料 void mx usart1 uart init void ...

STM32使用HAL串列埠封裝printf

自己封裝乙個類似 printf 的函式 前提是已經可以實現串列埠傳送了 include include include uint32 t uart strlen uint8 t str return cnt void usart printf uint8 t usartport,char fmt,v...