搜索
楼主: cpev

[已解决] 用DMA传输ADC转换结果, 数据不正确

[复制链接]

该用户从未签到

133

主题

4688

帖子

239

蝴蝶豆

版主

最后登录
2021-4-10
发表于 2018-3-15 11:08:21 | 显示全部楼层
你缓冲区怎么定义的?要定义为16位的。
回复 支持 反对

使用道具 举报

该用户从未签到

12

主题

76

帖子

8

蝴蝶豆

中级会员

最后登录
2018-5-11
发表于 2018-3-15 11:11:06 | 显示全部楼层
cpev 发表于 2018-3-15 11:04
嗯 我改成16位的,但得到的结果只有低8位,高8位传不过来。

问一下楼主,没有flash模块可以使用DMA吗?
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

21

帖子

0

蝴蝶豆

初级会员

最后登录
2018-4-27
 楼主| 发表于 2018-3-15 11:13:10 | 显示全部楼层
安 发表于 2018-3-15 11:08
你缓冲区怎么定义的?要定义为16位的。

我现在只试验传一路ADC配置如下:
        DMA_InitTypeDef DMA_InitStructure;
       
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);        //使能DMA传输
    DMA_DeInit(DMA1_Channel1);   //将DMA的通道1寄存器重设为缺省值
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&ADC1->DR); //DMA外设ADC1转换结果基地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;//(u32)DMA1Buf;  //DMA内存基地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,从外设读取数据到内存
        DMA_InitStructure.DMA_BufferSize = 1; //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
        DMA_InitStructure.DMA_MemoryInc = DMA_PeripheralInc_Disable;//DMA_MemoryInc_Enable;  //内存地址寄存器递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//DMA_PeripheralDataSize_Word; //数据宽度为32位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;//DMA_PeripheralDataSize_Word; //数据宽度为32位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//工作在正常缓存模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA1通道1拥有中优先级
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
        DMA_Init(DMA1_Channel1,&DMA_InitStructure);   
有问题吗
回复 支持 反对

使用道具 举报

该用户从未签到

133

主题

4688

帖子

239

蝴蝶豆

版主

最后登录
2021-4-10
发表于 2018-3-15 11:16:02 | 显示全部楼层
ADCConvertedValue,这个是怎么定义的。
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

21

帖子

0

蝴蝶豆

初级会员

最后登录
2018-4-27
 楼主| 发表于 2018-3-15 11:16:55 | 显示全部楼层
安 发表于 2018-3-15 11:16
ADCConvertedValue,这个是怎么定义的。

如下定义 :__IO u16 ADCConvertedValue;  
回复 支持 反对

使用道具 举报

该用户从未签到

133

主题

4688

帖子

239

蝴蝶豆

版主

最后登录
2021-4-10
发表于 2018-3-15 11:26:21 | 显示全部楼层
看配置差不多,值应该是多少,采集到的是多少。
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

21

帖子

0

蝴蝶豆

初级会员

最后登录
2018-4-27
 楼主| 发表于 2018-3-15 11:30:57 | 显示全部楼层
安 发表于 2018-3-15 11:26
看配置差不多,值应该是多少,采集到的是多少。

AD转换结果为0x04ef, DMA传输后得到的结果为0x00ef, 高8位被丢掉了。
回复 支持 反对

使用道具 举报

该用户从未签到

5

主题

21

帖子

0

蝴蝶豆

初级会员

最后登录
2018-4-27
 楼主| 发表于 2018-3-15 12:38:45 | 显示全部楼层
安 发表于 2018-3-15 11:26
看配置差不多,值应该是多少,采集到的是多少。

控制部分是这样做的,需要每100ms转换一次,并用DMA传输  
         ADC_DMACmd(ADC1,ENABLE); //开启ADC1 DMA传输                  
         ADC_SoftwareStartConvCmd(ADC1,ENABLE); //使能指定的ADC1的软件转换启动功能                    
         while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); //等待转换结束         大约56us              
         while(DMA_GetFlagStatus(DMA1_FLAG_TC1) != RESET)
         {            
            DMA_ClearFlag(DMA1_FLAG_TC1);    //清除通道1传输完成标志
            break;
         }       
         ADC_DMACmd(ADC1,DISABLE);                     //关闭ADC1 DMA传输         
回复 支持 反对

使用道具 举报

该用户从未签到

133

主题

4688

帖子

239

蝴蝶豆

版主

最后登录
2021-4-10
发表于 2018-3-15 14:00:31 | 显示全部楼层
楼主,方便把你的代码共享一下吗?我找个板子测试一下。
也可以仿真的情况下,看一下寄存器的值和DMA取到的值是不是一致。我使用很长时间DMA中断,发生的问题基本是因为自己配置错误导致。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

回复 支持 反对

使用道具 举报

该用户从未签到

74

主题

3420

帖子

82

蝴蝶豆

社区小助手

最后登录
2023-11-12
发表于 2018-3-15 14:57:35 | 显示全部楼层
本帖最后由 wenyangzeng 于 2018-3-15 15:01 编辑

楼主既然一次扫描8个通道4次,就不应该将这里设成禁止:
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
这样的话ADC只转换8个通道一次就结束,DMA不知道,它会硬要凑足32个数据,后面的数据必定对不上号
要么设成ENABLE,要么32改成8
还有字长应该设成:
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-8 05:54 , Processed in 1.177458 second(s), 41 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

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