本文使用ADC轉(zhuǎn)換電位器輸出的電壓值,并用DMA模式傳輸轉(zhuǎn)換的結(jié)果,每8次采樣轉(zhuǎn)換取平均值,做一個(gè)簡單的數(shù)字濾波。
ADC的詳細(xì)配置與使用
見之前的日記STM32中ADC的使用,只是最后增加一步配置DMA:
DMA for ADC channels features configuration
? To enable the DMA mode for ADC channels group, use the ADC_DMACmd()function.
? To configure the DMA transfer request, use ADC_DMAConfig() function.
DMA的配置
(摘自STM32F3官方用戶手冊(cè)UM1581User manual)
1. Enable The DMA controller clock using
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE) function for DMA1 orusing RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE) function forDMA2.
2. Enable and configure the peripheral to be connected to the DMA channel (except forinternal SRAM / FLASH memories: no initialization is necessary)。
3. For a given Channel, program the Source and Destination addresses, the transferDirection, the Buffer Size, the Peripheral and Memory Incrementation mode and Data
Size, the Circular or Normal mode, the channel transfer Priority and the Memory-to-Memory transfer mode (if needed) using the DMA_Init() function.
4. Enable the NVIC and the corresponding interrupt(s) using the function
DMA_ITConfig() if you need to use DMA interrupts.
5. Enable the DMA channel using the DMA_Cmd() function.
6. Activate the needed channel Request using PPP_DMACmd() function for any PPPperipheral except internal SRAM and FLASH (ie. SPI, USART 。..) The functionallowing this operation is provided in each PPP peripheral driver (ie. SPI_DMACmd forSPI peripheral)。
7. Optionally, you can configure the number of data to be transferred when the channel
is disabled (ie. after each Transfer Complete event or when a Transfer Error occurs)using the function DMA_SetCurrDataCounter()。 And you can get the number ofremaining data to be transferred using the function DMA_GetCurrDataCounter() at runtime (when the DMA channel is enabled and running)。
8. To control DMA events you can use one of the following two methods:
a. Check on DMA channel flags using the function DMA_GetFlagStatus()。
b. Use DMA interrupts through the function DMA_ITConfig() at initialization phaseand DMA_GetITStatus() function into interrupt routines in communication phase.After checking on a flag you should clear it using DMA_ClearFlag() function. Andafter checking on an interrupt event you should clear it usingDMA_ClearITPendingBit()function.
重要代碼:
#include“ADC_DMA.h”
#defineDATANUM8
uint8_tFLAG=0;//轉(zhuǎn)換次數(shù)標(biāo)志位
uint16_tCONV_RESULTS[DATANUM];
voidADC_Config(void)
{
ADC_InitTypeDefADC_InitStructure;
ADC_CommonInitTypeDefADC_CommonInitStructure;
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12,ENABLE);
//GPIO_Config();//實(shí)現(xiàn)采樣輸入引腳的配置,配置為模擬輸入模式
//。..。..其他
ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_2;
ADC_CommonInitStructure.ADC_DMAMode=ADC_DMAMode_Circular;
//。..。..。其他
ADC_CommonInit(USING_ADC,&ADC_CommonInitStructure);
//ADCInit,ADC_Init(USING_ADC,&ADC_InitStructure);
ADC_ITConfig(USING_ADC,ADC_IT_EOC,ENABLE);//開中斷
ADC_DMAConfig(USING_ADC,ADC_DMAMode_Circular);//配置ADC_DMA,非常重要
ADC_DMACmd(USING_ADC,ENABLE);//打開ADC_DMA
DMA_Config();
ADC_Cmd(USING_ADC,ENABLE);
while(!ADC_GetFlagStatus(USING_ADC,ADC_FLAG_RDY));
ADC_StartConversion(USING_ADC);
}
voidGPIO_Config(void)
{
//。..。..。
//。..。..
}
voidDMA_Config(void)
{
DMA_InitTypeDefDMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr=ADC_DATA_ADDR;//ADC數(shù)據(jù)寄存器DR的地址
DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&CONV_RESULTS;//存放轉(zhuǎn)換結(jié)果的地址
DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize=DATANUM;
//。..。.
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
DMA_Cmd(DMA1_Channel1,ENABLE);
}
voidADC1_2_IRQHandler(void)
{
FLAG++;//在主函數(shù)中檢查FLAG并驚醒處理
//計(jì)算轉(zhuǎn)換數(shù)據(jù)的個(gè)數(shù)
if(FLAG》DATANUM-1)
{
FLAG=0;
}
ADC_ClearITPendingBit(USING_ADC,ADC_IT_EOC);
}
//獲取轉(zhuǎn)換結(jié)果的平均值,做濾波處理
uint16_tGetAverage(void)
{
u8i=0;
u16average=0;
u32sum=0,voltage=0;
for(i=0;i
{
sum+=CONV_RESULTS[i];
}
average=sum/DATANUM;
voltage=average*3300/0xFFF;
returnvoltage;
}
//配置中斷
voidNVIC_Config(void)
{
NVIC_InitTypeDefNVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=ADC1_IRQn;
//。..。..。.
NVIC_Init(&NVIC_InitStruct);
}
評(píng)論
查看更多