OpenEdv-开源电子网

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

STM32 DMA的问题

[复制链接]

52

主题

214

帖子

0

精华

高级会员

Rank: 4

积分
504
金钱
504
注册时间
2012-4-26
在线时间
17 小时
发表于 2012-8-2 17:05:24 | 显示全部楼层 |阅读模式
当选为非循环模式时,是否就意味着这个程序中DMA只能发送一次,在打开或关闭DMA通道都没用啊?
可是选为循环模式,我又不想让它一直没完没了的发,如何才能控制想让它发才发?
急啊
努力?奋斗
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-8-2 18:14:01 | 显示全部楼层
回复【楼主位】原味_郭:
---------------------------------
我们的dma实验就提供了实现吧.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

52

主题

214

帖子

0

精华

高级会员

Rank: 4

积分
504
金钱
504
注册时间
2012-4-26
在线时间
17 小时
 楼主| 发表于 2012-8-3 08:32:50 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
程序可以了,重新启动一次DMA时,还需加入DMA_Init(DMA1_Channel4, &DMA_InitStructure);
努力?奋斗
回复 支持 反对

使用道具 举报

36

主题

1263

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1612
金钱
1612
注册时间
2012-6-15
在线时间
39 小时
发表于 2012-8-3 09:27:51 | 显示全部楼层
将DMA配置为单次模式

重新启动时候 不需要初始化
只需要 重置 DMA传输的长度 在使能就可以了

DMAx->CCR&=~0x1ul;
DMAx->CNDTR = size;
DMAx->CCR |= 0x1ul;

一定要传输完成 TC中断之后,再重新启动,否则传输数据有错误
回复 支持 反对

使用道具 举报

52

主题

214

帖子

0

精华

高级会员

Rank: 4

积分
504
金钱
504
注册时间
2012-4-26
在线时间
17 小时
 楼主| 发表于 2012-8-3 13:23:21 | 显示全部楼层
回复【4楼】aleda303:
---------------------------------
谢谢,可是使用库做时直接加入DMA_InitStructure.DMA_BufferSize = Size;这句是不行的,我已经试过了。
努力?奋斗
回复 支持 反对

使用道具 举报

52

主题

214

帖子

0

精华

高级会员

Rank: 4

积分
504
金钱
504
注册时间
2012-4-26
在线时间
17 小时
 楼主| 发表于 2012-8-9 15:35:37 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
USART利用DMA连续通信,
我现在有三个数组需要依次发送,可是DMA只能配置一个源地址,我现在也只能发送一个数组中的内容,
请问怎么就能将三个数组依次发送出去,
努力?奋斗
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-8-9 16:11:33 | 显示全部楼层
回复【6楼】原味_郭:
---------------------------------
每次改变源地址不就得了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

52

主题

214

帖子

0

精华

高级会员

Rank: 4

积分
504
金钱
504
注册时间
2012-4-26
在线时间
17 小时
 楼主| 发表于 2012-8-9 16:13:03 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
是不是每次都需要重新配置一下DMA
努力?奋斗
回复 支持 反对

使用道具 举报

36

主题

1263

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1612
金钱
1612
注册时间
2012-6-15
在线时间
39 小时
发表于 2012-8-13 17:28:24 | 显示全部楼层
回复【5楼】原味_郭:
---------------------------------
需要 禁止传输后 才能更改 size
然后在使能
回复 支持 反对

使用道具 举报

52

主题

214

帖子

0

精华

高级会员

Rank: 4

积分
504
金钱
504
注册时间
2012-4-26
在线时间
17 小时
 楼主| 发表于 2012-8-13 19:14:09 | 显示全部楼层
回复【9楼】aleda303:
---------------------------------
谢谢你的帮助
努力?奋斗
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2014-5-31
在线时间
0 小时
发表于 2014-5-31 10:59:58 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
可以把DMA传输模式设为循环模式:DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
在中断里面先关一下AD的DMA传输:ADC_DMACmd(ADC1, DISABLE);
等到该处理的处理完毕了,再把DMA传输重新使能:ADC_DMACmd(ADC1, ENABLE);
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2014-5-31
在线时间
0 小时
发表于 2014-5-31 11:08:03 | 显示全部楼层
回复【11楼】将风汉王鑫:
---------------------------------
PS:再恢复ADC传输之前还得初始化一下DMA:  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
照着最开始的设置来也行的,关键看你的要求是怎么回事。
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
47
金钱
47
注册时间
2014-7-28
在线时间
5 小时
发表于 2014-8-29 15:18:29 | 显示全部楼层
同意楼上的,可以完全重新设置启动。我就是这样在应用的。
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2014-3-18
在线时间
0 小时
发表于 2014-11-7 16:34:15 | 显示全部楼层
回复【12楼】将风汉王鑫:
---------------------------------
我按照你的意思设置了下,把DMA传输模式设为循环模式:DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 

/* I/O????????????????PC5 */
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5) != RESET) //?·±???·??ú?ú??EXTI Line????
{
    
DMA_endble();
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);

EXTI_ClearITPendingBit(EXTI_Line5);    
}  
}

void DMA1_Channel1_IRQHandler(void)
{
  /* Test on DMA1 Channel1 Transfer Complete interrupt */
  if(DMA_GetITStatus(DMA1_IT_TC1))
  {
ADC_DMACmd(ADC1, DISABLE);
average();//?ó???ù??

printf("\r\n%4d %4d %4d %4d %4d %4d\r\n",sum[0],sum[1],sum[2],sum[3],sum[4],sum[5]);
DMA1->IFCR = DMA1_IT_TC1;
  }
}

我是想在外部线中断函数里面开启ADC_DMA,然后再DMA中断函数里面关闭ADC_DMA ,并且处理数据,
但是DMA数据会错位,比如实际上sum[1]为4095,其他都为0,但是 偶尔会出现sum[2]=4095,其他为0
这个有遇到过吗  怎么解决呢?
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2014-3-18
在线时间
0 小时
发表于 2014-11-10 22:18:53 | 显示全部楼层
回复【14楼】大漠孤烟:
---------------------------------
这个我解决了,原来把DMA_endble(); 这句要放到DMA中断函数里面的末尾,难道DMA配置好之后还要预留“足够”的时间才能ADC_SoftwareStartConvCmd(ADC1, ENABLE);   ?
回复 支持 反对

使用道具 举报

38

主题

109

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
294
金钱
294
注册时间
2014-8-1
在线时间
6 小时
发表于 2014-11-12 21:10:21 | 显示全部楼层
重新启动一下DMA_Cmd(DMA2_Stream5, ENABLE);
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-29 14:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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