在嵌入式產(chǎn)品中有時候需要實現(xiàn)對外部的模擬量進行采樣處理和記錄,而這就需要使用到ADC功能,將外部的模擬量轉換成數(shù)字量。而在復雜的嵌入式產(chǎn)品中,往往需要使用多路AD采樣,例如在智能家居產(chǎn)品,電池電量檢測,熱敏溫度傳感器,煙霧傳感器,氣敏傳感器等都是可以使用ADC來實現(xiàn)采樣的。在本文章,將會介紹如何通過意法的STM32 MCU實現(xiàn)用DMA完成多通道的AD采樣功能。
什么叫ADC
ADC即模擬數(shù)字轉換器(英語:Analog-to-digital converter)是用于將模擬形式的連續(xù)信號轉換為數(shù)字形式的離散信號的一類設備。一個模擬數(shù)字轉換器可以提供信號用于測量。與之相對的設備成為數(shù)字模擬轉換器。
影響AD采樣的因素有哪些
分辨率
分辨率指的是ADC的位數(shù),例如STM32F103MCU的內部ADC的分辨率是12位,那么它所采樣的結果就在0-4096之間。
最小采樣單位值
根據(jù)基準電壓和參考電壓的不同,其值也是不同的,例如在基準電壓為3.3V,參考電壓最低為0V,最高為3.3V,采樣分辨率位12位的嵌入式系統(tǒng)中,則ADC的最小量程單位則為:3.3V/4096 = 0.00080566。
量程
在無負電壓的嵌入式系統(tǒng)中,量程范圍0-基準電壓。
電源噪音
電源質量直接影響了AD采樣的正確性和穩(wěn)定性,如果條件滿足,建議使用線性穩(wěn)壓源,若是使用開關電源的話,需要在VDDA模擬電源輸入和參考電壓輸入接一個線性穩(wěn)壓管,同時要注意減小PCB板布局走線中結電容對采樣電路的影響。
STM32F103 ADC主要特性
12-位分辨率
轉換結束,注入轉換結束和發(fā)生模擬看門狗事件時產(chǎn)生中斷
單次和連續(xù)轉換模式
從通道0到通道n的自動掃描模式
自校準
帶內嵌數(shù)據(jù)一致的數(shù)據(jù)對齊
通道之間采樣間隔可編程
規(guī)則轉換和注入轉換均有外部觸發(fā)選項
間斷模式
雙重模式(帶2個或以上ADC的器件)
ADC轉換時間:─ STM32F103xx 增強型產(chǎn)品: ADC 時鐘為 56MHz 時為 1μs(ADC 時鐘為 72MHz 為 1.17μs)─ STM32F101xx 基本型產(chǎn)品: ADC 時鐘為 28MHz 時為 1μs(ADC 時鐘為 36MHz 為 1.55μs)─ STM32F102xxUSB 型產(chǎn)品: ADC 時鐘為 48MHz 時為 1.2μs
ADC供電要求: 2.4V到3.6V
ADC輸入范圍: VREF- ≤ VIN ≤ VREF+● 規(guī)則通道轉換期間有DMA請求產(chǎn)生。
DMA簡介
直接存儲器存取用來提供在外設和存儲器之間或者存儲器和存儲器之間的高速數(shù)據(jù)傳輸。無須CPU任何干預,通過DMA數(shù)據(jù)可以快速地移動。這就節(jié)省了CPU的資源來做其他操作。
STM32F103 DMA主要特性
12個 獨立的可配置的通道(請求)DMA1有7個通道, DMA2有5個通道
每個通道都直接連接專用的硬件DMA請求,每個通道都同樣支持軟件觸發(fā)。這些功能通過軟件來配置。
在七個請求間的優(yōu)先權可以通過軟件編程設置(共有四級:很高、高、中等和低),假如在相等優(yōu)先權時由硬件決定(請求0優(yōu)先于請求1,依此類推) 。
獨立的源和目標數(shù)據(jù)區(qū)的傳輸寬度(字節(jié)、半字、全字),模擬打包和拆包的過程。源和目標地址必須按數(shù)據(jù)傳輸寬度對齊。
支持循環(huán)的緩沖器管理
每個通道都有3個事件標志(DMA 半傳輸, DMA傳輸完成和DMA傳輸出錯),這3個事件標志邏輯或成為一個單獨的中斷請求。
存儲器和存儲器間的傳輸
外設和存儲器,存儲器和外設的傳輸
閃存、 SRAM、外設的SRAM、 APB1 APB2和AHB外設均可作為訪問的源和目標。
可編程的數(shù)據(jù)傳輸數(shù)目:最大為65536
如何實現(xiàn)多通道AD采樣的DMA傳輸
ADC功能引腳配置
void ADC_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable DMA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
//配置模擬通道輸入引腳
GPIO_InitStructure.GPIO_Pin = ADC1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//配置引腳為模擬輸入模式
GPIO_Init(ADC1_GPIOX, &GPIO_InitStructure); // 輸入時不用設置速率
//配置模擬通道輸入引腳
GPIO_InitStructure.GPIO_Pin = ADC2_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//配置引腳為模擬輸入模式
GPIO_Init(ADC2_GPIOX, &GPIO_InitStructure); // 輸入時不用設置速率
//配置模擬通道輸入引腳
GPIO_InitStructure.GPIO_Pin = ADC3_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//配置引腳為模擬輸入模式
GPIO_Init(ADC3_GPIOX, &GPIO_InitStructure); // 輸入時不用設置速率
GPIO_InitStructure.GPIO_Pin = ADC4_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(ADC4_GPIOX,&GPIO_InitStructure);
}
配置多通道ADC功能
void ADC_Multichannel_Config(void){ADC_InitTypeDef ADC_InitStructure; ADC_DeInit(ADC1); //將外設 ADC1 的全部寄存器重設為缺省值 /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式:ADC1和ADC2工作在獨立模式
ADC_InitStructure.ADC_ScanConvMode =ENABLE; //模數(shù)轉換工作在掃描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模數(shù)轉換工作在連續(xù)轉換模式
ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None; //外部觸發(fā)轉換關閉
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC數(shù)據(jù)右對齊
ADC_InitStructure.ADC_NbrOfChannel = M; //順序進行規(guī)則轉換的ADC通道的數(shù)目
ADC_Init(ADC1, &ADC_InitStructure); //根據(jù)ADC_InitStruct中指定的參數(shù)初始化外設ADCx的寄存器 /* ADC1 regular channel11 configuration */ //設置指定ADC的規(guī)則組通道,設置它們的轉化順序和采樣時間 //ADC1,ADC通道x,規(guī)則采樣順序值為y,采樣時間為239.5周期ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1,ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2,ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_4,3,ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_8,4,ADC_SampleTime_239Cycles5);
// 開啟ADC的DMA支持(要實現(xiàn)DMA功能,還需獨立配置DMA通道等參數(shù))
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
/* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); //復位指定的ADC1的校準寄存器 /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); //復位指定的ADC1的校準寄存器
/* Start ADC1 calibaration */ADC_StartCalibration(ADC1); //開始指定ADC1的校準狀態(tài)
/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1)); //獲取指定ADC1的校準程序,設置狀態(tài)則等待}
配置DMA通道,使能ADC轉換結果從外設到內存
void DMA_Configuration(void) {/* ADC1 DMA1 Channel Config */
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA傳輸
DMA_DeInit(DMA1_Channel1); //將DMA的通道1寄存器重設為缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //DMA外設ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_Value; //DMA內存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //內存作為數(shù)據(jù)傳輸?shù)哪康牡?/p>
DMA_InitStructure.DMA_BufferSize = N*M; //DMA通道的DMA緩存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設地址寄存器不變
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內存地址寄存器遞增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //數(shù)據(jù)位寬度16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //數(shù)據(jù)寬度16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循環(huán)緩存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x擁有高優(yōu)先級
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x沒有設置為內存到內存
DMA_Init(DMA1_Channel1, &DMA_InitStructure); //根據(jù)DMA_InitStruct中指定的參數(shù)DMA通道
開始啟動ADC轉換功能
void ADC_Start(void){ ADC_GPIO_Config(); ADC_Multichannel_Config(); DMA_Configuration(); ADC_SoftwareStartConvCmd(ADC1, ENABLE); //開始ADC轉換 DMA_Cmd(DMA1_Channel1, ENABLE); //啟動DMA通道}
使用冒泡排序法,對各通道的連續(xù)五次采樣結果取平均值
u16 ADC1_AveragValue(u16 ADC_Value[N][M]){ u16 ADC1_Value[N]; u8 i = 0; u8 j = 0; u16 temp = 0; u16 ADC1_Av = 0; for (i = 0;i < N;i++) { ADC1_Value[i] = ADC_Value[i][0]; } /*冒泡排序*/ for(i=0; i
轉換采樣結果
(float)ADC1_AveragValue(ADC_Value)/4096*3.3)
-
mcu
+關注
關注
146文章
16885瀏覽量
349922 -
STM32
+關注
關注
2264文章
10854瀏覽量
354299 -
dma
+關注
關注
3文章
556瀏覽量
100347 -
AD采樣
+關注
關注
0文章
23瀏覽量
15931
原文標題:STM32如何實現(xiàn)用DMA完成多通道的AD采樣功能?看完這篇徹底懂了~
文章出處:【微信號:Mouser-Community,微信公眾號:貿(mào)澤電子設計圈】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論