娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

STM32 ADC多通道轉(zhuǎn)換DMA模式與非DMA模式兩種方法(HAL庫)

發(fā)布者:EuphoricMelody最新更新時(shí)間:2025-02-18 來源: cnblogs關(guān)鍵字:STM32  ADC  多通道轉(zhuǎn)換  DMA模式  非DMA模式  HAL庫 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

一、非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。

Stm32cubeMx配置ADC多通道采集

先使能幾個(gè)通道,我這里設(shè)置為0、1、4、5.

然后就要配置ADC的參數(shù):

Stm32cubeMx配置ADC多通道采集

  目前經(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é)果如下

    


關(guān)鍵字:STM32  ADC  多通道轉(zhuǎn)換  DMA模式  非DMA模式  HAL庫 引用地址:STM32 ADC多通道轉(zhuǎn)換DMA模式與非DMA模式兩種方法(HAL庫)

上一篇:STM32 實(shí)現(xiàn) 4*4 矩陣鍵盤掃描(HAL庫、標(biāo)準(zhǔn)庫 都適用)
下一篇:STM32 HAL庫使用中斷實(shí)現(xiàn)串口接收不定長數(shù)據(jù)

0
添点儿料...
无论热点新闻、行业分析、技术干货……
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 洱源县| 全椒县| 通州区| 磐石市| 眉山市| 藁城市| 离岛区| 时尚| 华容县| 新巴尔虎右旗| 政和县| 广南县| 芷江| 鹤岗市| 子长县| 防城港市| 沙湾县| 峨边| 镇平县| 都安| 镇坪县| 景洪市| 彭水| 封丘县| 黄梅县| 惠州市| 静乐县| 黄大仙区| 清涧县| 北辰区| 浑源县| 绥芬河市| 广丰县| 锡林浩特市| 武功县| 石景山区| 长宁区| 铜鼓县| 盐源县| 蕲春县| 海口市|