智能车制作

 找回密码
 注册

扫一扫,访问微社区

楼主: yangkuanqaz8598
打印 上一主题 下一主题

[讨论] K60 的 DMA 部分

  [复制链接]

10

主题

105

帖子

0

精华

高级会员

Rank: 4

积分
619
威望
289
贡献
138
兑换币
184
注册时间
2012-12-13
在线时间
96 小时
11#
 楼主| 发表于 2013-2-16 17:24:31 | 只看该作者
qurrer 发表于 2013-2-16 16:57
不懂

一起学习,一起研究{:soso_e113:}
回复 支持 反对

使用道具 举报

10

主题

105

帖子

0

精华

高级会员

Rank: 4

积分
619
威望
289
贡献
138
兑换币
184
注册时间
2012-12-13
在线时间
96 小时
12#
 楼主| 发表于 2013-2-17 00:25:13 | 只看该作者
本帖最后由 yangkuanqaz8598 于 2013-2-17 00:32 编辑
suebillt 发表于 2013-2-16 14:05
英文资料太复杂,没看懂,刚刚看这个知道了通道源那部分

看了你给的资料后,我貌似懂了点东西,说出看下理解的对不对~

       对于主循环的理解:你需要传输多少次数据,传输的次数值存储在主循环计器DMA_CITER_ELINKNO(CHn)的CITER中,每次传输完数据之后,CITER的值就会自动减一,一旦主循环计数器的CITER的值减到0,则DMA传输完毕后,TCDn_CSR[DONE]置1,如果允许,可以向CPU申请中断,读走这部分数据(比如我们要对一个传感器的电压值,采集100次,则应该将主循环的次数就设定为100,也就是DMA_CITER_ELINKNO(CHn)的CITER的数值设定为100)。

      对于目的地址的理解:当DMA存储数据的时候,也就是每次数据传输之后,目的地址会自动加上DMA_DOFF(CHn)这个目的地址偏移量的值。
如果偏移量为0时,每次传输数据之后目的地址不会发生变化,这样一来,如果有多次数据的传输(也就是主循环的次数),则就会造成对上次数据的更新覆盖( DMA_count_init()就是这样,只不过其实它并没有利用存储在COUNTSADDR这个地址的数据值,而是利用DMA_CITER_ELINKNO(CHn)的CITER值在每次数据传输传输完成之后,值会自动减一,从而达到累加计数的目的)。
如果DMA_DOFF(CHn)等于BYTEn(每次DMA传输字节数),这样以来,如果有多次数据的传输,那数据在内存里面的地址就会变成连续的储存,而不会造成对上次数据的覆盖。
DMA_SLAST(CHn)和DMA_DLAST_SGA(CHn)分别为当DMA传输结束后(主循环结束后),对于源地址和目的地址的最终偏移调整值。如果其值都为0,则下次需要DMA传输数据的时候,则此次数据组将会覆盖上次的数据组。(对于AD采样的话,应该可以理解为,如果我先对1号传感器采集100个数据,数据依次经过DMA存储在内存中,形成这次的数据组。当我们读走这个数据组之后,我们又需要对2号传感器采集100个数据,这100个数据就会覆盖上次的数据,从而形成此次的数据组。这样以来我们应该可以定义一个 ADC_result[100] 用来存储每次传感器的100数据)
所以对于目的地址,我的理解就是,目的地址就是每次DMA收到数据后,这个数据在内存中的存储位置。


      而对于源地址,简单理解可以通过内存中数据的复制这类问题来理解。比如通过设定一些配置参数后,DMA按照设定好的顺序从0x1000(源地址)取出数据,在将此数据复制到0X2000(目的地址)中,这样就实现了内存中数据的复制,并且不需要CPU的干预也就是所DMA就是将源地址的数据经过设定好的规律直接搬移到目的地址(但是此时数据总线是被DMA在利用,所以数据进行复制的时候,CPU并不能对内存进行访问,所以才有什么数据总线的分时复用吧,纯属于个人理解)。
下面我们把它简单应用在ADC采样的问题上,因为一个AD采样,其采样的结果保存在数据结果寄存器(ADCx_Rn)中,并且此结果寄存器在内存中肯定是映射一个地址。因此,我们就可以把DMA的源地址设定为这个地址,这样一来,就可以把AD的采样数据就可以通过DMA直接保存在内存中。并且如果每次读取源地址的数据之后,源地址的偏移值为0,换句话说就是源地址一直保持不变,依旧指向AD采样的结果值,这样下次AD的采样值就也可以不断的保存在相应的目的地址中了。而对应的,我们只要把目的地址偏移量设定为1,也就说每次储存数据之后,目的地址会加一,这样一来,AD的采样值在内存中就会以地址连续的方式存储了。
K60是32位单片机,所以其内存中的一个地址就可以保存4个字节(32位)的数据,由于AD的数据精度可以选择为8bit、10bit、12bit、16bit,但是对于一个结果整体而言,其任然是以32位的形式存储,所以源数据宽度也就应该设定为4个字节,目的数据宽度也应该与之匹配,也设定为4个字节,否则数据的传输就会出现错误了。假如源数据宽度为1个字节,源地址为0X1000,那么源地址里面的数据就会分为4个字节,分别进过四次读取之后,再交给目的地址。这样一来,一个完整的数据就会被拆为4个数据,这样数据传输就出错了。


       对于触发源的理解:Trigger(触发源)和 Peripheral Request 一起构成了DMA Request (数据采集的控制信号)

DMA有三种工作模式:无效模式、正常模式、和周期触发模式。
周期触发模式:触发源是PIT(周期定时器中断),这种模式仅仅适用与DMA Channel 0 -- DMA Channel 3。
正常工作模式:触发源是由DMAMUX_CHCFG_REG的SOURCE[0:5]决定的,它们之间的映射关系野火的ADC驱动中DMA_sources枚举已经定义好了。触发源包含很多,有UART、SPI、ADC、FTM、PDB、CPM、I2C、IO口触发,以及 Always On(一直使能,DMA Request完全由Peripheral Request决定,但是这个Peripheral Request,我不知道它是怎么来的,从这里我就开始理解不清楚了) 。其中看到例程中用的最多是IO口触发了,这个比较好理解。但是触发源还可以ADCn等触发,这个我也不理解了。




这就是我理解的东西了,我说的肯定有地方理解不到位,要是有错误的话,希望你也提醒我下,免得我一直错下去,哈哈~~     欢迎继续讨论


补充内容 (2013-2-17 09:01):
DMA选择了触发源之后,其触发源还是需要进行相应的配置。比如DMA_Source选择了IO口触发之后,对应IO口就应该做开启时钟,输出方向设定为输入,以及配置为触发模式,输入上拉或者下拉之类的.......

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

10

主题

105

帖子

0

精华

高级会员

Rank: 4

积分
619
威望
289
贡献
138
兑换币
184
注册时间
2012-12-13
在线时间
96 小时
13#
 楼主| 发表于 2013-2-17 10:20:42 | 只看该作者
yangkuanqaz8598 发表于 2013-2-17 00:25
看了你给的资料后,我貌似懂了点东西,说出看下理解的对不对~

       对于主循环的理解:你需要传输多 ...

有没有大神能给指点的啊,在触发源这边还是不理解啊,很徘徊这个DMA_Source到底是触发源还是源地址啊.....
回复 支持 反对

使用道具 举报

17

主题

466

帖子

0

精华

杰出人士

Rank: 12Rank: 12Rank: 12

积分
13941
QQ
威望
10902
贡献
2497
兑换币
716
注册时间
2011-9-24
在线时间
271 小时
14#
发表于 2013-2-17 11:47:28 | 只看该作者
yangkuanqaz8598 发表于 2013-2-17 10:20
有没有大神能给指点的啊,在触发源这边还是不理解啊,很徘徊这个DMA_Source到底是触发源还是源地址啊.... ...

触发源是在这个寄存器设置的DMAMUX_CHCFG_SOURCE(),不是源地址,表格中PA是49,PB50,以此类推
回复 支持 反对

使用道具 举报

10

主题

105

帖子

0

精华

高级会员

Rank: 4

积分
619
威望
289
贡献
138
兑换币
184
注册时间
2012-12-13
在线时间
96 小时
15#
 楼主| 发表于 2013-2-17 12:24:35 | 只看该作者
suebillt 发表于 2013-2-17 11:47
触发源是在这个寄存器设置的DMAMUX_CHCFG_SOURCE(),不是源地址,表格中PA是49,PB50,以此类推

嗯,那这样一来,他这个Source[0:5]里面可以选择的ADC和UART,这两个触发怎么理解呢。ADC触发会是指一旦采样结束,就触发DMA吗,它是考ADC的转换结束标志位来触发的吗,我就是不懂在这个里。
回复 支持 反对

使用道具 举报

17

主题

466

帖子

0

精华

杰出人士

Rank: 12Rank: 12Rank: 12

积分
13941
QQ
威望
10902
贡献
2497
兑换币
716
注册时间
2011-9-24
在线时间
271 小时
16#
发表于 2013-2-17 12:56:42 | 只看该作者
yangkuanqaz8598 发表于 2013-2-17 12:24
嗯,那这样一来,他这个Source[0:5]里面可以选择的ADC和UART,这两个触发怎么理解呢。ADC触发会是指一旦采 ...

IO的触发是外部中断中设置的DMA触发,我想ADC也是由中断触发DMA
回复 支持 反对

使用道具 举报

10

主题

105

帖子

0

精华

高级会员

Rank: 4

积分
619
威望
289
贡献
138
兑换币
184
注册时间
2012-12-13
在线时间
96 小时
17#
 楼主| 发表于 2013-2-17 16:53:17 | 只看该作者
本帖最后由 yangkuanqaz8598 于 2013-2-17 16:54 编辑
suebillt 发表于 2013-2-17 12:56
IO的触发是外部中断中设置的DMA触发,我想ADC也是由中断触发DMA

对于IO口而言,它的触发如果是依靠外部中断的话,那在外部中断函数里面不是应该有相应的软件触发DMA代码吗?但是野火的驱动里面并没有编写啊。我觉得IO口触发的话,应该仅仅就是设定IO口为触发模式,DMA为IO口触发,这两种外设模式就好了吧。


或者你的意思是指,DMA的IO触发,是因为DMA利用了IO口的中断信号,从而触发DMA数据传输的。要是这样理解的话,DMA的ADC触发,就也可以理解为DMA利用了ADC的转换结束的中断信号来触发DMA数据传输的喽,是这个意思吗


回复 支持 反对

使用道具 举报

10

主题

105

帖子

0

精华

高级会员

Rank: 4

积分
619
威望
289
贡献
138
兑换币
184
注册时间
2012-12-13
在线时间
96 小时
18#
 楼主| 发表于 2013-2-17 17:22:37 | 只看该作者
suebillt 发表于 2013-2-17 12:56
IO的触发是外部中断中设置的DMA触发,我想ADC也是由中断触发DMA

还有疑问就是,虽然知道源地址应该设定为ADC0的结果寄存器地址,可是在C代码里面应该写多少呢?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

17

主题

466

帖子

0

精华

杰出人士

Rank: 12Rank: 12Rank: 12

积分
13941
QQ
威望
10902
贡献
2497
兑换币
716
注册时间
2011-9-24
在线时间
271 小时
19#
发表于 2013-2-17 22:51:55 | 只看该作者
yangkuanqaz8598 发表于 2013-2-17 17:22
还有疑问就是,虽然知道源地址应该设定为ADC0的结果寄存器地址,可是在C代码里面应该写多少呢?

就是寄存器地址吧,baseADDRess + 10h
回复 支持 反对

使用道具 举报

10

主题

105

帖子

0

精华

高级会员

Rank: 4

积分
619
威望
289
贡献
138
兑换币
184
注册时间
2012-12-13
在线时间
96 小时
20#
 楼主| 发表于 2013-2-18 09:50:33 | 只看该作者
suebillt 发表于 2013-2-17 22:51
就是寄存器地址吧,baseADDRess + 10h

可以根据ADC memory map 里面的 absolut address(hex)来定吗?  也就地址就是    0X4003B010
回复 支持 反对

使用道具 举报

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

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-11-7 17:00 , Processed in 0.052342 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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