历史上的今天
返回首页

历史上的今天

今天是:2024年10月20日(星期日)

正在发生

2018年10月20日 | STM32学习——AD单通道与多通道转换(DMA)

2018-10-20 来源:eefocus

第三章AD转换

本章的内容分两部分,第一是AD的单通道转换,第二是AD的多通道转换。首先先将单通道转换。

 STM32中自带的AD最大的转换频率是14MHZ,共有16个转换通道,每个转换通道对应的管脚如下表所示。

管脚名

默认复用功能

PF6

ADC3_IN4

PF7

ADC3_IN5

PF8

ADC3_IN6

PF9

ADC3_IN7

PF10

ADC3_IN8

PC0

ADC123_IN10

PC1

ADC123_IN11

PC2

ADC123_IN12

PC3

ADC123_IN13

PA3

ADC123_IN3

PA6

ADC12_IN6

PA7

ADC12_IN7

PC4

ADC12_IN14

PC5

ADC12_IN15

PB0

ADC12_IN8

PB1

ADC12_IN9

注:ADC123_IN10表明PC0管脚可以作为AD1,AD2,AD3的第10通道。

下面我们将PC0配置成AD1的通道10为例进行讲解。

3.1首先我们应将PC0设置成模拟输入:

#include "adc.h"

 

#define  ADC1_DR_Address    ((u32)0x40012400+0x4c)

 

__IO uint16_t ADC_ConvertedValue;

 

        static void ADC1_GPIO_Config(void)

{

 GPIO_InitTypeDef  GPIO_InitStructure;

  

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC,ENABLE);

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

   GPIO_Init(GPIOC, &GPIO_InitStructure);

}

 

3.2设置完端口后下一步当然是对AD进行初始化:

        这里需要补充一个知识点DMA,DMA就相当与CPU的一个秘书,他的作用就是帮CPU减轻负担的。说的再具体点就是帮CPU来转移数据的。我们都知道,AD每次转换结束后会将转换的结果放到一个固定的寄存器里,以往我们如果想将该寄存器中的值赋给某一变量时会用到赋值语句,如果不用DMA,则赋值语句便要CPU来完成,CPU本来就要忙着处理其他事情,现在还要来解决赋值语句这么简单的问题,肯到会蛋疼。所以需要DMA这个秘书来帮他解决这个问题。由于DMA只是个秘书,所以比较笨,你只有把任务交代清楚了她才能很好的完成任务。那么怎样来给DMA吩咐任务呢,聪明的人肯定想到了,那当然是“DMA_Init(DMA1_Channel1, &DMA_InitStructure)”这个函数啦。下面就来一步步的来给DMA交代任务。

 

static void ADC1_Mode_Config(void)

{

 DMA_InitTypeDef  DMA_InitStructure;

 ADC_InitTypeDef  ADC_InitStructure;

 

 DMA_DeInit(DMA1_Channel1);

 

 DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address;

 

 DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&ADC_ConvertedValue;

 

 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

 

 DMA_InitStructure.DMA_BufferSize = 1;

  

 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

 

 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

 

 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

  

 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

  

 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

 

 DMA_InitStructure.DMA_Priority = DMA_Priority_High;

 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

 DMA_Init(DMA1_Channel1, &DMA_InitStructure);

 

  DMA_Cmd(DMA1_Channel1, ENABLE);

  

   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

  

   ADC_InitStructure.ADC_ScanConvMode = DISABLE ;

  

   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  

   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  

   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  

   ADC_InitStructure.ADC_NbrOfChannel = 1;

   ADC_Init(ADC1, &ADC_InitStructure);

  

   RCC_ADCCLKConfig(RCC_PCLK2_Div8);

  

  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);

         

   ADC_DMACmd(ADC1, ENABLE);

  

   ADC_Cmd(ADC1, ENABLE);

  

   ADC_ResetCalibration(ADC1);

  

   while(ADC_GetResetCalibrationStatus(ADC1));

  

   ADC_StartCalibration(ADC1);

  

   while(ADC_GetCalibrationStatus(ADC1));

  

   ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

配置完以上的程序,那么AD每转换一次,DMA都会将转换结果搬到变量

ADC_ConvertedValue中,而不需用每次都用赋值语句来取值AD转换的值。

 

 

 

 

第二部分:AD多路采样

#include "adc.h"

#define  ADC1_DR_Address    ((u32)0x40012400+0x4c)

 

__IO uint16_t ADC_ConvertedValue[2];

 

static void ADC1_GPIO_Config(void)

{

 GPIO_InitTypeDef  GPIO_InitStructure;

  

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC,ENABLE);

   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

   GPIO_Init(GPIOC, &GPIO_InitStructure);

}

 

static void ADC1_Mode_Config(void)

{

 DMA_InitTypeDef  DMA_InitStructure;

 ADC_InitTypeDef  ADC_InitStructure;

 

 DMA_DeInit(DMA1_Channel1);

 

 DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address;

 

 DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&ADC_ConvertedValue;

 

 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

 

 DMA_InitStructure.DMA_BufferSize = 2;

  

 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

 

 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

   

 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

  

 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

  

 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

 

 DMA_InitStructure.DMA_Priority = DMA_Priority_High;

 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

 DMA_Init(DMA1_Channel1, &DMA_InitStructure);

 

  DMA_Cmd(DMA1_Channel1, ENABLE);

  

   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

       ADC_InitStructure.ADC_ScanConvMode = ENABLE ;

  

   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  

   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  

   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  

   ADC_InitStructure.ADC_NbrOfChannel = 2;

   ADC_Init(ADC1, &ADC_InitStructure);

  

   RCC_ADCCLKConfig(RCC_PCLK2_Div8);

 

   ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);

   ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);

  

   ADC_DMACmd(ADC1, ENABLE);

  

   ADC_Cmd(ADC1, ENABLE);

  

   ADC_ResetCalibration(ADC1);

  

   while(ADC_GetResetCalibrationStatus(ADC1));

  

   ADC_StartCalibration(ADC1);

  

   while(ADC_GetCalibrationStatus(ADC1));

  

   ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

 

!!!!!单通道采样与多通道采样的不同点都在第二段程序中用红色标出来了,注意比较。

总结:DMA就是一个无私奉献的搬运工,想将外设寄存器中的值放入内存中原本需要CPU来完成,现在DMA来帮CPU完成,这在一定程度上解放了CPU.


推荐阅读

史海拾趣

Equinox公司的发展小趣事

1991年,在纽约的上西区,一个名叫Equinox的健身俱乐部悄然开业。它的创始人凭借对健身行业的热情和对高端市场的敏锐洞察,将Equinox定位为一家提供豪华健身体验的俱乐部。通过提供优质的设施、个性化的服务和丰富的课程,Equinox很快在上西区树立了良好的口碑。

ELEKTRO-PLAST NASIELSK公司的发展小趣事

随着环保意识的提高和可持续发展理念的普及,电子行业对环保要求也越来越高。ELEKTRO-PLAST NASIELSK公司积极响应这一趋势,将绿色环保理念贯穿于产品研发和生产过程中。公司采用环保材料和工艺生产产品,并推动供应链中的合作伙伴共同践行环保理念。此外,公司还积极推广可回收利用和循环再生的理念,为保护环境做出了积极贡献。

Gwconnect (Molex)公司的发展小趣事
使用分立元件构成电路,相比集成电路成本更低。
Adafruit公司的发展小趣事
可以根据具体需求灵活调整电路参数,实现不同的功能和性能。
Hitachi Metals公司的发展小趣事

面对数字化浪潮的冲击,Hitachi Metals积极拥抱变革,致力于数字化转型。公司推出了全球级别的物联网平台Lumada,该平台能够为客户提供从企业扩建、价值核查到设备和系统管理的全方位解决方案。Lumada平台的成功应用不仅提升了日立金属自身的运营效率和管理水平,还为客户带来了显著的价值增长。通过Lumada平台,日立金属与全球范围内的合作伙伴建立了更加紧密的联系,共同推动电子行业的数字化转型进程。

Diodes Incorporated公司的发展小趣事

在公司的发展过程中,Diodes Incorporated与富昌电子建立了长期稳定的合作关系。富昌电子作为Diodes Incorporated的全球分销商之一,不仅为公司提供了广阔的市场渠道,还在产品推广和技术支持等方面给予了大力支持。这种紧密的合作关系,不仅促进了双方业务的共同发展,也为Diodes Incorporated在电子行业中树立了良好的品牌形象。

问答坊 | AI 解惑

放大电路的直流工作状态

这一节是本章的重点内容,在这一节中我们要掌握公式法计算Q点和图形法计算Q点  在学习之前,我们先来了解一个概念: 什麽是Q点?它就是直流工作点,又称为静态工作点,简称Q点。我们在进行静态分析时,主要是求基极直流电流IB ...…

查看全部问答>

电子工程辞典

电子工程辞典。…

查看全部问答>

容量无限延伸的U盘

由Yanko Design所设计的Memory Infinite,简单来说就是USB随身碟。然而它与现在市面上贩卖的随身碟有几个不同的地方:Memory Infinite可随意弯曲,头尾分别有一公一母的USB接头,可将Memory Infinite串接起来,增加内存容量。 …

查看全部问答>

半导体基础知识和半导体器件工艺

半导体基础知识和半导体器件工艺…

查看全部问答>

串口转USB出现乱码

不知道大家有没有出现过串口转USB在UBOOT下面出现乱码的?我用的sbc2410的板子,在vivi上正常,在norflash上启动uboot出现乱码用的是HL340的芯片…

查看全部问答>

linux 下写nor flash的方法

虽然网上有很多关于写nor flash的方法,很多都是基于MTD框架的,由于我现在做的这个项目不能基于MTD的框架,所以自己在底层写了一个关于nor flash的驱动,然后在应用层写了一个应用程序,最终尝试了很多方法,终于完成了此项目!以后哪位兄弟遇到No ...…

查看全部问答>

FPGA时钟输出问题

EP3Cls200  fpGA中 pllout时钟输出引脚中说Optional negative terminal for external clock outputs from PLL[1..4]. These pins can only use thedifferential I/O standard if it is being fed by a PLL output  什么意思,时钟输出引 ...…

查看全部问答>

在做两块LM3S9B96用spi通信,从机收不到数。

把主机发送和从机接收的程序附上请大家帮我看看问题出在哪里?先谢谢了。SPI_rec_slave(从机接收程序)#include \"inc/hw_memmap.h\"#include \"inc/hw_ssi.h\"#include \"inc/hw_types.h\"#include \"driverlib/ssi.h\"#include \"driverlib/gpio.h ...…

查看全部问答>

AD09布PCB板时的问题

在用AD09布PCB板时出现过孔连不上导线的现象,过孔被当作障碍物绕开了,或者是连上过孔后过孔属性中的网络没有和导线一致,还是NO NET,不知道是什么原因,请各位不吝赐教!谢谢了!…

查看全部问答>