本帖最后由 jxc827 于 2012-6-24 19:12 编辑
使用DMA实现UART0收发功能。直接在网站例程基础上修改,在此谢谢原作者。
UART0通过DMA方式接收串口数据,当长度达到16字节时,将接收到的数据通过DMA发送回来。两个LED闪烁指示UART0的发送和接收。
实验板上焊掉了R5,R6两个电阻。
需要注意的是:DMA接收数据长度必须4字节对齐,最少接收4个字节才能触发DMA接收中断。
主程序main.c-
- /*----------------------------------------------------------------------------*/
- /* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved. */
- /*----------------------------------------------------------------------------*/
- #include "includes.h" //包含所需的头文件
- #define DMA_LENTH 16
- uint8_t RX_BUFF[DMA_LENTH];
- uint8_t i=0, j=1;
- /*************PDMA CH0传输完成中断函数********************************/
- void PFN_DRVPDMA0_callback(void)
- {
- DrvPDMA_ClearIntFlag(eDRVPDMA_CHANNEL_0, eDRVPDMA_BLKD_FLAG); //清除中断标志
- if(i%2)
- DrvGPIO_SetBit(E_GPA,2);
- else
- DrvGPIO_ClrBit(E_GPA,2);
- i++;
- }
- /*************PDMA CH1传输完成中断函数****************************/
- void PFN_DRVPDMA1_callback(void)
- {
- DrvPDMA_ClearIntFlag(eDRVPDMA_CHANNEL_0, eDRVPDMA_BLKD_FLAG); //清除中断标志
- DrvPDMA_CHEnableTransfer(eDRVPDMA_CHANNEL_0); //将接收的数据DMA发送回去
- DrvPDMA_CHEnableTransfer(eDRVPDMA_CHANNEL_1); //重新开始接收
- if(j%2)
- DrvGPIO_SetBit(E_GPA,3);
- else
- DrvGPIO_ClrBit(E_GPA,3);
- j++;
- }
- /*************PDMA CH0配置函数********************************/
- void PDMA0_Configuration(void)
- {
- STR_PDMA_T sPDMA;
- DrvPDMA_Init(); //使能PDMA时钟
- DrvPDMA_CHSoftwareReset(eDRVPDMA_CHANNEL_0); //软件复位CH0内部状态机和指针
- DrvPDMA_SetCHForAPBDevice(eDRVPDMA_CHANNEL_0,eDRVPDMA_UART0,eDRVPDMA_WRITE_APB); //指定PDMA0为UART0的发送
- sPDMA.sSrcCtrl.u32Addr = (uint32_t)RX_BUFF; //源地址为发送BUFF
- sPDMA.sDestCtrl.u32Addr = UART0_BASE; //目的地址为UART0发送FIFO
- sPDMA.u8TransWidth = eDRVPDMA_WIDTH_8BITS; //8位宽度
- sPDMA.u8Mode = eDRVPDMA_MODE_MEM2APB; //内存到外设模式
- sPDMA.sSrcCtrl.eAddrDirection = eDRVPDMA_DIRECTION_INCREMENTED; //源地址增长
- sPDMA.sDestCtrl.eAddrDirection = eDRVPDMA_DIRECTION_FIXED; //目的地址固定不变
- sPDMA.i32ByteCnt = DMA_LENTH; //传输长度
- DrvPDMA_Open(eDRVPDMA_CHANNEL_0,&sPDMA); //配置DMA CH0参数
- DrvPDMA_EnableInt(eDRVPDMA_CHANNEL_0, eDRVPDMA_BLKD ); //使能传输完成中断
- DrvPDMA_InstallCallBack(eDRVPDMA_CHANNEL_0,eDRVPDMA_BLKD,(PFN_DRVPDMA_CALLBACK)PFN_DRVPDMA0_callback);
- }
- /*************PDMA CH1配置函数********************************/
- void PDMA1_Configuration(void)
- {
- STR_PDMA_T sPDMA;
- DrvPDMA_Init(); //使能PDMA时钟
- DrvPDMA_CHSoftwareReset(eDRVPDMA_CHANNEL_1); //软件复位CH1内部状态机和指针
- DrvPDMA_SetCHForAPBDevice(eDRVPDMA_CHANNEL_1,eDRVPDMA_UART0,eDRVPDMA_READ_APB); //指定PDMA1为UART0的接收
- sPDMA.sSrcCtrl.u32Addr = UART0_BASE; //源地址为UART0 FIFO
- sPDMA.sDestCtrl.u32Addr =(uint32_t)RX_BUFF ; //目的地址为接收BUFF
- sPDMA.u8TransWidth = eDRVPDMA_WIDTH_8BITS;
- sPDMA.u8Mode = eDRVPDMA_MODE_APB2MEM; //外设到内存模式
- sPDMA.sSrcCtrl.eAddrDirection = eDRVPDMA_DIRECTION_FIXED; //源地址固定
- sPDMA.sDestCtrl.eAddrDirection = eDRVPDMA_DIRECTION_INCREMENTED; //目的地址增长
- sPDMA.i32ByteCnt = DMA_LENTH; //一次DMA长度4字节
- DrvPDMA_Open(eDRVPDMA_CHANNEL_1,&sPDMA); //配置DMA CH1参数
- DrvPDMA_EnableInt(eDRVPDMA_CHANNEL_1, eDRVPDMA_BLKD );
- DrvPDMA_InstallCallBack(eDRVPDMA_CHANNEL_1,eDRVPDMA_BLKD,(PFN_DRVPDMA_CALLBACK)PFN_DRVPDMA1_callback);
- }
- /**************************************************************** Function name: main
- ** Descriptions: usart
- ** input parameters: 无
- ** output parameters: 无
- ** Returned value: 无
- *************************************************************/
- int main (void)
- {
- Set_System(); //封装一些初始化模块
- PDMA0_Configuration(); //配置发送DMA
- PDMA1_Configuration(); //配置接收DMA
- DrvPDMA_CHEnableTransfer(eDRVPDMA_CHANNEL_1); //开始接收
- while(1)
- {
- ;
- }
- }
工程压缩包:
|