一、非DMA模式(轉(zhuǎn))
說明:這個(gè)是自己剛做的時(shí)候百度出來的,不是我自己做出來的,因?yàn)楦杏X有用就保存下來做學(xué)習(xí)用,原文鏈接:https://blog.csdn.net/qq_24815615/article/details/70227385,下面第二部分我會(huì)補(bǔ)充自己的DMA模式的方法。
Stm32 ADC 的轉(zhuǎn)換模式還是很靈活,很強(qiáng)大,模式種類很多,那么這也導(dǎo)致很多人使用的時(shí)候沒細(xì)心研究參考手冊的情況下容易混淆。不知道該用哪種方式來實(shí)現(xiàn)自己想要的功能。網(wǎng)上也可以搜到很多資料,但是大部分是針對之前老版本的標(biāo)準(zhǔn)庫的。昨天幫客戶解決這個(gè)問題,正好做個(gè)總結(jié):使用stm32cubeMX配置生成多通道采集的例子。
軟件:STM32Cumebx MDK
硬件:eemaker板(基于stm32F103c8的)
在百度搜索ADC多通道采集,大部分的都是基于采用dma模式才實(shí)現(xiàn)的。而我講的使用非dma方法。首先有幾個(gè)概念要搞清楚:
掃描模式(想采集多通道必須開啟):是一次對所選中的通道進(jìn)行轉(zhuǎn)換,比如開了ch0,ch1,ch4,ch5。Ch0轉(zhuǎn)換完以后就會(huì)自動(dòng)轉(zhuǎn)換通道0,1,4,5直到轉(zhuǎn)換完。但是這種連續(xù)性并不是不能被打斷。這就引入了間斷模式,可以說是對掃描模式的一種補(bǔ)充。它可以把0,1,4,5這四個(gè)通道進(jìn)行分組。可以分成0,1一組,4,5一組。也可以每個(gè)通道配置為一組。這樣每一組轉(zhuǎn)換之前都需要先觸發(fā)一次。
Stm32 ADC的單次模式和連續(xù)模式。這兩中模式的概念是相對應(yīng)的。這里的單次模式并不是指一個(gè)通道。假如你同時(shí)開了ch0,ch1,ch4,ch5這四個(gè)通道。單次模式轉(zhuǎn)換模式下會(huì)把這四個(gè)通道采集一邊就停止了。而連續(xù)模式就是這四個(gè)通道轉(zhuǎn)換完以后再循環(huán)過來再從ch0開始。
另外還有規(guī)則組和注入組的概念,因?yàn)槲疫@個(gè)例程只用到了規(guī)則組,就不多介紹這兩個(gè)概念,想要弄清楚請自行查閱手冊。
下面進(jìn)入正題,配置stm32cubeMX。
先使能幾個(gè)通道,我這里設(shè)置為0、1、4、5.
然后就要配置ADC的參數(shù):
目前經(jīng)過我的測試,要想用非dma和中斷模式只有這樣配置可以正確進(jìn)行多通道轉(zhuǎn)換:掃描模式+單次轉(zhuǎn)換模式+間斷轉(zhuǎn)換模式(每個(gè)間斷組一個(gè)通道)。
分析配置成這樣的模式,掃描模式是在配置為多個(gè)通道必須打開的,stm32cubeMX上也默認(rèn)好了,只能enable。單次轉(zhuǎn)換模式是我不需要不停的去采集每個(gè)通道值,而是把四個(gè)通道采集完以后就讓它停止。這里間斷配置是關(guān)鍵,間斷模式可以讓掃描的四個(gè)通道進(jìn)行分成四個(gè)組,stm32cubeMX參數(shù)里面number of Discontinous Conversions是配置間斷組每個(gè)組有幾個(gè)通道的,這里必須配置為1(否則在獲取ad值得時(shí)候只能讀取到每個(gè)間斷組最后一個(gè)通道)。
生成mdk工程代碼。這時(shí)候還沒有完成,只是實(shí)現(xiàn)了ADC的初始化,需要采集這四個(gè)通道值得函數(shù)還要自己寫。下面這個(gè)是我main函數(shù)的while循環(huán):
for(i=1;i<5;i++)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,0xffff);//等待ADC轉(zhuǎn)換完成
adcBuf[i]=HAL_ADC_GetValue(&hadc1);
printf('------ch:%d--%d-------rn',i,adcBuf[i]);
}
HAL_ADC_Stop(&hadc1);
HAL_Delay(1000);
調(diào)用hal庫接口函數(shù)也需要注意,HAL_ADC_Start一定要放在for里面,即每一個(gè)通道都要觸發(fā)。四個(gè)通道都采集完了,再去調(diào)用HAL_ADC_Stop(&hadc1);結(jié)束本次ADC采集。
二、DMA模式
下面就是我自己的DMA模式的ADC多通道轉(zhuǎn)換了。
先配置一些ADC的基本配置:
引腳
時(shí)鐘
這個(gè)時(shí)鐘可以結(jié)合ADC設(shè)置里配置的采樣時(shí)間結(jié)合計(jì)算出ADC轉(zhuǎn)換的時(shí)間,進(jìn)而換算出頻率。
接著配置DMA
ADC是12位的,其實(shí)DMA只需要用Half Word就可以了,但實(shí)際中HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
該函數(shù)中pData為32位的,也就是DMA必須配置為Word才可以。
配置ADC基本設(shè)置
這里要注意選擇對不同的通道,一開始我就是沒留意到這個(gè)問題,就只有一個(gè)通道 Channel10 在轉(zhuǎn)換,后來查看就是Rank1、2、3全配置成 Channel10 了,所以只有這個(gè)通道在轉(zhuǎn)換,這里這個(gè)提醒大家注意一下。
中斷配置
最后在main文件的main函數(shù)里的while循環(huán)里加入下面代碼
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&AD_DMA, 5); //啟用DMA的ADC轉(zhuǎn)換,AD_DMA 0~3 對應(yīng)ADC 0~3,這里注意最后一個(gè)參數(shù)的大小
printf('AD_DMA_0 = %drn',AD_DMA[0]);
printf('AD_DMA_1 = %drn',AD_DMA[1]);
printf('AD_DMA_2 = %drn',AD_DMA[2]);
HAL_Delay(500);
注意:在while循環(huán)前要加ADC校準(zhǔn)
HAL_ADCEx_Calibration_Start(&hadc1); //AD校準(zhǔn)
串口打印結(jié)果如下,至于怎樣串口打印這里就不多說了,想知道的可以看https://www.cnblogs.com/xingboy/p/9522940.html
補(bǔ)充:使用定時(shí)器與DMA中斷定時(shí)采集
上面只是單純的一直采集的,如果想要用到中斷的話就可以按下面的方式來,ADC配置跟上面說的DMA模式一樣:
先配置定時(shí)器中斷,怎么配置可以參考我的另一個(gè)文章https://www.cnblogs.com/xingboy/p/9897500.html
接著在 main 函數(shù)的 while 循環(huán)前打開定時(shí)器中斷
HAL_TIM_Base_Start_IT(&htim3); //啟動(dòng)定時(shí)器中斷
然后重寫定時(shí)器中斷回調(diào)函數(shù)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&AD_DMA, 5); //啟用DMA的ADC轉(zhuǎn)換,AD_DMA 0~3 對應(yīng)ADC 0~3,這里注意最后一個(gè)參數(shù)的大小
}
這里要注意了,我調(diào)試的時(shí)候發(fā)現(xiàn)HAL_ADC_Start_DMA()函數(shù)中最后一個(gè)參數(shù)的大小起碼要比你定義的AD_DMA數(shù)組大2,不過不能大于2倍,前面的使用這個(gè)函數(shù)的時(shí)候也是要這樣,數(shù)據(jù)太小,會(huì)導(dǎo)致后面的AD通道采集不了數(shù)據(jù),大于2倍程序會(huì)一直卡住,至于為什么這樣子我也還沒搞懂,知道的可以告訴我一聲。【補(bǔ)充:關(guān)于這個(gè)參數(shù)大小的問題,我查了一些資料,一般ADC每次讀進(jìn)來的數(shù)據(jù)都是2個(gè)字節(jié)大小的半字,所以3個(gè)通道讀進(jìn)來的一般一次6個(gè)字節(jié)這樣,4個(gè)通道類似,而這里的最后一個(gè)參數(shù)代表的就是要傳輸?shù)淖止?jié)數(shù),所以這個(gè)參數(shù)要根據(jù)通道個(gè)數(shù)設(shè)置,通常ADC讀入一個(gè)半字,也就是uint16_t,你設(shè)為Word,那么會(huì)去讀一個(gè)uint32_t是4個(gè)字節(jié),其實(shí)這個(gè)我也還不是很懂,不知道對不對的歡迎大家指出】
最后寫DMA中斷服務(wù)函數(shù)
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/*自己添加代碼部分*/
HAL_ADC_Stop_DMA(&hadc1); //停止DMA的ADC轉(zhuǎn)換,AD_DMA 0~3 對應(yīng)ADC 0~3
HAL_TIM_Base_Stop_IT(&htim3);//關(guān)閉定時(shí)器
printf('AD_DMA_0 = %drn',AD_DMA[0]);
printf('AD_DMA_1 = %drn',AD_DMA[1]);
printf('AD_DMA_2 = %drn',AD_DMA[2]);
HAL_TIM_Base_Start_IT(&htim3); //重新開啟定時(shí)器
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
//__HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1)); //清楚標(biāo)志位
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
這樣子,就可以實(shí)現(xiàn)1S采集多少次ADC了,而不用單純控制采樣頻率來控制1S的ADC采集次數(shù)了,個(gè)人覺得單純控制采樣頻率比較難算。
補(bǔ)充:單通ADC采集參考:https://www.cnblogs.com/xingboy/p/10018749.html
補(bǔ)充一個(gè) 4 通道采集 DMA 模式:
定義一個(gè)數(shù)組存放DMA數(shù)據(jù)
uint16_t AD_DMA[4];
直接在 main 函數(shù)的 while 前面開啟 ADC校驗(yàn)跟采集
HAL_ADCEx_Calibration_Start(&hadc1); //AD校準(zhǔn)
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&AD_DMA, 8); //啟用DMA的ADC轉(zhuǎn)換,AD_DMA 0~3 對應(yīng)ADC 0~3
hile函數(shù)里打印DMA的值
printf('AD0 = %drn',AD_DMA[0]);
printf('AD1 = %drn',AD_DMA[1]);
printf('AD2 = %drn',AD_DMA[2]);
printf('AD3 = %drn',AD_DMA[3]);
HAL_Delay(1000);
打印結(jié)果如下
打印結(jié)果如下
上一篇:STM32 實(shí)現(xiàn) 4*4 矩陣鍵盤掃描(HAL庫、標(biāo)準(zhǔn)庫 都適用)
下一篇:STM32 HAL庫使用中斷實(shí)現(xiàn)串口接收不定長數(shù)據(jù)
- 熱門資源推薦
- 熱門放大器推薦
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- 英飛凌穩(wěn)居微控制器領(lǐng)域榜首,鞏固其在全球車用半導(dǎo)體市場的領(lǐng)導(dǎo)地位
- 迅為imx6ull開發(fā)板使用c語言調(diào)用shell命令控制led燈
- 迅為IMX8MM開發(fā)板Android編譯環(huán)境搭建
- 迅為IMX6ULL開發(fā)板NFS服務(wù)器的使用
- 迅為ITOP4412開發(fā)板Qt界面添加圖片
- 迅為IMX6開發(fā)板OTA遠(yuǎn)程升級(jí)-SWUpdata概述和使用
- 迅為IMX6ULL開發(fā)板NFS服務(wù)器的搭建
- 迅為IMX6開發(fā)板Buildroot文件系統(tǒng)4G撥號(hào)上網(wǎng)工具測試
- 實(shí)驗(yàn)分享丨迅為IMX6ULL開發(fā)板點(diǎn)亮第一個(gè)led燈
- 4.1W、3-LED 通用 LED 照明驅(qū)動(dòng)器
- ADV3221-EVALZ,ADV3221 800 MHz、4:1模擬多路復(fù)用器評(píng)估板
- Si477X 系列調(diào)諧器評(píng)估板
- 使用 ON Semiconductor 的 LV8762T 的參考設(shè)計(jì)
- 使用 STMicroelectronics 的 TDA7577LV 的參考設(shè)計(jì)
- LED2472G 24通道帶誤差檢測和增益控制的LED驅(qū)動(dòng)器典型應(yīng)用電路
- 擬輝光管-亞克力燈板工程
- 6S自動(dòng)升降壓平衡充/自動(dòng)升降壓可調(diào)電源
- 使用 ROHM Semiconductor 的 BD46272 的參考設(shè)計(jì)
- FAN2558 180mA低壓CMOS LDO典型應(yīng)用電路
- TE Connectivity在推動(dòng)長期可持續(xù)發(fā)展目標(biāo)方面取得顯著進(jìn)展
- 世索科攜一系列用于半導(dǎo)體制造的先進(jìn)材料亮相Semicon China 2025
- TITAN Haptics助力中國健康產(chǎn)業(yè)的革新
- 汽車線束布置的四大注意事項(xiàng)
- 什么原因?qū)е缕囉秃母吆秃桶l(fā)動(dòng)機(jī)轉(zhuǎn)速高
- 莫仕的電容式背光設(shè)計(jì)在汽車應(yīng)用的五大設(shè)計(jì)挑戰(zhàn)與方案
- 關(guān)于車載Ethernet降噪措施的必要性
- 學(xué)子專區(qū)論壇- ADALM2000實(shí)驗(yàn):脈寬調(diào)制
- 車載以太網(wǎng)的靜噪措施
- 未來自動(dòng)駕駛汽車會(huì)不會(huì)造成道路擁堵?
- EEWorld下載中心大批技術(shù)資料等你來領(lǐng),還有好禮相助
- 有獎(jiǎng)活動(dòng)|Mentor PCB 手冊:《利用自動(dòng)驗(yàn)證消除原理圖設(shè)計(jì)錯(cuò)誤》
- 有獎(jiǎng)學(xué)習(xí) | Multi-Die系統(tǒng)的設(shè)計(jì)和驗(yàn)證很難嗎?教你輕松“拿捏”
- 看MCU精品課程,讓你立馬變身考試達(dá)人!
- 意法半導(dǎo)體工業(yè)峰會(huì)2023 直播結(jié)束
- 關(guān)注EE官方微信,大年初一搶新年紅包
- 有獎(jiǎng)問答:在線尋找英特爾® 視覺加速設(shè)計(jì)“全知”達(dá)人
- 評(píng)論有禮|【Discovery 】走進(jìn)TI毫米波雷達(dá)世界 快速獲得設(shè)計(jì)技能
- 榮耀Play 4T系列發(fā)布,4800萬主攝售價(jià)1199元起
- TRINAMIC公司CEO:專注與專業(yè)是公司成功秘笈
- 正面對決微信?運(yùn)營商力推測“5G消息”背后的盤算
- 東芝重建成敗在中國?半導(dǎo)體存儲(chǔ)器業(yè)務(wù)是關(guān)鍵
- 英特爾提出“智能X效應(yīng)” 數(shù)據(jù)時(shí)代萬物均為計(jì)算機(jī)
- 英特爾 混合架構(gòu)了人工智能芯片
- 日經(jīng):智能手機(jī)外包開發(fā)勢頭迅猛,中國ODM廠商優(yōu)勢顯現(xiàn)
- 國內(nèi)IGBT需求急速上升,中國IDM廠商怎樣搶占先機(jī)
- 國產(chǎn)首臺(tái)套BOG提氦裝置示范項(xiàng)目通過了技術(shù)鑒定
- 智能制造產(chǎn)業(yè),300億元成渝地區(qū)雙城經(jīng)濟(jì)圈發(fā)展基金成立
- 【X-Nucleo深度評(píng)測】——收到板子啦
- 如何獲取存儲(chǔ)卡的總?cè)萘浚捎萌萘亢臀募A的大小
- 關(guān)于登錄TI E2E社區(qū)的問題
- BB方案大結(jié)局之上位機(jī)軟件實(shí)現(xiàn)篇——基于BB及FPGA的DAQ及DDS設(shè)計(jì)與實(shí)現(xiàn)
- 單片機(jī)與對講機(jī)無線能通電!!
- 這個(gè)電容起到什么樣的作用呢?
- STM8S208內(nèi)部EEProm數(shù)據(jù)丟失
- u-boot 匯編疑問
- 【CN0209】適合過程控制應(yīng)用的完全可編程通用模擬前端
- 關(guān)于Wince中SDK的編譯問題