舒伯特玫瑰 发表于 2022-11-26 23:04

STM32的DMA2和ADC3搭配使用采集交流信号

请教大神,我准备做19年的电赛D题,我想用不同的ADC检测波形,计算峰峰值,我用ADC1和DMA1可以采集到数据,但用ADC3和DMA2就不行,根本就不去DMA3的中断函数,我已经检查了好几天了,就是不知道哪里错了,请大神赐教。
这是我的DMA2的配置
void MYDMA2_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
      DMA_InitTypeDef DMA_InitStructure;
      NVIC_InitTypeDef NVIC_InitStructure;
      
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);      //使能DMA传输
      
    DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
      DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;//DMA外设ADC基地址
      DMA_InitStructure.DMA_MemoryBaseAddr = cmar;//DMA内存基地址
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//数据传输方向,从外设读取发送到内存//
      DMA_InitStructure.DMA_BufferSize = cndtr;//DMA通道的DMA缓存的大小
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为16位
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//工作在循环模式
//      DMA_InitStructure.DMA_Mode =DMA_Mode_Normal;//工作在一次模式
      DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//DMA通道x没有设置为内存到内存传输
      DMA_Init(DMA_CHx, &DMA_InitStructure);//ADC1匹配DMA通道1
      
      DMA_ITConfig(DMA2_Channel5,DMA2_IT_TC5,ENABLE);      //使能DMA传输中断      
      
      //配置中断优先级
      NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;               
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        
      NVIC_Init(&NVIC_InitStructure);      

      DMA_Cmd(DMA2_Channel5,ENABLE);//使能DMA通道
}

舒伯特玫瑰 发表于 2022-11-26 23:05

这是我的ADC3的配置
voidAdc3_Init(void)
{         
      ADC_InitTypeDef ADC_InitStructure;
      GPIO_InitTypeDef GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC3, ENABLE );          //使能ADC3通道时钟

      RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

      //PA6 作为模拟通道输入引脚                        
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PC1,通道11
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOC, &GPIO_InitStructure);      

      ADC_DeInit(ADC3);//复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

      ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;      //ADC工作模式:ADC1工作在独立模式
      ADC_InitStructure.ADC_ScanConvMode = DISABLE;      //模数转换工作在单通道模式
      ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;      //模数转换工作在非连续转换模式
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC3;      //转换由定时器2的通道2触发(只有在上升沿时可以触发)
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;      //ADC数据右对齐
      ADC_InitStructure.ADC_NbrOfChannel = 1;      //顺序进行规则转换的ADC通道的数目
      ADC_Init(ADC3, &ADC_InitStructure);      //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

      ADC_Cmd(ADC3, ENABLE);      //使能指定的ADC1
      ADC_DMACmd(ADC3, ENABLE);      //ADC的DMA功能使能
      ADC_ResetCalibration(ADC3);      //使能复位校准   
      ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_1Cycles5 );//ADC1通道6,采样时间为239.5周期         
      ADC_ResetCalibration(ADC3);//复位较准寄存器
      while(ADC_GetResetCalibrationStatus(ADC3));      //等待复位校准结束
      ADC_StartCalibration(ADC3);         //开启AD校准
      while(ADC_GetCalibrationStatus(ADC3));         //等待校准结束
      ADC_SoftwareStartConvCmd(ADC3, ENABLE);                //使能指定的ADC1的软件转换启动功能

}      

舒伯特玫瑰 发表于 2022-11-26 23:09

这是我DMA2的中断函数
void DMA2_Channel5_IRQHandler(void)
{
      LED0=!LED0;
      delay_ms(100);
      if(DMA_GetITStatus(DMA2_IT_TC5)!=RESET)
      {
                adcx2=currentadc2;
                t++;
                if(t==NPT)
                {
                        t=0;
                        adc_flag2=1;
                        
                        DMA_Cmd(DMA2_Channel5, DISABLE);      //失能DMA
                }
      }
      DMA_ClearITPendingBit(DMA2_IT_TC5);
}

舒伯特玫瑰 发表于 2022-11-26 23:10

STM32的DMA2和ADC3搭配使用

请教大神,我准备做19年的电赛D题,我想用不同的ADC检测波形,计算峰峰值,我用ADC1和DMA1可以采集到数据,但用ADC3和DMA2就不行,根本就不去DMA3的中断函数,我已经检查了好几天了,就是不知道哪里错了,请大神赐教。
这是我的DMA2的配置
void MYDMA2_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
      DMA_InitTypeDef DMA_InitStructure;
      NVIC_InitTypeDef NVIC_InitStructure;
      
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);      //使能DMA传输
      
    DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
      DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;//DMA外设ADC基地址
      DMA_InitStructure.DMA_MemoryBaseAddr = cmar;//DMA内存基地址
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//数据传输方向,从外设读取发送到内存//
      DMA_InitStructure.DMA_BufferSize = cndtr;//DMA通道的DMA缓存的大小
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为16位
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//工作在循环模式
//      DMA_InitStructure.DMA_Mode =DMA_Mode_Normal;//工作在一次模式
      DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//DMA通道x没有设置为内存到内存传输
      DMA_Init(DMA_CHx, &DMA_InitStructure);//ADC1匹配DMA通道1
      
      DMA_ITConfig(DMA2_Channel5,DMA2_IT_TC5,ENABLE);      //使能DMA传输中断      
      
      //配置中断优先级
      NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;               
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        
      NVIC_Init(&NVIC_InitStructure);      

      DMA_Cmd(DMA2_Channel5,ENABLE);//使能DMA通道
}

舒伯特玫瑰 发表于 2022-11-26 23:10


这是我的ADC3的配置
voidAdc3_Init(void)
{         
      ADC_InitTypeDef ADC_InitStructure;
      GPIO_InitTypeDef GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC3, ENABLE );          //使能ADC3通道时钟

      RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

      //PA6 作为模拟通道输入引脚                        
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PC1,通道11
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //模拟输入
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOC, &GPIO_InitStructure);      

      ADC_DeInit(ADC3);//复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

      ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;      //ADC工作模式:ADC1工作在独立模式
      ADC_InitStructure.ADC_ScanConvMode = DISABLE;      //模数转换工作在单通道模式
      ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;      //模数转换工作在非连续转换模式
      ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC3;      //转换由定时器2的通道2触发(只有在上升沿时可以触发)
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;      //ADC数据右对齐
      ADC_InitStructure.ADC_NbrOfChannel = 1;      //顺序进行规则转换的ADC通道的数目
      ADC_Init(ADC3, &ADC_InitStructure);      //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

      ADC_Cmd(ADC3, ENABLE);      //使能指定的ADC1
      ADC_DMACmd(ADC3, ENABLE);      //ADC的DMA功能使能
      ADC_ResetCalibration(ADC3);      //使能复位校准   
      ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_1Cycles5 );//ADC1通道6,采样时间为239.5周期         
      ADC_ResetCalibration(ADC3);//复位较准寄存器
      while(ADC_GetResetCalibrationStatus(ADC3));      //等待复位校准结束
      ADC_StartCalibration(ADC3);         //开启AD校准
      while(ADC_GetCalibrationStatus(ADC3));         //等待校准结束
      ADC_SoftwareStartConvCmd(ADC3, ENABLE);                //使能指定的ADC1的软件转换启动功能

}      

舒伯特玫瑰 发表于 2022-11-26 23:11


这是我的DMA2的中断函数
void DMA2_Channel5_IRQHandler(void)
{
      LED0=!LED0;
      delay_ms(100);
      if(DMA_GetITStatus(DMA2_IT_TC5)!=RESET)
      {
                adcx2=currentadc2;
                t++;
                if(t==NPT)
                {
                        t=0;
                        adc_flag2=1;
                        
                        DMA_Cmd(DMA2_Channel5, DISABLE);      //失能DMA
                }
      }
      DMA_ClearITPendingBit(DMA2_IT_TC5);
}

rzjvv 发表于 2022-11-26 23:22

我的天,你中断里面那个100ms延时是认真的吗??{:sweat:}

Uriah 发表于 2024-11-8 08:15


这些引线越窄越好

帛灿灿 发表于 2024-11-8 10:11


输入电容主要是起到高频能量存储器的作用

Bblythe 发表于 2024-11-8 11:14


输入滤波电容的公共端应作为其他交流电流地的唯一接点

周半梅 发表于 2024-11-8 13:10


它们对PCB布局的重要性

Pulitzer 发表于 2024-11-8 14:13


混淆的话,会引起电源工作不稳定

童雨竹 发表于 2024-11-8 16:09


把这干扰信号再次辐射出去

Wordsworth 发表于 2024-11-8 17:12


对变换器效率测量

Clyde011 发表于 2024-11-8 18:15


把纹波电流分摊到每个电容上

公羊子丹 发表于 2024-11-8 19:08


印制电路板(PCB)的线路设计
页: [1]
查看完整版本: STM32的DMA2和ADC3搭配使用采集交流信号