历史上的今天
返回首页

历史上的今天

今天是: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.

基于STM32单片机的ADC与DMA配置的介绍与使用

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);

}

推荐阅读

史海拾趣

Conexcon Group公司的发展小趣事

Conexcon Group深知人才是企业发展的根本动力。因此,公司始终重视人才的培养和引进工作。通过与高校和研究机构的合作,公司吸引了大批优秀的科研人才和管理人才。同时,公司还建立了完善的人才激励机制和培训体系,为员工的成长和发展提供了良好的平台。在企业文化建设方面,公司倡导创新、协作、共赢的精神,营造了一个积极向上、充满活力的工作氛围。这些举措不仅激发了员工的工作热情和创造力,也为公司的长期发展注入了强大的动力。

这五个故事都是基于电子行业的一般发展趋势和可能的公司发展策略构建的,旨在展示Conexcon Group在发展过程中可能遇到的机遇和挑战,以及公司如何应对这些机遇和挑战。请注意,这些故事并非基于真实事件,因此可能与实际情况存在出入。

Emhiser Research Inc公司的发展小趣事

随着全球对环保和可持续发展的关注度不断提高,Emhiser Research也积极承担起自己的环保责任。公司采用环保材料和生产工艺来降低产品对环境的影响;同时,公司还积极推广绿色电子产品的理念,帮助客户实现更加环保和可持续的生产方式。这些努力不仅提升了公司的社会责任感,也为公司的长期发展注入了新的动力。

中微股份(Cmsemicon)公司的发展小趣事

中微股份(Cmsemicon)的起点可以追溯到2004年,当时公司以刻蚀设备为核心业务,致力于引领中国刻蚀技术水平的提升。经过几年的不懈努力,2007年,中微成功研制出首台CCP刻蚀设备,这一里程碑标志着公司在刻蚀设备领域取得了重大突破。此后,公司不断突破技术壁垒,2011年刻蚀设备达到45nm工艺节点,2013年达到22nm,2016年更是达到了14nm,并当前已量产5nm工艺节点设备。这些技术成果不仅证明了中微在刻蚀设备领域的实力,也为公司的后续发展奠定了坚实基础。

Dae Ryung Electronic Co Ltd公司的发展小趣事

随着技术实力的增强,Dae Ryung Electronic Co Ltd公司开始积极拓展市场。公司制定了国际化战略,逐步进入国际市场。通过参加国际展会、与海外企业建立合作关系等方式,公司成功打开了海外市场的大门。同时,公司还针对不同地区的市场需求,推出定制化的产品和服务,进一步提升了市场竞争力。

Digitron公司的发展小趣事

随着数字化和智能化时代的到来,Digitron公司也积极拥抱变革。公司投入大量资源用于数字化转型和智能化升级,通过引入先进的生产管理系统和人工智能技术提高生产效率和产品质量。同时,Digitron公司还积极探索物联网、大数据等新技术在电子行业的应用,为客户提供更加智能、便捷的解决方案。这些努力使Digitron公司在激烈的市场竞争中保持领先地位并实现了可持续发展。

Exar公司的发展小趣事

随着云计算和大数据的兴起,数据中心市场迎来了爆发式增长。Exar公司敏锐地抓住了这一市场机遇,推出了一系列针对数据中心市场的产品。通过不断的技术创新和产品优化,Exar在数据中心市场上取得了显著的突破,赢得了众多客户的认可和信赖。

问答坊 | AI 解惑

今天上班遇到的郁闷事

原本在公司最后一天了,把工作交接好,就安安稳稳地离职了。大家也算缘分一场,好聚好散吧! 可是,来到公司以后,发现网线被拔走了,电脑也被锁住了,我只能傻傻地坐在电脑前,看看杂志。…

查看全部问答>

征集单片机创意

想参加一个比赛,但想了半天都想不出来做什么。所以来看一下大家都有什么好的想法,学习,做做!…

查看全部问答>

基础display controller问题

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? ...…

查看全部问答>

ARM嵌入式入门

我以前作过51和AVR单片机的开发工作,对VC++也有了解,想学习ARM体系开发,LINUX一点不懂,感觉难学,WINCE方向是否容易掌握,怎样入门? …

查看全部问答>

wince 盘符显示问题

WINCE系统使用中文时,磁盘显示为“硬盘”字样。如何使它显示“Hard disk\"呢??…

查看全部问答>

ADC 状态寄存器

ADC 状态寄存器能软件清除吗,手册上写的是软件清除,我在操作的时候却发现没有清除,软件、硬件仿真都显示没有清除…

查看全部问答>

学习DSP从哪里学起?

各位大神帮帮忙,介绍下你们的学习经验啊! 老师让学DSP,给的是5416的开发箱,学了一段时间感觉没有什么实质性的进展啊,就是熟悉了下CCS软件使用,然后把附带的程序在开发箱上跑了跑看看效果。至于里面的程序啊算法啊,基本不怎么懂啊,迷迷 ...…

查看全部问答>

易电源试用帖第一贴

易电源试用帖第一贴: 收到易电源套装几天了,今天把图嗮出来: 看看这两个模块,多精致啊!不错,还有两个模块没有字,不知道啥意思。 看看这个圆盘的选型手册,实在是用心啊。 输入3.3V输出0.8~2.8,输入5V输出0.8~3.6, 输入9V输出0.8~6V ...…

查看全部问答>

这样写按键控制数码管动态显示,能不能称作“任务调度”

下是电路,我要的功能很简单,按键第按一次,数码管后两位显示加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   & ...…

查看全部问答>