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

发布者:中华古风最新更新时间:2020-02-04 来源: elecfans关键字:STM32单片机  ADC  DMA配置 手机看文章 扫描二维码
随时随地手机看文章

本文使用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);

}

关键字:STM32单片机  ADC  DMA配置 引用地址:基于STM32单片机的ADC与DMA配置的介绍与使用

上一篇:基于STM32单片机连接射频si4438模块的方案设计
下一篇:STM32单片机的5个时钟源解析

推荐阅读最新更新时间:2024-11-09 20:23

MSP430 中ADC12用法
1.1. 介绍 Figure 4 AD模块图 在处AD时,我们关注的对象有如下几个,参考源、通道、存储地址、时钟、触发方式、精度,速度(200k)。 在上图中我们都可以找到,msp430f149的参考正电源有VRFE+ VeREF+ ,Vcc,同时有对应的负电源。采样通道有16个,存储地址则有对应16个通道,时钟则是有内部时钟及3种时钟源的分频,触发方式有4种。 因此,对于这些特点我们可以实现4种模式,单通道单次采样,单通道多次采样,多通道单次采样,多通道多次采样。 1.2. 相关寄存器 ADC12CTL0:前面8位是对采样保持时间的设置。后8位分别对应8种设置 ADC12CTL1:前4位进行通道选择,
[单片机]
MSP430 中<font color='red'>ADC</font>12用法
MCU ADC如何测量超过VCC的电压?
假设MCU的供电是3.3V,ADC能够测量的电压范围是0-3.3V,如果要测量如电池电压6V的这种场景,该怎么办呢? 很容易能够想到的方法是先进行电阻分压,将高于3.3V的电压分到ADC的量程内进行采集,最后再换算回实际电压。这就引入了一个问题,分压电压该选多大?比如进行1/2分压,是选2个1KΩ串联还是选两个1MΩ串联呢?电阻值能否随意选择呢? 先说结论:电阻不能随意选,首先它不能太大! 以STM32F103为例子,在数据手册中可以看到外部输入阻抗有一个最大值50kΩ的要求。 这个值是由下面的计算公式算出来的, 需要注意的是输入阻抗的最大值并不是固定不变的,不是说只要小于50kΩ就可以,因为它和ADC时钟频率、采样周
[单片机]
MCU <font color='red'>ADC</font>如何测量超过VCC的电压?
N76E003之ADC 多通道采样
首先让我们来看看N76E003单片机的ADC工作方式,从下图中可以看到ADCHS寄存器决定当前使用哪一个通道的ADC。 接下来我们再来看看具体的寄存器含义 接下来就是N76e003库中包含的相关宏定义,可以看到每次使能一个ADC通道时,会先关闭所有通道,再去打开指定对象的通道,之后将对应ADC设置为输入模式 #define Enable_ADC_AIN3 ADCCON0&=0xF0;ADCCON0|=0x03;P06_Input_Mode;AINDIDS=0x00;AINDIDS|=SET_BIT3;ADCCON1|=SET_BIT0 //P06 接下来我们再来看看带隙电压是如何操作的,官方例程没有使用ADC中断,而是
[单片机]
N76E003之<font color='red'>ADC</font> 多通道采样
PIC单片机ADC的简单应用
#include pic.h __CONFIG(0X1F71); #define uchar unsigned char #define uint unsigned int const uchar Tab = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; const uchar Tab1 = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//带小数点的代码 void DisPlay(uchar date1,uchar date2,uchar date3,uchar date4); void DelayMS(uin
[单片机]
51单片机外接ADC0808制作简易电压表
main.c #include reg52.h #define uchar unsigned char #define uint unsigned int sbit Start = P3^0; sbit EOC=P3^1; // sbit OE=P3^2 ; // uchar code table = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//段选 uchar code table_SMG = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//位选 //------------
[单片机]
51单片机外接<font color='red'>ADC</font>0808制作简易电压表
STM32单片机(5) 定时器中断实验
/******************************************************************************* * * 软件功能: 定时器中断实验 * *******************************************************************************/ #include stm32f10x.h #include delay.h void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_
[单片机]
ADC0832转换C程序
#include reg51.h #include intrins.h #define uchar unsigned char #define nop() _nop_(); sbit clk=P1^6; sbit data_i=P1^4; sbit data_o=P1^5; sbit cs=P1^2; //此程序A TO D为CH1 uchar read_adc(void) { uchar i,ch=0; cs=0; clk=1; nop(); nop(); clk=0; nop(); nop(); for (;data_o==1;) { clk=1; nop();
[单片机]
多片高速ADC和DAC在闭环系统中的关键作用
引言 在当今工业自动化应用中,复杂的控制系统代替人工来操作不同的机器和过程。术语 自动化 指其智能化足以制定正确的过程决策从而实现目标结果的系统。我们这里所说的 系统 是指闭环控制系统。这些系统依赖于输入至控制器的传感器数据,提供反馈,控制器据此采取措施。这些措施就是控制器输出的变化。通过确保高性能、高可靠性工业操作,闭环控制系统对于现代化工业4.0工厂的工业自动化和效率至关重要。 本文讨论闭环系统的关键要素,重点关注模/数转换器(ADC)和数/模转换器(DAC)的关键角色。文章介绍多片高速ADC和DAC作为控制系统核心的关键作用和性能优势。最后,我们以MAXREFDES32和MAXREFDES71参考设计为例,介绍隔离电源和
[电源管理]
多片高速<font color='red'>ADC</font>和DAC在闭环系统中的关键作用
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved