OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9645|回复: 8

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

[复制链接]

0

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2021-7-28
在线时间
4 小时
发表于 2021-9-9 19:42:39 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 古一凡 于 2021-9-9 19:58 编辑

请教大神,我准备做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通道
}

这是我的ADC3的配置
void  Adc3_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的软件转换启动功能

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

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2021-7-28
在线时间
4 小时
 楼主| 发表于 2021-9-9 19:54:35 | 显示全部楼层

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通道
}

回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2021-7-28
在线时间
4 小时
 楼主| 发表于 2021-9-9 19:55:46 | 显示全部楼层
这是我的ADC3的配置
void  Adc3_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的软件转换启动功能

}       
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2021-7-28
在线时间
4 小时
 楼主| 发表于 2021-9-9 19:56:22 | 显示全部楼层
这是我的DMA2的中断函数
void DMA2_Channel5_IRQHandler(void)
{
        LED0=!LED0;
        delay_ms(100);
        if(DMA_GetITStatus(DMA2_IT_TC5)!=RESET)
        {
                adcx2[t]=currentadc2;
                t++;
                if(t==NPT)
                {
                        t=0;
                        adc_flag2=1;
                       
                        DMA_Cmd(DMA2_Channel5, DISABLE);        //失能DMA
                }
        }
        DMA_ClearITPendingBit(DMA2_IT_TC5);
}
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2021-9-10 10:44:09 | 显示全部楼层
先不说配置的问题,你中断里面搞个100ms延时是什么逻辑?
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2021-7-28
在线时间
4 小时
 楼主| 发表于 2021-9-10 20:58:46 | 显示全部楼层
阿侑kevin 发表于 2021-9-10 10:44
先不说配置的问题,你中断里面搞个100ms延时是什么逻辑?

那个我注释掉了,在这上面没去掉
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2021-9-13 09:37:04 | 显示全部楼层
古一凡 发表于 2021-9-10 20:58
那个我注释掉了,在这上面没去掉

1、加ADC_ExternalTrigConvCmd(ADC3, ENABLE);这句在ADC使能之前
2、注释ADC_SoftwareStartConvCmd(ADC3, ENABLE);
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2021-7-28
在线时间
4 小时
 楼主| 发表于 2021-10-11 20:24:02 | 显示全部楼层
阿侑kevin 发表于 2021-9-13 09:37
1、加ADC_ExternalTrigConvCmd(ADC3, ENABLE);这句在ADC使能之前
2、注释ADC_SoftwareStartConvCmd(ADC3 ...

按照您说的改完之后没有变化
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2022-11-23
在线时间
4 小时
发表于 2022-11-25 16:49:36 | 显示全部楼层
同问,解决了吗,我也遇到这样的问题了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 21:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表