历史上的今天
今天是:2025年02月04日(星期二)
2020年02月04日 | 基于STM32单片机的ADC与DMA配置的介绍与使用
2020-02-04 来源:elecfans
本文使用ADC转换电位器输出的电压值,并用DMA模式传输转换的结果,每8次采样转换取平均值,做一个简单的数字滤波。
ADC的详细配置与使用
见之前的日记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官方用户手册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;//转换次数标志位
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();//实现采样输入引脚的配置,配置为模拟输入模式
//。..。..其他
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数据寄存器DR的地址
DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&CONV_RESULTS;//存放转换结果的地址
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++;//在主函数中检查FLAG并惊醒处理
//计算转换数据的个数
if(FLAG》DATANUM-1)
{
FLAG=0;
}
ADC_ClearITPendingBit(USING_ADC,ADC_IT_EOC);
}
//获取转换结果的平均值,做滤波处理
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);
}
史海拾趣
|
原本在公司最后一天了,把工作交接好,就安安稳稳地离职了。大家也算缘分一场,好聚好散吧! 可是,来到公司以后,发现网线被拔走了,电脑也被锁住了,我只能傻傻地坐在电脑前,看看杂志。… 查看全部问答> |
|
The Overlay/Display controller consists of logic for transferring image data from a local bus of the POST Processor or a video buffer located in system memory to an external LCD driver interface. what\'s the meaning of Overlay? ...… 查看全部问答> |
|
各位大神帮帮忙,介绍下你们的学习经验啊! 老师让学DSP,给的是5416的开发箱,学了一段时间感觉没有什么实质性的进展啊,就是熟悉了下CCS软件使用,然后把附带的程序在开发箱上跑了跑看看效果。至于里面的程序啊算法啊,基本不怎么懂啊,迷迷 ...… 查看全部问答> |
|
下是电路,我要的功能很简单,按键第按一次,数码管后两位显示加1,到100后回头,看这样写能不能称作“任务调度”,如果是,那么这种方式比较好处理,因为程序执行的间隔时间都是固定的,但对于有些交互式外设,如AD,DA,LCD,必须从对方读取数据,时 ...… 查看全部问答> |
|
#include #include #define uint unsigned int #define uchar unsigned char #define TX_ADR_WIDTH 5 // 5 uints TX address width #define RX_ADR_WIDTH 5 & ...… 查看全部问答> |




