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);
} 怎么没人呢,拉人气 NXP就这德行。以前1768我问原厂,也没结果。
后来不用DMA了。
ST的DMA这方面好点,初始化后就可以用了,尤其用于串口和ADC,很爽。 tiger5 发表于 2014-12-30 11:15
NXP就这德行。以前1768我问原厂,也没结果。
后来不用DMA了。
ST的DMA这方面好点,初始化后就可以用了,尤 ...
感觉1788不会这么挫吧,这点都做不到 suebillt 发表于 2014-12-30 11:54
感觉1788不会这么挫吧,这点都做不到
1788和1768很多地方都一样。
结贴,其实是可行的
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);
}
} 楼主,请问你有用NXP的库(lpcopen)吗?感觉他的库不怎么样?有些配置就会有问题。 lujan1 发表于 2015-1-30 14:58
楼主,请问你有用NXP的库(lpcopen)吗?感觉他的库不怎么样?有些配置就会有问题。 ...
NXP的库确实不太好,所以有的就直接操作寄存器 suebillt 发表于 2015-1-17 17:11
结贴,其实是可行的
void DMA_IRQHandler (void)
{
感觉1768的DMA还是笨笨的,每次还要到中断中去处理一下,1768的DMA试了好多天了,连续转换一直没搞定,一定要象你那样在中断中再处理一下,才可以连续转换
STM32就无需中断去处理,初始化完,就可以连续不停的转换。
popo_new 发表于 2015-10-28 15:51
感觉1768的DMA还是笨笨的,每次还要到中断中去处理一下,1768的DMA试了好多天了,连续转换一直没搞定,一 ...
各有各的优势 为什么不用链表 fu563048951 发表于 2015-10-29 15:47
为什么不用链表
链表怎么用? 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]