OpenEdv-开源电子网

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

ADC连续模式+DMA循环模式,不能循环,求助

[复制链接]

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2017-1-31
在线时间
14 小时
发表于 2018-4-23 11:19:41 | 显示全部楼层 |阅读模式
10金钱
以参考过网上很多程序,都没成功,不说废话,以下是详情,盼教!
设备:探索者STM32F407ZG
目标:用ADC连续模式+DMA循环模式 来实现ADC一直采样并且不断刷新存储区内存储的采样值,以使得我可以实时从存储区获得采样值


代码:
DMA配置(两个函数):
[mw_shl_code=c,true]void MYDMA_p2m_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx,u32 par,u32 mar,u16 ndtr)
{

        DMA_InitTypeDef  DMA_InitStructure;
       
        if((u32)DMA_Streamx>(u32)DMA2)//
        {
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//
               
        }else
        {
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);//
        }
  DMA_DeInit(DMA_Streamx);
       
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}//
       
  /* ÅäÖÃ DMA Stream */
  DMA_InitStructure.DMA_Channel = chx;
  DMA_InitStructure.DMA_PeripheralBaseAddr = par;
  DMA_InitStructure.DMA_Memory0BaseAddr = mar;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//
  DMA_InitStructure.DMA_BufferSize = ndtr;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//循环模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA_Streamx, &DMA_InitStructure);
}

void MYDMA_p2m_Enable(DMA_Stream_TypeDef *DMA_Streamx,u16 ndtr)
{

        DMA_Cmd(DMA_Streamx, DISABLE);
       
        while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE){}
               
        DMA_SetCurrDataCounter(DMA_Streamx,ndtr);

        DMA_Cmd(DMA_Streamx, ENABLE); //使能DMA传输
}          [/mw_shl_code]

ADC配置:
[mw_shl_code=applescript,true]void  Adc_Init(void)
{   
  GPIO_InitTypeDef  GPIO_InitStructure;
        ADC_CommonInitTypeDef ADC_CommonInitStructure;
        ADC_InitTypeDef       ADC_InitStructure;
       
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  //Ïè3õê¼»ˉADC1í¨μà5 IO¿ú
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//
  GPIO_Init(GPIOA, &GPIO_InitStructure);//

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);          //
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);        //

       
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //开启DMA模式
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//
  ADC_CommonInit(&ADC_CommonInitStructure);//
       
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//
  ADC_InitStructure.ADC_NbrOfConversion = 1;//
  ADC_Init(ADC1, &ADC_InitStructure);

        ADC_Cmd(ADC1, ENABLE);
        ADC_DMACmd(ADC1, ENABLE);//开启ADC的DMA功能
        ADC_SoftwareStartConv(ADC1);//软件触发开始转换
}                [/mw_shl_code]

测试用主函数:
[mw_shl_code=applescript,true] NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);/
        delay_init(168);     /
        uart_init(115200);        /

/*--------------------------------------------------------------------------------------------*/
       
        Adc_Init();
        MYDMA_p2m_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC1->DR,(u32)SendBuff,1);//一个字节循环传输
        MYDMA_p2m_Enable(DMA2_Stream0, 1);
       
        while(1)
        {//每隔一段时间打印一次储存区的值,SendBuff是个数组,用它第0个位置当存储区
                delay_ms(1000);
                printf("the SendBuff[0]: %d\r\n",SendBuff[0]);
        }[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

自己结一下吧,后来找到了原因 是因为网上的各种各样的成功的案例,基本都是用的f1的芯片(至少我查到的都是),而f4的ADC的固件库与f1的有了修改,它将其中一个功能位(传送结束后发送新的DMA请求)的写入从原来的函数中提取了出来,将该位置位后即可实现循环传输采样数据。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2017-1-31
在线时间
14 小时
 楼主| 发表于 2018-4-23 11:19:42 | 显示全部楼层
自己结一下吧,后来找到了原因
是因为网上的各种各样的成功的案例,基本都是用的f1的芯片(至少我查到的都是),而f4的ADC的固件库与f1的有了修改,它将其中一个功能位(传送结束后发送新的DMA请求)的写入从原来的函数中提取了出来,将该位置位后即可实现循环传输采样数据。
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2017-1-31
在线时间
14 小时
 楼主| 发表于 2018-4-23 11:40:28 | 显示全部楼层
本帖最后由 一毛零Logo 于 2018-4-23 11:44 编辑

结果输出始终为同一个值,即每次开机时的第一个采样值。

拜托了,咨询原子技术客服太忙了顾不过来,望有前辈的话指导一下,谢谢了
回复

使用道具 举报

5

主题

57

帖子

0

精华

初级会员

Rank: 2

积分
143
金钱
143
注册时间
2017-9-26
在线时间
25 小时
发表于 2018-4-23 15:13:30 | 显示全部楼层
DMA配置问题DMA_Init(DMA_Streamx, &DMA_InitStructure); 你没有确定是哪个DMA流
回复

使用道具 举报

6

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2017-8-23
在线时间
34 小时
发表于 2018-4-26 09:44:59 | 显示全部楼层
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//
这个地方改成使用软件触发试试,然后如果实在没有找到问题,你可以用调试模式,看一下你配置的ADC和DMA里面的寄存器的值,对照数据手册,看是否是你要配置的
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2017-1-31
在线时间
14 小时
 楼主| 发表于 2018-4-26 11:35:23 | 显示全部楼层
青春梦飞翔 发表于 2018-4-23 15:13
DMA配置问题DMA_Init(DMA_Streamx, &DMA_InitStructure); 你没有确定是哪个DMA流

确定了啊:
MYDMA_p2m_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC1->DR,(u32)SendBuff,1);//一个字节循环传输
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2017-1-31
在线时间
14 小时
 楼主| 发表于 2018-4-26 11:35:56 | 显示全部楼层
依宝 发表于 2018-4-26 09:44
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//
这个地方改成使用软件 ...

这个就是软件触发
回复

使用道具 举报

6

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2017-8-23
在线时间
34 小时
发表于 2018-4-26 14:04:07 | 显示全部楼层
本帖最后由 依宝 于 2018-4-26 16:06 编辑

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
你的AD是设置的12位的,如果你的DMA设置成8位的话,难道不会溢出吗?一旦溢出,就停止工作啦而且你如果DMA设置字节,那你那个DMA_SxNDTR必须要设置为2才可以整个接收吧
回复

使用道具 举报

4

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
90
金钱
90
注册时间
2017-1-31
在线时间
14 小时
 楼主| 发表于 2018-5-30 20:46:35 | 显示全部楼层
依宝 发表于 2018-4-26 14:04
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA ...

ADC读取转换完成后是将数据存在其数据寄存器中,这里不存在溢出问题,而且这样将威慑和存储区均设置为1字节的数据宽度只是为了测试ADC+USART+DMA的循环功能,所以这里就暂时没管数据的截断问题,,最后真正开始传ADC采集数据是是按照2字节的宽度设置的
[mw_shl_code=c,true]  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;[/mw_shl_code]
回复

使用道具 举报

3

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2019-1-16
在线时间
21 小时
发表于 2019-1-23 22:18:15 | 显示全部楼层
一毛零Logo 发表于 2018-4-23 11:19
自己结一下吧,后来找到了原因
是因为网上的各种各样的成功的案例,基本都是用的f1的芯片(至少我查到的都 ...

请问楼主说的是不是CR2中的DDS位
回复

使用道具 举报

2

主题

4

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2020-5-14
在线时间
2 小时
发表于 2020-5-14 09:34:09 | 显示全部楼层
你好! 最近在学习STM32F407的例程,看到你“用ADC连续模式+DMA循环模式 ”的帖子,不知道能不能把源码发我一份? 十分感谢!!! fangkainagejitui@126.com
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-1 22:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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