打印

F28335_DMA使用

[复制链接]
8073|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huangfeng33|  楼主 | 2014-9-14 22:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  void DMACH1AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
        源地址有两个,一个A为用于传输时(随每个字节递增),另一个B作为返回的备份(当一帧结束后,重新装载入A)
        目的地址有两个,一个A为用于传输时(随每个字节递增),另一个B作为返回的备份(当一帧结束后,重新装载入A)
        每次启动DMA相应通道,都会把B装载入A
        void DMACH1BurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)
        Bsize: 每一个脉冲传递的字的个数,实际脉冲数为bsize+1
        Srcbstep:每传递一个字后,源地址A增量
        Desbstep:每传递一个字后,目的地址A增量

        void DMACH1TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
        Tsize:每一帧的脉冲个数,脉冲递减到0时(即一帧传递完成,也是DMA传递完成),产生DMA中断。实际帧数为tsize+1
        Srctstep:每个脉冲的最后一个字传递结束后,源地址A增量
        Deststep:每个脉冲的最后一个字传递结束后,目的地址A增量

        void DMACH1WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
        Srcwsize:当已经传递的脉冲数为srcwsize+1的整数倍时,源地址(B)增加srcwstep(常为0),并装载入源地址A
        Deswsize:当已经传递的脉冲数为deswsize+1的整数倍时,目的地址(B)增加deswstep(常为0),并装载入目的地址A

        void DMACH1ModeConfig(Uint16 persel, Uint16 perinte, Uint16 oneshot, Uint16 cont, Uint16 synce, Uint16 syncsel, Uint16 ovrinte, Uint16 datasize, Uint16 chintmode, Uint16 chinte)
        Persel:选择触发DMA的外设中断源
        Perinte:外设中断使能,
        Oneshot:使能时,外设产生一次中断,就能够把一帧传递完。禁止,外设产生一次中断,只能传递一个脉冲
        Cont:使能时,每次DMA结束后,需要再次启动DMA时,就不需要调用void StartDMACH1(void)。禁止时,重启DMA,需要调用void StartDMACH1(void)
        Datasize:设置每个字是16位或者32位
        Chintmode:设置DMA中断是在DMA启动或者结束时产生
        Chinte:DMA相应通道的中断使能(外设级)。
        注:Perinte和Chinte同时使能时,才能进入DMA通道中断
        仅Perinte使能,可以传输数据,但是不进入通道的中断程序

        void StartDMACH1(void)
        首次启动DMA,若Cont为禁止,每次DMA结束后,需要再次启动DMA时需要调用
        只开启相应用于触发的外设级中断,不开启PIE对应位,则能够触发DMA而不触发CPU的中断程序
        经过DMACH1ModeConfig配置的中断,DMA会自动清除相应外设级的中断标志位,不用程序清除

相关帖子

沙发
小木欧尼| | 2014-9-14 23:18 | 只看该作者
明白了

使用特权

评论回复
板凳
小灰辉| | 2014-10-16 11:05 | 只看该作者
本帖最后由 小灰辉 于 2014-10-16 11:19 编辑

你好,最近在看28335的DMA,看见了你对DMA的理解,收获很大。但还是有几个问题想向你请教一下。第一:TI的DMA其中一个例程是每个启动脉冲对ADC的四个通道转换,共收到10个转换脉冲。DMACH1BurstConfig(3,1,10);DMACH1TransferConfig(9,1,0);DMACH1WrapConfig(1,0,0,1);是例程中的设置,我很疑惑,理解不透,但感觉TI例程应该不会错吧。DMACH1BurstConfig(3,1,10)可以理解,每次突发传送4路信号,每传送一个字原地址加1,目的地址加10。DMACH1TransferConfig(9,1,0)就有点理解不了,每一帧的脉冲个数10个,每个脉冲的最后一个字传递结束后原地址加1,目的地址不增加。我感觉是不是要配置为DMACH1TransferConfig(9,0,0),每个脉冲的最后一个字传递结束后原地址不增加,目的地址不增加??DMACH1WrapConfig(1,0,0,1)也有点理解不了,感觉是不是要配置为DMACH1WrapConfig(0,0,0,1),当已经传递的脉冲数为1时,回绕时原地址不增加,目的地址加1??

使用特权

评论回复
地板
小灰辉| | 2014-10-16 11:19 | 只看该作者
  AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
   AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
   AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;        // 0 Non-Cascaded Mode
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 0x1;
   AdcRegs.ADCTRL2.bit.RST_SEQ1 = 0x1;
   AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
   AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;
   AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;
   AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;
   AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x0;
   AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x1;
   AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x2;
   AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x3;
   AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 3;   // Set up ADC to perform 4 conversions for every SOC
   对了,还有个问题想请教你一下,采集4路为什么要用8个通道,而最大转换序列却为4?能不能下面这样设置?
  AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
   AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
   AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;        // 0 Non-Cascaded Mode
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 0x1;
   AdcRegs.ADCTRL2.bit.RST_SEQ1 = 0x1;
   AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
   AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1;
   AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x2;
   AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x3;
   AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 3;

使用特权

评论回复
5
京江自动化| | 2015-1-12 15:27 | 只看该作者
小灰辉 发表于 2014-10-16 11:19
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
   AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
   AdcRegs.ADC ...

我是江苏大学的

使用特权

评论回复
6
RONDO7174| | 2015-1-31 11:44 | 只看该作者
小灰辉 发表于 2014-10-16 11:05
你好,最近在看28335的DMA,看见了你对DMA的理解,收获很大。但还是有几个问题想向你请教一下。第一:TI的D ...

你好,你的问题我也有,不过刚才想通了,分享一下我的理解。
DMACH1TransferConfig(9,1,0);DMACH1WrapConfig(1,0,0,1);这两个是相互配合的。DMACH1WrapConfig(1,0,0,1);设置源地址每传两个脉冲循环一次,而目标地址每传一个脉冲循环一次;所以DMACHI1TransferConfig(9,1,0)设置原地址每个脉冲加1,而目标地址每个脉冲可以不加,把0改成任何值都可以,效果相同,因为DMACH1WrapConfig(1,0,0,1)设置每个脉冲循环一次,循环后目标地址加1。
根据在线调试很容易看出规律。
说的有点啰嗦,希望能够帮助你理解

使用特权

评论回复
7
edishen| | 2015-1-31 15:39 | 只看该作者
很实用的问题谢谢楼主喽

使用特权

评论回复
8
小屁屁| | 2015-4-12 15:24 | 只看该作者
谢谢楼主了,正在看DMA,很困惑的,看完楼主的帖子一下就明白了,楼主好人啊

使用特权

评论回复
9
firstblood| | 2015-4-13 20:08 | 只看该作者
这个原函数的很多的,,各功能介绍的也详细。

使用特权

评论回复
10
lqq007| | 2015-4-23 16:58 | 只看该作者
请教一下下面两个的增量问题第一个是一个脉冲里面的每个字传输结束之后增加的步长,第二个是这个脉冲的最后一个字传输完之后增加的步长
DmaRegs.CH1.SRC_BURST_STEP = srcbstep;
DmaRegs.CH1.SRC_TRANSFER_STEP = srctstep;
意思是不是就是在一个传输中,每个字传输完地址在增加,等一个脉冲传递完,再接着在地址上接着增加第二个偏移量

使用特权

评论回复
11
ccw1986| | 2015-4-29 22:45 | 只看该作者
这是一篇讲述dma的好**,真的是太谢谢了

使用特权

评论回复
12
WING1987| | 2015-5-6 14:58 | 只看该作者
感谢!

使用特权

评论回复
13
wkwangke123| | 2015-7-21 16:12 | 只看该作者
这篇**写得真的是很详细,也很透彻。一看就会。关于官方例程上的设置,可以画一张4×10的表格,将ADC_RESULTX的数据依次写入进去,你就会发现第BUFF【0-9】对应的全是CH1的数据也就是RESULT0和RESULT4的数据。【10-19】对应的是CH2的数据。依次类推,这样看下来例程的设置也就很清楚了。

使用特权

评论回复
14
lovecat2015| | 2015-7-21 20:49 | 只看该作者
明白了,谢谢楼主的分享

使用特权

评论回复
15
小李爬坡| | 2015-12-11 16:45 | 只看该作者
太棒了,解决了我的疑惑

使用特权

评论回复
16
jdliuhuihong| | 2015-12-12 22:06 | 只看该作者
不错,比数据手册还详细,以后可以不用看英文手册了。赞

使用特权

评论回复
17
angerbird| | 2015-12-13 17:19 | 只看该作者
这些函数在调用的时候是需要多注意函数库的。

使用特权

评论回复
18
lscsmile| | 2016-3-19 16:48 | 只看该作者
wkwangke123 发表于 2015-7-21 16:12
这篇**写得真的是很详细,也很透彻。一看就会。关于官方例程上的设置,可以画一张4×10的表格,将ADC_RES ...

你好,我是学dsp的新手,我在注释那给出了各个变量的值(不懂这些值怎么工作的),请问你能帮我画一张表格,关于地址是怎么增加的,我还不是很清楚,求大神帮忙
void DMACH1AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source)
{
        EALLOW;
        // Set up SOURCE address:
        DmaRegs.CH1.SRC_BEG_ADDR_SHADOW = (Uint32)DMA_Source;        // Point to beginning of source buffer
        DmaRegs.CH1.SRC_ADDR_SHADOW =     (Uint32)DMA_Source;

        // Set up DESTINATION address:
        DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32)DMA_Dest;            // Point to beginning of destination buffer
        DmaRegs.CH1.DST_ADDR_SHADOW =     (Uint32)DMA_Dest;

       
        EDIS;
}

void DMACH1BurstConfig(Uint16 bsize, int16 srcbstep, int16 desbstep)
{
        EALLOW;
       
        // Set up BURST registers:
        DmaRegs.CH1.BURST_SIZE.all = bsize;           // (15)Number of words(X-1) x-ferred in a burst
        DmaRegs.CH1.SRC_BURST_STEP = srcbstep; //(1) Increment source addr between each word x-ferred
        DmaRegs.CH1.DST_BURST_STEP = desbstep; //(10) Increment dest addr between each word x-ferred


        EDIS;
}

void DMACH1TransferConfig(Uint16 tsize, int16 srctstep, int16 deststep)
{
        EALLOW;
       
        // Set up TRANSFER registers:
        DmaRegs.CH1.TRANSFER_SIZE = tsize;       //9  Number of bursts per transfer, DMA interrupt will occur after completed transfer
        DmaRegs.CH1.SRC_TRANSFER_STEP = srctstep;//-15 TRANSFER_STEP is ignored when WRAP occurs
        DmaRegs.CH1.DST_TRANSFER_STEP = deststep;//-150+1 TRANSFER_STEP is ignored when WRAP occurs

        EDIS;
}

void DMACH1WrapConfig(Uint16 srcwsize, int16 srcwstep, Uint16 deswsize, int16 deswstep)
{
        EALLOW;
       
                // Set up WRAP registers:
        DmaRegs.CH1.SRC_WRAP_SIZE = srcwsize;        //100  Wrap source address after N bursts
    DmaRegs.CH1.SRC_WRAP_STEP = srcwstep;        // 100 Step for source wrap

        DmaRegs.CH1.DST_WRAP_SIZE = deswsize;        //100  Wrap destination address after N bursts
        DmaRegs.CH1.DST_WRAP_STEP = deswstep;        //100  Step for destination wrap
       
        EDIS;
}



使用特权

评论回复
19
爱慕臣| | 2017-12-3 11:53 | 只看该作者
是不是可以这么理解呢,如果DMA中断设置成传送结束时产生,那么TRANSFER_SIZE和SRC/DST_WRAP_SIZE都记录了一次完整的传送过程的所产生的突发传送的次数,只是前者是为了计算传送的数据量,后者是为了计算下一次传送的其实地址。

使用特权

评论回复
20
爱慕臣| | 2017-12-3 12:08 | 只看该作者
我理解的有点偏差了,在一次完整的传送过程中可以产生多次的返回操作!谢谢分享,很棒的**。、

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

506

主题

2446

帖子

8

粉丝