搜索
bottom↓
回复: 12

LPC1788DMA不能重复使用,请问怎么解决

[复制链接]

出0入4汤圆

发表于 2014-12-29 23:51:31 | 显示全部楼层 |阅读模式
本帖最后由 suebillt 于 2014-12-30 11:37 编辑

具体代码如下,串口和SSP的都测试过,当数据传输完进入中断后必须重新初始化才能进行下次DMA的接收,否则只能传输一次
void DMA_IRQHandler (void)
{
        uint8_t i;
        NVIC_DisableIRQ(DMA_IRQn);               
        if (GPDMA_IntGetStatus(GPDMA_STAT_INT, 0))
        {
                if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0))
                {                       
                        GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
                        dma_finished = 1;//                        Channel0_TC++;               
                        for(i=0;i<DMA_SIZE;i++)
                        {
                                 printf("%d",DMADest_Buffer);
                       }
                        lpc1788_DMA_Init();               
                }
                if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0))               
                {
                        GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);       
                }
        }
                NVIC_EnableIRQ(DMA_IRQn);               
}
void lpc1788_DMA_Init(void)
{
        GPDMA_Channel_CFG_Type GPDMACfg;

        NVIC_DisableIRQ(DMA_IRQn);               
        NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01));
        GPDMA_Init();       
        GPDMACfg.ChannelNum = 0;
        GPDMACfg.SrcMemAddr =0;       
        GPDMACfg.DstMemAddr = (uint32_t)DMADest_Buffer;       
        GPDMACfg.TransferSize = sizeof(DMADest_Buffer);
        GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_P2M;       
        GPDMACfg.SrcConn = GPDMA_CONN_SSP0_Rx;       
        GPDMACfg.DstConn = 0;       
        GPDMACfg.DMALLI = 0;       

        GPDMA_Setup(&GPDMACfg);
       
        LPC_SSP0->DMACR |=0x11;//SSP_DMACmd (0, SSP_DMA_RXDMA_EN, ENABLE);
       
        NVIC_EnableIRQ(DMA_IRQn);
        GPDMA_ChannelCmd(0, ENABLE);
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入4汤圆

 楼主| 发表于 2014-12-30 11:07:48 | 显示全部楼层
怎么没人呢,拉人气

出0入0汤圆

发表于 2014-12-30 11:15:58 | 显示全部楼层
NXP就这德行。以前1768我问原厂,也没结果。
后来不用DMA了。
ST的DMA这方面好点,初始化后就可以用了,尤其用于串口和ADC,很爽。

出0入4汤圆

 楼主| 发表于 2014-12-30 11:54:34 | 显示全部楼层
tiger5 发表于 2014-12-30 11:15
NXP就这德行。以前1768我问原厂,也没结果。
后来不用DMA了。
ST的DMA这方面好点,初始化后就可以用了,尤 ...

感觉1788不会这么挫吧,这点都做不到

出0入0汤圆

发表于 2014-12-30 12:47:19 | 显示全部楼层
suebillt 发表于 2014-12-30 11:54
感觉1788不会这么挫吧,这点都做不到

1788和1768很多地方都一样。

出0入4汤圆

 楼主| 发表于 2015-1-17 17:11:25 | 显示全部楼层
结贴,其实是可行的
void DMA_IRQHandler (void)
{
        uint8_t i;
        if (GPDMA_IntGetStatus(GPDMA_STAT_INT, 0))/* ¼ì²éDMAͨµÀ0ÖжÏ״̬ */
        {
                GPDMA_ChannelCmd(0, DISABLE);
                if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0))/* ¼ì²éDMAͨµÀ0Öն˼ÆÊýÇëÇó״̬£¬¶ÁÈ¡DMACIntTCStatus¼Ä´æÆ÷À´ÅжÏÖжÏÊÇ·ñÒòΪ´«ÊäµÄ½áÊø¶ø²úÉú£¨Öն˼ÆÊý£© */
                {                       
                        GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);/* Çå³ýDMAͨµÀ0Öն˼ÆÊýÖжÏÇëÇó */       
                        for(i=0;i<DMA_SIZE;i++){printf("%d",DMADest_Buffer[i]);}
                        printf("\r\n");
                        LPC_GPDMACH0->CDestAddr = GPDMACfg.DstMemAddr;// Assign memory destination address
                        LPC_GPDMACH0->CControl= GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMACfg.TransferSize)\
                                                                                                                | GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMACfg.SrcConn]) \
                                                                                                                | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMACfg.SrcConn]) \
                                                                                                                | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMACfg.SrcConn]) \
                                                                                                                | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMACfg.SrcConn]) \
                                                                                                                | GPDMA_DMACCxControl_DI \
                                                                                                                | GPDMA_DMACCxControl_I;       
                }
                if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0))                /* ¼ì²éDMAͨµÀ0ÖжϴíÎó״̬ */
                {
                        GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);//Channel0_Err++;        /* Çå³ýDMAͨµÀ0ÖжϴíÎóÇëÇó */
                }
                GPDMA_ChannelCmd(0, ENABLE);
        }
}

出0入0汤圆

发表于 2015-1-30 14:58:06 | 显示全部楼层
楼主,请问你有用NXP的库(lpcopen)吗?感觉他的库不怎么样?有些配置就会有问题。

出0入4汤圆

 楼主| 发表于 2015-1-30 18:02:05 | 显示全部楼层
lujan1 发表于 2015-1-30 14:58
楼主,请问你有用NXP的库(lpcopen)吗?感觉他的库不怎么样?有些配置就会有问题。 ...

NXP的库确实不太好,所以有的就直接操作寄存器

出0入0汤圆

发表于 2015-10-28 15:51:09 | 显示全部楼层
suebillt 发表于 2015-1-17 17:11
结贴,其实是可行的
void DMA_IRQHandler (void)
{

感觉1768的DMA还是笨笨的,每次还要到中断中去处理一下,1768的DMA试了好多天了,连续转换一直没搞定,一定要象你那样在中断中再处理一下,才可以连续转换

STM32就无需中断去处理,初始化完,就可以连续不停的转换。

出0入4汤圆

 楼主| 发表于 2015-10-28 17:59:25 | 显示全部楼层
popo_new 发表于 2015-10-28 15:51
感觉1768的DMA还是笨笨的,每次还要到中断中去处理一下,1768的DMA试了好多天了,连续转换一直没搞定,一 ...

各有各的优势

出0入0汤圆

发表于 2015-10-29 15:47:43 | 显示全部楼层
为什么不用链表

出0入4汤圆

 楼主| 发表于 2015-10-29 16:59:16 | 显示全部楼层

链表怎么用?

出0入0汤圆

发表于 2015-10-29 17:29:15 | 显示全部楼层

DMA带有链表功能啊,首先定义个结构体
//链表结构体
typedef struct {
  unsigned int DMA_SrcAddr;
        unsigned int DMA_DstAddr;
        unsigned int DMA_LLI;
        unsigned int DMA_Control;
}LLI;  

LLI *LLI1,*LLI2;//定义两个结构体指针

LLI1  = (LLI*)(0x10002000);                                        /* 将链表指针指向一个地址 用来存放链表 该地址可自定义 注意要在SRAM中或者外部存储器中*/
LLI2  = (LLI*)(0x10003000);

然后先初始化DMA

初始化DMA后,开始初始化链表

LLI1->DMA_SrcAddr = SSP0_DMA_TX_SRC;  //你的源地址
        LLI1->DMA_DstAddr =  SSP0_DMA_TX_DST;  //目的地址
        LLI1->DMA_LLI = (unsigned int)LLI1;
        LLI1->DMA_Control = (SSP_DMA_SIZE & 0x0FFF) |                       /* ´此处值与你初始化DMA时 CControl寄存器是一样的    */
                           (0x02 << 12) |                           
                           (0x02 << 15) |                           
                           (0x01 << 18) |                           
                           (0x01 << 21) |                          
                           (1 << 26) |                           
                           0x00000000;                             
        LPC_GPDMACH1->CLLI = (unsigned int)LLI1;              //然后将DMA带的链表指向自定义的链表地址   


这样定义过后  DMA就可以一直传输数据了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-23 15:31

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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