1.开DMA时钟
2.开DMA通道使能
3.此版存在以下问题待解决:不能持续接收,需要在中断中重新初始化DMA,影响效率。更改目标:能够持续接收
4.2015.3.17追加,问题应该在一月份解决了,但是忘记追加了,现在把改正后的代码放在帖子后面
DMA初始化及中断服务函数:
#define DMA_SIZE 32
uint8_t DMADest_Buffer[DMA_SIZE];
void DMA_IRQHandler (void)
{
//GPDMA_ChannelCmd(0, DISABLE);
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++;
UART_Send((UART_ID_Type)0,DMADest_Buffer,sizeof(DMADest_Buffer),BLOCKING);
lpc1788_DMA_Init();
}
if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)) /* ¼ì²éDMAͨµÀ0ÖжϴíÎó״̬ */
{
GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);//Channel0_Err++; /* Çå³ýDMAͨµÀ0ÖжϴíÎóÇëÇó */
}
}
//GPDMA_ChannelCmd(0, ENABLE);
}
void lpc1788_DMA_Init(void)
{
GPDMA_Channel_CFG_Type GPDMACfg;
NVIC_DisableIRQ(DMA_IRQn); /* ¹Ø±ÕGPDMAÖÐ¶Ï */
NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01));/* ÉèÖÃÇÀÕ¼ÓÅÏȼ¶preemptionΪ1, ×ÓÓÅÏȼ¶sub-priorityΪ1 */
GPDMA_Init(); /* ³õʼ»¯GPDMA¿ØÖÆÆ÷£¬´ò¿ªDMAʱÖÓµçÔ´£¬¸´Î»¸÷ͨµÀ¼Ä´æÆ÷£¬Çå³ý´íÎó±êÖ¾µÈ */
GPDMACfg.ChannelNum = 0; /* ʹÓÃDMAͨµÀ0 */
GPDMACfg.SrcMemAddr =0; /* Ô´µØÖ· */
GPDMACfg.DstMemAddr = (uint32_t)DMADest_Buffer; /* Ä¿µÄµØÖ· */
GPDMACfg.TransferSize = sizeof(DMADest_Buffer);/* ´«Êä´óС */
//GPDMACfg.TransferWidth =GPDMA_WIDTH_WORD; /* ´«Êä¿í¶È */
GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_P2M; /* ÉèÖô«ÊäÀàÐÍΪÍâÉèµ½´æ´¢Æ÷ */
GPDMACfg.SrcConn = GPDMA_CONN_UART0_Rx; /* ÉèÖÃDMAÔ´ÇëÇóÁ¬½Ó£¬Î´Ê¹ÓÃ*/
GPDMACfg.DstConn = 0; /* ÉèÖÃDMAÄ¿µÄÇëÇóÁ¬½Ó£¬Î´Ê¹ÓÃ*/
GPDMACfg.DMALLI = 0; /* ÉèÖÃDMAͨµÀÁ´±íÏδʹÓà */
GPDMA_Setup(&GPDMACfg);/* °ÑÉÏÃæµÄ²ÎÊýÉèÖýøDMAÏà¹Ø¼Ä´æÆ÷ */
NVIC_EnableIRQ(DMA_IRQn);
GPDMA_ChannelCmd(0, ENABLE);
}
串口初始化函数:
void lpc1788_Uart_Init(int port)//LPC1788_Uart_Init
{
UART_CFG_Type UARTConfigStruct; /* UARTÅäÖÃ */
UART_FIFO_CFG_Type UARTFIFOConfigStruct; /* UART FIFOÅäÖÃ */
if( port == 0 )
{
PINSEL_ConfigPin(0,2,1); /* ÅäÖÃUART0Òý½ÅP0.2: U0_TXD P0.3: U0_RXD*/
PINSEL_ConfigPin(0,3,1);
}
UART_ConfigStructInit(&UARTConfigStruct);/* ³õʼ»¯UARTConfigStruct½á¹¹ÌåΪ£º²¨ÌØÂÊΪ115200£¬8λÊý¾Ý£¬ÎÞÆæÅ¼Ð£Ñ飬1λֹͣλ */
UART_Init((UART_ID_Type)port, &UARTConfigStruct); /* ÓÃUARTConfigStruct¸ø¶¨µÄ²ÎÊý³õʼ»¯UARTÍâÉè */
/* ³õʼ»¯FIFOConfigStructΪĬÈÏÖµ:
* - FIFO_DMAMode = DISABLE
* - FIFO_Level = UART_FIFO_TRGLEV0
* - FIFO_ResetRxBuf = ENABLE
* - FIFO_ResetTxBuf = ENABLE
* - FIFO_State = ENABLE
*/
UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
UARTFIFOConfigStruct.FIFO_DMAMode = ENABLE;//ΪUARTʹÄÜDMA
UART_FIFOConfig(UART_0, &UARTFIFOConfigStruct);// ΪUART0ÍâÉè³õʼ»¯FIFO
UART_TxCmd((UART_ID_Type)port, ENABLE);/* ʹÄÜUART·¢ËÍ */
UART_IntConfig(UART_0, UART_INTCFG_RBR, ENABLE);
UART_IntConfig(UART_0, UART_INTCFG_RLS, ENABLE);
NVIC_DisableIRQ(UART0_IRQn);
}
追加、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
中断服务函数中不需要对整个DMA重新初始化,只要下面两句即可:
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;