stm32 多通道ADC+DMA采集

/*******************************************************************
** Variables Definitions **
*******************************************************************/
__IO uint16_t ADC_DMAValue[20][2];
GPIO_InitTypeDef GPIO_Init_ADC;           
ADC_InitTypeDef ADC1_InitStructure;        //ADC初始化结构体声明
DMA_InitTypeDef DMA1_InitStructure;        //DMA初始化结构体声明
NVIC_InitTypeDef NVIC_DMA1Structure;
/*******************************
函数名称:ADC_DMA_config
函数功能:ADC1与DMA1的联合初始化
函数参数:uint32_t addr  DMA1内存存储地址
函数返回值:无
*********************************/
void ADC1_DMA1_config(uint32_t addr)
{  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);              //使能ADC时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);             //使能GPIOC时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);             //使能GPIOC时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);               //使能DMA时钟
    RCC_ADCCLKConfig(RCC_ADCCLK_PCLK2_Div4);                       //ADC时钟频率 48/4=12MHZ  ,不可以大于14MHZ

    GPIO_Init_ADC.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_0;               //管脚PB1 PB0
     GPIO_Init_ADC.GPIO_Mode = GPIO_Mode_AN;                    //模拟输入模式
     GPIO_Init_ADC.GPIO_Speed   = GPIO_Speed_Level_3;
     GPIO_Init_ADC.GPIO_PuPd    = GPIO_PuPd_NOPULL;
     GPIO_Init(GPIOB, &GPIO_Init_ADC);                      //GPIOB初始化

/*********************      ADC1初始化       ******************************/   
    ADC_DeInit(ADC1);
    ADC1_InitStructure.ADC_Mode = ADC_Mode_Independent;                                 //独立的转换模式
    ADC1_InitStructure.ADC_ScanConvMode = ENABLE;                                       //开启扫描模式
    ADC1_InitStructure.ADC_ContinuousConvMode = ENABLE;                              //开启连续转换模式
       ADC1_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;           //ADC外部开关,关闭状态
    ADC1_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                         //对齐方式,ADC为12位中,右对齐方式
    ADC1_InitStructure.ADC_NbrOfChannel =2;                                      //开启通道数,2个
    ADC_Init(ADC1, &ADC1_InitStructure);

   // ADC_ExternalTrigConvCmd(ADC1,ENABLE);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);    //ADC通道组, 第8个通道 采样顺序1,转换时间 239.5个周期
    ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5);    //ADC通道组, 第9个通道 采样顺序2,转换时间 
    ADC_DMACmd(ADC1, ENABLE);                                                     //使能ADC与DMA的传输
    ADC_Cmd(ADC1, ENABLE);                                                       //开启ADC1  
    Delay_US(20);
    ADC_ResetCalibration(ADC1);                                              //重新校准
    while(ADC_GetResetCalibrationStatus(ADC1));                           //等待重新校准完成
    ADC_StartCalibration(ADC1);                                         //开始校准
    while(ADC_GetCalibrationStatus(ADC1));                         //等待校准完成


    /******************        DMA1初始化       *******************/
    DMA_DeInit(DMA1_Channel1);                                      //开启DMA1的第一通道 
    DMA1_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&ADC1->DR;       //DMA对应的外设基地址
    DMA1_InitStructure.DMA_MemoryBaseAddr =addr;               //内存存储基地址
    DMA1_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;           //DMA的转换模式为SRC模式,由外设搬移到内存
    DMA1_InitStructure.DMA_BufferSize =40;                                //DMA缓存大小,20个
    DMA1_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;       //外设地址递增    
    DMA1_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                    //内存地址递增
    DMA1_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;        //定义外设数据宽度
    DMA1_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;          //DMA搬移数据尺寸
    DMA1_InitStructure.DMA_Mode = DMA_Mode_Circular;                       //转换模式,循环缓存模式。
    DMA1_InitStructure.DMA_Priority = DMA_Priority_High;            //DMA优先级高
    DMA1_InitStructure.DMA_M2M = DMA_M2M_Disable;                //M2M模式禁用
    DMA_Init(DMA1_Channel1, &DMA1_InitStructure);          
    DMA_Cmd(DMA1_Channel1, ENABLE);
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);       //DMA发送中断使能


    NVIC_DMA1Structure.NVIC_IRQChannel = DMA1_Channel1_IRQn; 
    NVIC_DMA1Structure.NVIC_IRQChannelPreemptionPriority = 2; 
    NVIC_DMA1Structure.NVIC_IRQChannelSubPriority = 1; 
    NVIC_DMA1Structure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_DMA1Structure);          // Enable the DMA Interrupt 

}



/*********************************************************** 
函数名称: Get_Adc
函数功能: 等待ADC1转换完成
入口参数: void
出口参数: void
***********************************************************/ 
void Get_Adc()   
{
   ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1, ADC_SampleTime_239Cycles5);    //ADC通道组, 第8个通道 采样顺序1,转换时间 239.5个周期
   ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5);    //ADC通道组, 第9个通道 采样顺序2,转换时间 
   ADC_SoftwareStartConvCmd(ADC1, ENABLE);                          //软件规则组通道转换使能
   while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));                  //等待转换结束     
}

void bubbleSort(uint8_t column)  //冒泡排序算法,从大到小进行排序
{  
    int i,j;
    int flag = 1;  
    for(i=0;i<N&&flag;i++) 
    {  
        for(j=0;j<N-1-i;j++) 
        {  
            flag = 0;  
            if(ADC_DMAValue[j][column]>ADC_DMAValue[j+1][column])
            {
                uint16_t temp = ADC_DMAValue[j][column];  
                ADC_DMAValue[j][column] = ADC_DMAValue[j+1][column];  
                ADC_DMAValue[j+1][column] = temp;  
                flag = 1;  
            } 
         }   
      } 
}


void filter()   //均值滤波处理函数
{
  for(count=4;count<N-4;count++)     //去掉较大的四个值和较小的四个值,再取其余值的平均值
   {  
      ADC_Value1+=ADC_DMAValue[count][0];  
      ADC_Value2+=ADC_DMAValue[count][1];     
   }
   ADC_Value1=ADC_Value1/(N-8);
   ADC_Value2=ADC_Value2/(N-8);
   RxCounter=7;
}


该程序由本楼主自己编写,完成调试,只要适当调用程序即可正常使用,有问题可评论,一起探讨。。。



  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全职编程-叶湫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值