好了,下面就開始說明怎麼用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) //到這裡就完成單通道adc中斷轉換的所有步驟啦,通過串列埠助手實測轉換結果誤差為0.0008v。定時器中斷**
void hal_adc_convcpltcallback(adc_handletypedef* hadc) //
adc轉換完成**
至於串列埠檢視資訊列印輸出重定向可以看我這篇文章:
不使用中斷模式
不使用中斷模式的情況下跟使用中斷的類似的,首先配置的過程中不需要開啟中斷,至於定時器開不開看個人需要,想利用定時器定時採集的可以開,不想的不用開,其他的配置一樣。生成**後,在main檔案的main函式中的while迴圈裡新增下面**:
/*這裡面的一些變數就你們自己去定義了,我就不列出來了,實測誤差在0.001v以內。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;
補充注意事項:
1、adc初始化後要進行校準,使用下面函式校準,可以放在adc初始化函式後面校準
hal_adcex_calibration_start(&hadc2); //2、傳入adc的電壓不可以超過3.3v,就是不可以超過你的參考電壓,不然結果不准,還有可能燒壞adc引腳ad校準
使用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在main()函式裡新增;/[i] user code end 0 [/i]/
/[i] user code begin 2 [/i]/hal_adc_start_dma(&hadc1, (uint32_t*)&uhadcxconvertedvalue, 1意思是開啟dma傳輸,傳送乙個字的資料到uhadcxconvertedvalue這個變數裡面); /[i] user code end 2 [/i]/
然後再檔案的末尾處新增
/[i] user code begin 4 [/i]/意思是ad轉換完成呼叫這個函式,函式裡使能ledvoid hal_adc_convcpltcallback(adc_handletypedef*adchandle)
/[i] user code end 4 [/i]/
也許,你會問,為毛是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...