OpenEdv-开源电子网

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

STM32F4通过DMA将GPIO口输入的数据存放到SRAM中

[复制链接]

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
发表于 2016-3-17 20:42:52 | 显示全部楼层 |阅读模式
2金钱
    最近在做一个AD的项目,AD数据线与STM32中GPIOD pin0~pin15相连,想通过DMA将GPIOD输入的数据存放到SRAM中。因为AD是在不断的进行数据转换,所以DMA的模式只能是循环模式,看STM32F4 reference manual说如果是循环模式的话,就不能是MemoryToMemory,但是PeripheralToMemory需要DMA请求源,那么怎么使用合适的请求源呢?希望大家能够给我一些建议!!!

最佳答案

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

我就是最近有做類似的東東...我才覺得OK的... TIM1串TIM2又串TIM4 來產生VSYNC HSYNC PCLK DATA(TIM1 DMA) 然後影像感測器 也是Analog輸出的 我也外掛ADC 只是跟你時序不一樣 我的是自己給它CLK 那邊我也串了2個 用DMA又改位址(ODR) 又抓資料的(IDR)... 我也邊做邊一值改...因為PCLK 2MHz 不可能用程序去做處理 光中斷響應的時間就受不了了 (只是進中斷翻個GPIO腳就過了150ns以上了) 如果怕麻煩 情況又許可的話 你就別 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-17 20:42:53 | 显示全部楼层
我就是最近有做類似的東東...我才覺得OK的...

TIM1串TIM2又串TIM4 來產生VSYNC HSYNC PCLK DATA(TIM1 DMA)
然後影像感測器 也是Analog輸出的 我也外掛ADC 只是跟你時序不一樣 我的是自己給它CLK
那邊我也串了2個 用DMA又改位址(ODR) 又抓資料的(IDR)...

我也邊做邊一值改...因為PCLK 2MHz 不可能用程序去做處理 光中斷響應的時間就受不了了
(只是進中斷翻個GPIO腳就過了150ns以上了)

如果怕麻煩 情況又許可的話 你就別用DMA了..
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2016-3-17 22:33:57 | 显示全部楼层
必须用MEM TO MEM这个模式,你可以在完成中断里面,重新开启一次即可.
回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-18 09:55:03 | 显示全部楼层
正点原子 发表于 2016-3-17 22:33
必须用MEM TO MEM这个模式,你可以在完成中断里面,重新开启一次即可.

       谢谢原子哥的帮助!!!
我有个问题,如果用MEM TO MEM模式的话,如何用软件触发DMA传输呢?
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-21 15:23:02 | 显示全部楼层
TIM1或TIM8的DMA請求  

你是不是外掛ADC然後直接拉一組GPIO去接收?  ADC的頻率總該知道吧
設定TIM去觸發DMA PeripheralToMemory



回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-21 17:40:07 | 显示全部楼层
civic7366 发表于 2016-3-21 15:23
TIM1或TIM8的DMA請求  

你是不是外掛ADC然後直接拉一組GPIO去接收?  ADC的頻率總該知道吧

谢谢civic7366解答,我确实外挂ADC然后拉一组GPIO去接收,但是如何使用TIM取触发呢?我的AD芯片没有任何引脚是接在可以AF为TIM的GPIO口上的
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-21 18:02:08 | 显示全部楼层
沒有要用到TIM_CH..把它拿來當定時器而已 (為了它的DMA_requset)

例如:
你把TIM1 設定ARR後(你要的頻率) 然後enable DMA UI_requset   

然後初始化DMA2(TIM1_UP)
之後每次TIM1周期到了 DMA就會去接收IDR到你要存的地方

一定要DMA2...因為DMA1沒辦法訪問ODR或IDR 所以你只能選TIM1或TIM8



回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-21 18:21:12 | 显示全部楼层
civic7366 发表于 2016-3-21 18:02
沒有要用到TIM_CH..把它拿來當定時器而已 (為了它的DMA_requset)

例如:

可是AD都是有个转换时间的,并不是说你给AD一个转换信号,立刻就会有数据出来(AD转换完成的标志是AD的busy引脚由高电平下降为低电平
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-21 18:34:44 | 显示全部楼层
本帖最后由 civic7366 于 2016-3-21 18:41 编辑

并不是说你给AD一个转换信号,立刻就会有数据出来

所以你的ADC是你觸發一次 它轉換一次? 如果是這樣的話 你還不會設定頻率@@?

AD转换完成的标志是AD的busy引脚由高电平下降为低电平 <==這個有可能會沒固定轉換時間嗎?

而且用MtoM更奇怪...DMA沒有看到MtoM能控制傳輸時機(請求源)的register

你採樣100次 DMA收了100筆 可實際上DMA可能收了100筆同一個採樣點的資料

回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-21 18:45:02 | 显示全部楼层
civic7366 发表于 2016-3-21 18:34
并不是说你给AD一个转换信号,立刻就会有数据出来

所以你的ADC是你觸發一次 它轉換一次? 如果是這樣的 ...

无标题.png
     如上图所示,给个上升沿的转换信号后,AD有个tconv的转换时间,不超过1.7us,但并不是一个固定时间

回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-21 18:49:27 | 显示全部楼层
civic7366 发表于 2016-3-21 18:34
并不是说你给AD一个转换信号,立刻就会有数据出来

所以你的ADC是你觸發一次 它轉換一次? 如果是這樣的 ...

另外我认为你说的MtoM是正确的,我也认为MtoM不能控制传输时机,事实上,我用MtoM正如你所说的“你採樣100次 DMA收了100筆 可實際上DMA可能收了100筆同一個採樣點的資料”
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-22 09:43:30 | 显示全部楼层
一定要用DMA2 (因為你要讀IDR)

然後去看看DMA2的請求源...看看哪個能抓來應用

是我就直接勾示波器抓時間來設定了...如果之後量產測試差異很多再說了

除非連同一顆IC 時間還能變來變去 還差很多...那就無言了








回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-22 10:26:17 | 显示全部楼层
civic7366 发表于 2016-3-22 09:43
一定要用DMA2 (因為你要讀IDR)

然後去看看DMA2的請求源...看看哪個能抓來應用

和你讨论了这么多,总之可以确定“不能使用MtoM”,但是你说的用TIM设定转换信号,然后enable DMA request,我觉得这个也似乎不可以。因为转换信号一到,同时触发DMA request,实际上这个时候AD还在转换过程中,传输过去的数据肯定不是正确的数据。
回复

使用道具 举报

58

主题

6293

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11473
金钱
11473
注册时间
2014-4-1
在线时间
1297 小时
发表于 2016-3-22 10:59:09 | 显示全部楼层
veblen 发表于 2016-3-22 10:26
和你讨论了这么多,总之可以确定“不能使用MtoM”,但是你说的用TIM设定转换信号,然后enable DMA reques ...


所以,被传输的将是上一次转换的结果。

回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-22 12:01:14 | 显示全部楼层
我覺得可以...大概想法...細節你要邊做邊想...

你pulse一發就enable另一個TIM(1.7u 單次的)   之後在中斷中enable TIM1(先初始化好DMA_request)
這裡很多時間點可以用的 上升沿 下降沿  看示要UI還是CCxI觸發DMA
不然就串TIM 設定trgi去啟動TIM1 這樣就不用中斷了
DMA傳完就把TIM1關掉

我覺得好多可以調...邊做邊調吧...
回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-22 16:00:59 | 显示全部楼层
xuande 发表于 2016-3-22 10:59
所以,被传输的将是上一次转换的结果。

谢谢xuande版主的解答,请看这个AD读取数据的时序图,如下图所示:
无标题.png
    可知在读取数据前,需要将CS拉低,且每次读取一个通道(共有八个通道)时,需要将RD由高变低,再拉高。所以我每一次的转换之后都需要有这么一个过程才能读取到数据。这样的话我应该怎么操作呢???
回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-22 16:16:34 | 显示全部楼层
civic7366 发表于 2016-3-22 12:01
我覺得可以...大概想法...細節你要邊做邊想...

你pulse一發就enable另一個TIM(1.7u 單次的)   之後在中 ...

我理解你的意思,但是这样做真的非常的麻烦,首先TIM定时多少是个问题,需要尝试。还有并不是只要触发DMA传送,DMA就可以把AD转换后的数据传送到SRAM中,你看我的AD读取数据时序图可知,在取数据过程中,RD是由高变低,再拉高的过程。
回复

使用道具 举报

58

主题

6293

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11473
金钱
11473
注册时间
2014-4-1
在线时间
1297 小时
发表于 2016-3-22 16:31:32 | 显示全部楼层

实现这一套功能,需要了解、熟悉包括DMA、定时器在内多个硬件的功能。

先说RD。
选一个可以触发DMA的定时器,印象里TIM1可以,用TIM1的某个通道作为RD信号;
该通道设为PWM方式,匹配事件发生时触发DMA,DMA把并口数据搬运到指定存储空间;
DMA的NDTR设为8次,以运输8个通道数据。

至于CS,可以用软件方式,比如IO方式,判断DMA完成8次(此时DMA发生中断)后拉高;
也可以用硬件,比如把上述PWM方波送到另一个定时器。

这是举例,需要统筹考虑,规划一下软硬件。

回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-22 17:12:52 | 显示全部楼层
xuande 发表于 2016-3-22 16:31
实现这一套功能,需要了解、熟悉包括DMA、定时器在内多个硬件的功能。

先说RD。

你所说的方法需要一个大前提,那就是AD的RD或者CS引脚连接到STM32的可以AF到TIM的gpio口,遗憾的是,我的并没有
回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-22 17:30:35 | 显示全部楼层
civic7366 发表于 2016-3-22 16:43
我就是最近有做類似的東東...我才覺得OK的...

TIM1串TIM2又串TIM4 來產生VSYNC HSYNC PCLK DATA(TIM1 DM ...

问你一下,你是怎么根据时序图来控制DMA的请求的,我纠结的地方在于:我需要拉低CS、RD,然后GPIOD->IDR才会有CH1转换的数据;然后拉高RD,再拉低RD,GPIOD->IDR才会有CH2转换的数据。。。。。。,这样的话,我应该什么时候来进行DMA的请求呢?是每得到一个CHX的数据,就进行一次DMA请求吗?
回复

使用道具 举报

60

主题

409

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2814
金钱
2814
注册时间
2012-10-17
在线时间
653 小时
发表于 2016-3-22 17:42:31 | 显示全部楼层
我也沒辦法太詳細 因為這中間發生的問題 要一步一步去調...

TIM1_CHx產生RD 串到 TIMx_CH產生CS 這裡你就知道ARR=你發pulse的週期  CCRx=8
如果可以發pulse都用TIM1_CHx CCRx設小一點就好...  

在CCRx=8的時後設定GPIO_RD復用功能 其它時間 output功能 設high 然後就XXXX

你RD不一定CCRx要設ARR的一半 你可以設一個確定DATA已經更新的時間 然後enable DMA2的TIM1_Chx

如果你那幾隻腳都沒法改成TIM_CH 那你就只能....自己實驗抓時間 ...TIM感覺還是能用 反正RD CS也是你送的
回复

使用道具 举报

9

主题

41

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-3-15
在线时间
33 小时
 楼主| 发表于 2016-3-23 14:41:58 | 显示全部楼层
civic7366 发表于 2016-3-22 17:42
我也沒辦法太詳細 因為這中間發生的問題 要一步一步去調...

TIM1_CHx產生RD 串到 TIMx_CH產生CS 這裡你 ...

谢谢civic7366,因为考虑到使用DMA结合我现在的连接电路来实现我想要的功能确实比较麻烦,我先没有使用DMA实现了AD采样,采样频率现在为25K,采样的数据还算比较稳定,当下降到20K时,数据波动有点大,估计后面可能还会有些问题,总之谢谢了
回复

使用道具 举报

6

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
148
金钱
148
注册时间
2015-12-20
在线时间
24 小时
发表于 2020-11-28 16:46:53 | 显示全部楼层
正点原子 发表于 2016-3-17 22:33
必须用MEM TO MEM这个模式,你可以在完成中断里面,重新开启一次即可.

F4用DMA进行内存和GPIO之间传输,搜到网上好几个地方看到都说要用DMA2的M2M模式,也不知道出处在哪,照着这个做被坑惨了。      后面找到ST的例程,发现根本不是M2M模式,而是正常的P2M和M2P模式,用起来很顺滑。           M2M模式实测定时器根本不起作用,跟真正的内存传输一样一股脑就完了,不可控制节拍。正常的P2M和M2P模式可以用TIM控制节拍,只是坑爹的ST只能选T1/T8,浪费高级定时器,这时候明明只需要一个普通定时器。

很想问版主,必须M2M模式这个传说到底源头哪来的,网上几个地方说法都如此,实测根本不是这样,正常P2M和M2P才顺滑。
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2022-6-10
在线时间
2 小时
发表于 2022-6-10 16:16:31 | 显示全部楼层
dddggg 发表于 2020-11-28 16:46
F4用DMA进行内存和GPIO之间传输,搜到网上好几个地方看到都说要用DMA2的M2M模式,也不知道出处在哪,照着 ...

请问ST例程哪里可以找到?
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
9
金钱
9
注册时间
2021-1-10
在线时间
1 小时
发表于 2022-9-25 12:33:21 | 显示全部楼层
dddggg 发表于 2020-11-28 16:46
F4用DMA进行内存和GPIO之间传输,搜到网上好几个地方看到都说要用DMA2的M2M模式,也不知道出处在哪,照着 ...

求ST例程
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2022-6-10
在线时间
2 小时
发表于 2022-9-27 10:04:16 | 显示全部楼层
通过DMA把GPIO的数据传输到内存是不存在问题的,STM32F4XX的Datasheet我反复看了很多遍,没有看到只能memory  to memory的模式。关键是我目前开发的系统正是实现GPIO到memory的数据传输的,并且已经获得成功。
在我的系统中,ADC芯片在一个时钟信号驱动下工作,时钟的高、低电平分别输出结果的高字节和低字节。由于速度很快,因此只能采用DMA。我用TIM1产生ADC的时钟,并且同时触发DMA传输,ADC的数据线连接到GPIOC。DMA配置成双缓冲区模式,每次DMA中断则检测DMAC寄存器中的CT位,决定处理哪个缓冲区的数据。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-25 02:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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