• 案例 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);
    
    
  • 相关阅读:
    shell
    梯度,也即该物理参数的变化率,导数
    一些石油类核心期刊
    泰勒展开
    向量范数
    添加打印机
    泛函
    9.3.4 BeaufitulSoup4
    9.3.3 scrapy 框架
    9.3.2 网页爬虫
  • 原文地址:https://www.cnblogs.com/chulin/p/14047426.html
Copyright © 2020-2023  润新知