suebillt 发表于 2014-12-29 23:51:31

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

本帖最后由 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);
}

suebillt 发表于 2014-12-30 11:07:48

怎么没人呢,拉人气

tiger5 发表于 2014-12-30 11:15:58

NXP就这德行。以前1768我问原厂,也没结果。
后来不用DMA了。
ST的DMA这方面好点,初始化后就可以用了,尤其用于串口和ADC,很爽。

suebillt 发表于 2014-12-30 11:54:34

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

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

tiger5 发表于 2014-12-30 12:47:19

suebillt 发表于 2014-12-30 11:54
感觉1788不会这么挫吧,这点都做不到

1788和1768很多地方都一样。

suebillt 发表于 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);}
                        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) \
                                                                                                                | GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst) \
                                                                                                                | GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid) \
                                                                                                                | GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid) \
                                                                                                                | 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);
        }
}

lujan1 发表于 2015-1-30 14:58:06

楼主,请问你有用NXP的库(lpcopen)吗?感觉他的库不怎么样?有些配置就会有问题。

suebillt 发表于 2015-1-30 18:02:05

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

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

popo_new 发表于 2015-10-28 15:51:09

suebillt 发表于 2015-1-17 17:11
结贴,其实是可行的
void DMA_IRQHandler (void)
{


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

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

suebillt 发表于 2015-10-28 17:59:25

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

各有各的优势

fu563048951 发表于 2015-10-29 15:47:43

为什么不用链表

suebillt 发表于 2015-10-29 16:59:16

fu563048951 发表于 2015-10-29 15:47
为什么不用链表

链表怎么用?

fu563048951 发表于 2015-10-29 17:29:15

suebillt 发表于 2015-10-29 16:59
链表怎么用?

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就可以一直传输数据了
页: [1]
查看完整版本: LPC1788DMA不能重复使用,请问怎么解决