案例 stm32单片机,adc的双通道+dma 内部温度

可以这样理解

先配置adc :有几个通道就配置几个通道.

 

然后配置dma,dma是针对adc的,而不是针对通道的.

一开始我以为一个adc通道对应一个dma通道.(这里是的,其实是我想复杂了)

一个adc,对应一个dma.  

adc可以开多个通道.比如采集电池的电量是一个通道,采集单片机温度是另一个通道.

adc1的所有通道对应着dma的某一个通道.

 

然后开启后dma,就会依次把各通道的数据存入数组:

数组元素1: 通道1的数据

数组元素2: 通道2的数据

数组元素3: 通道3的数据

数组元素4: 通道4的数据

数组元素5: 通道5的数据

 

然后又会从头存,一直循环下去....

 

这样可以设置成 多维数组

比如 100行 5列的数组

然后dma传输长度设置成500;

这样每个通道的数据,就自动存入  a[100][5] 的数组中,且每一列代表一个通道,可以除以100进行平均

 

下面给出一个程序:

adc1开启有两个通道,

一个通道用于采集电量.

另一个通道用于采集单片机内部温度.

 

首先,配置采集电量引脚的:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);    

//使用PC0做模拟输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure); 

然后配置adc,adc中使用了两个通道,一个是采集电量,一个是采集内部温度:

static void ADC_Configuration(void)
{
    ADC_InitTypeDef       ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    
    /* ADC Common Init **********************************************************/
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                       //独立工作模式
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);

    /* ADC3 Init ****************************************************************/
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                     //扫描模式
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                               //连续转换
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;      //由软件触发转换
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;            //外部触发源
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                           //数据右对其
    ADC_InitStructure.ADC_NbrOfConversion = 2;          //转换序列长度 因为有两个通道,这里是2    
    ADC_Init(ADC1, &ADC_InitStructure);
    
   
    ADC_TempSensorVrefintCmd(ENABLE);    //使能内部温度传感器


//采集电压的通道 ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_480Cycles); //内部温度的通道 ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_480Cycles); /* Enable DMA request after last transfer (Single-ADC mode) */ ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); ADC_SoftwareStartConv(ADC1); }

 

之后为adc的两个通道,配置一个dma.

ADCConvertedValue这个变量是一个二维数组,代表了两个通道,dma会把数据存入到这里.
    /* Enable DMA2 and GPIO clocks ****************************************/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
  
    /* DMA2 Stream0 channel2 configuration **************************************/
    DMA_DeInit(DMA2_Stream4);                                                                              
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;                                //DMA通道
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;         //外设基地址
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValue;         //数据存储区
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;                         //转换方向为外设到存储区
    DMA_InitStructure.DMA_BufferSize = 200;                                        //转换队列长度 
    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_FIFOMode = DMA_FIFOMode_Disable;         
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream4, &DMA_InitStructure);
    DMA_Cmd(DMA2_Stream4, ENABLE);

 

 

 

 


posted @ 2020-11-27 13:24  GXTon  阅读(999)  评论(0编辑  收藏  举报