OpenEdv-开源电子网

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

关于ADC和DMA的问题

[复制链接]

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2017-5-23
在线时间
6 小时
发表于 2017-5-26 21:32:03 | 显示全部楼层 |阅读模式
1金钱
我想将ADC的输出值存储到DMA存储器中,使用F429,ADC通道为ADC1 CH5,DMA存储器定义了一个Sendbuff数组(10个数),不知道为什么DMA存储器的数值和ADC转出的数值不相同,不知道为什么,求各路大神解答。



搜狗截图20170526212802.png
这是DMA存储器中的数
搜狗截图20170526212826.png
这是ADC采集的数据

最佳答案

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

MYDMA_Config(DMA2_Stream0,0,(u32)ADC1->DR,(u32)Sendbuff0,SEND_BUF_SIZE); 这一句错了,应该改成: MYDMA_Config(DMA2_Stream0,0,(u32)&(ADC1->DR),(u32)Sendbuff0,SEND_BUF_SIZE); 因为你需要给定的是外设ADC数据寄存器的地址,而不是数据寄存器的值。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2015-12-3
在线时间
8 小时
发表于 2017-5-26 21:32:04 | 显示全部楼层
MYDMA_Config(DMA2_Stream0,0,(u32)ADC1->DR,(u32)Sendbuff0,SEND_BUF_SIZE);
这一句错了,应该改成:
MYDMA_Config(DMA2_Stream0,0,(u32)&(ADC1->DR),(u32)Sendbuff0,SEND_BUF_SIZE);
因为你需要给定的是外设ADC数据寄存器的地址,而不是数据寄存器的值。
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2017-5-23
在线时间
6 小时
 楼主| 发表于 2017-5-27 14:27:20 | 显示全部楼层
主程序如下:
int main(void)                                                                                                            
{
        Stm32_Clock_Init(360,25,2,8);
        delay_init(180);
        uart_init(90,115200);
        Adc_Init();
        //TIM3_Int_Init(1000-1,9000-1);//100ms
        MYDMA_Config(DMA2_Stream0,0,(u32)ADC1->DR,(u32)Sendbuff0,SEND_BUF_SIZE);
        while(1)
        {
                ADC_collect();
                ADC1->CR2|=1<<8;
       
        MYDMA_Enable(DMA2_Stream0,SEND_BUF_SIZE);
        while(1)
        {
                if(DMA2->LISR&(1<<5))
                {
                        DMA2->LIFCR|=1<<5;
                }
                break;
        }
        }
}
void ADC_collect(void)
{
        for(i=0;i<=9;i++)
        {
                a[i]=Get_Adc_Average(ADC_CH5,1);
        }
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-5-27 18:41:52 | 显示全部楼层
帮顶
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2017-5-23
在线时间
6 小时
 楼主| 发表于 2017-5-28 20:25:51 | 显示全部楼层
春天里打滚儿 发表于 2017-5-28 12:46
MYDMA_Config(DMA2_Stream0,0,(u32)ADC1->DR,(u32)Sendbuff0,SEND_BUF_SIZE);
这一句错了,应该改成:
MY ...

非常感谢!
不过还有个问题,不知道为什么数组中写入两个数据以后程序卡死在
while(!(ADC1->SR&1<<1));
求大神解释一下,万分感谢。
回复

使用道具 举报

2

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2015-12-3
在线时间
8 小时
发表于 2017-5-28 22:39:14 | 显示全部楼层
我不是太理解你的Get_Adc_Average(ADC_CH5,1)函数是怎么写的,既然你已经使用DMA方式来传数据了,为何不在void ADC_collect(void)函数里直接操作Sendbuff0而还要通过读取ADC的值来获取数据。你可能没有理解DMA真正的作用。
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2017-5-23
在线时间
6 小时
 楼主| 发表于 2017-5-29 17:45:38 | 显示全部楼层
我不太理解你说的操作Sendbuff0,不过Get_Adc_Average(ADC_CH5,1)函数里只是开启ADC转换,我想如果不开启ADC转换,那用DMA方式传输数据就没有意义。刚开始接触这个东西,可能理解不是那么准确。
回复

使用道具 举报

2

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2015-12-3
在线时间
8 小时
发表于 2017-5-30 10:11:34 | 显示全部楼层
ADC通过DMA的方式传输数据,配置好ADC之后只需要开启ADC即可。数据传输是通过使能DMA来启动的。你只要使能一次DMA传输,数据自动进入Sendbuff0,你只需要像操作数组一样操作Sendbuff0就可以了。
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2017-5-23
在线时间
6 小时
 楼主| 发表于 2017-5-31 09:01:12 | 显示全部楼层
弄明白了,我没有开启ADC的连续转换,现在问题已解决,谢谢。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-16 18:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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