[Cortex-M0技术交流] 新手学习笔记3——UART收发(PDMA方式)

[复制链接]
6456|4
 楼主| jxc827 发表于 2012-6-24 19:04 | 显示全部楼层 |阅读模式
本帖最后由 jxc827 于 2012-6-24 19:12 编辑

使用DMA实现UART0收发功能。直接在网站例程基础上修改,在此谢谢原作者。
UART0通过DMA方式接收串口数据,当长度达到16字节时,将接收到的数据通过DMA发送回来。两个LED闪烁指示UART0的发送和接收。
实验板上焊掉了R5,R6两个电阻。

需要注意的是:DMA接收数据长度必须4字节对齐,最少接收4个字节才能触发DMA接收中断。

主程序main.c

  1. /*----------------------------------------------------------------------------*/
  2. /* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved.  */
  3. /*----------------------------------------------------------------------------*/
  4. #include "includes.h"  //包含所需的头文件
  5. #define  DMA_LENTH  16
  6. uint8_t  RX_BUFF[DMA_LENTH];
  7. uint8_t  i=0, j=1;
  8. /*************PDMA CH0传输完成中断函数********************************/
  9. void PFN_DRVPDMA0_callback(void)
  10. {
  11. DrvPDMA_ClearIntFlag(eDRVPDMA_CHANNEL_0, eDRVPDMA_BLKD_FLAG); //清除中断标志
  12. if(i%2)
  13.      DrvGPIO_SetBit(E_GPA,2);
  14. else
  15.      DrvGPIO_ClrBit(E_GPA,2);
  16. i++;
  17. }
  18. /*************PDMA CH1传输完成中断函数****************************/
  19. void PFN_DRVPDMA1_callback(void)
  20. {
  21.     DrvPDMA_ClearIntFlag(eDRVPDMA_CHANNEL_0, eDRVPDMA_BLKD_FLAG); //清除中断标志
  22.     DrvPDMA_CHEnableTransfer(eDRVPDMA_CHANNEL_0); //将接收的数据DMA发送回去
  23.     DrvPDMA_CHEnableTransfer(eDRVPDMA_CHANNEL_1); //重新开始接收
  24. if(j%2)
  25.      DrvGPIO_SetBit(E_GPA,3);
  26. else
  27.      DrvGPIO_ClrBit(E_GPA,3);
  28. j++;
  29. }
  30. /*************PDMA CH0配置函数********************************/
  31. void PDMA0_Configuration(void)
  32. {
  33.     STR_PDMA_T  sPDMA;
  34.     DrvPDMA_Init();    //使能PDMA时钟
  35.     DrvPDMA_CHSoftwareReset(eDRVPDMA_CHANNEL_0);   //软件复位CH0内部状态机和指针
  36.     DrvPDMA_SetCHForAPBDevice(eDRVPDMA_CHANNEL_0,eDRVPDMA_UART0,eDRVPDMA_WRITE_APB); //指定PDMA0为UART0的发送
  37.     sPDMA.sSrcCtrl.u32Addr = (uint32_t)RX_BUFF; //源地址为发送BUFF
  38.     sPDMA.sDestCtrl.u32Addr = UART0_BASE;    //目的地址为UART0发送FIFO
  39.     sPDMA.u8TransWidth = eDRVPDMA_WIDTH_8BITS;  //8位宽度
  40.     sPDMA.u8Mode = eDRVPDMA_MODE_MEM2APB;  //内存到外设模式
  41.     sPDMA.sSrcCtrl.eAddrDirection = eDRVPDMA_DIRECTION_INCREMENTED;  //源地址增长
  42.     sPDMA.sDestCtrl.eAddrDirection = eDRVPDMA_DIRECTION_FIXED;     //目的地址固定不变
  43.     sPDMA.i32ByteCnt = DMA_LENTH; //传输长度
  44.     DrvPDMA_Open(eDRVPDMA_CHANNEL_0,&sPDMA); //配置DMA CH0参数
  45.     DrvPDMA_EnableInt(eDRVPDMA_CHANNEL_0, eDRVPDMA_BLKD ); //使能传输完成中断
  46.     DrvPDMA_InstallCallBack(eDRVPDMA_CHANNEL_0,eDRVPDMA_BLKD,(PFN_DRVPDMA_CALLBACK)PFN_DRVPDMA0_callback);
  47. }
  48. /*************PDMA CH1配置函数********************************/
  49. void PDMA1_Configuration(void)
  50. {
  51.     STR_PDMA_T  sPDMA;
  52.     DrvPDMA_Init();    //使能PDMA时钟
  53.     DrvPDMA_CHSoftwareReset(eDRVPDMA_CHANNEL_1);   //软件复位CH1内部状态机和指针
  54.     DrvPDMA_SetCHForAPBDevice(eDRVPDMA_CHANNEL_1,eDRVPDMA_UART0,eDRVPDMA_READ_APB); //指定PDMA1为UART0的接收
  55.     sPDMA.sSrcCtrl.u32Addr = UART0_BASE;  //源地址为UART0 FIFO
  56.     sPDMA.sDestCtrl.u32Addr =(uint32_t)RX_BUFF ;  //目的地址为接收BUFF
  57.     sPDMA.u8TransWidth = eDRVPDMA_WIDTH_8BITS;
  58.     sPDMA.u8Mode = eDRVPDMA_MODE_APB2MEM;  //外设到内存模式
  59.     sPDMA.sSrcCtrl.eAddrDirection = eDRVPDMA_DIRECTION_FIXED; //源地址固定
  60.     sPDMA.sDestCtrl.eAddrDirection =   eDRVPDMA_DIRECTION_INCREMENTED;  //目的地址增长
  61.     sPDMA.i32ByteCnt = DMA_LENTH;  //一次DMA长度4字节
  62.     DrvPDMA_Open(eDRVPDMA_CHANNEL_1,&sPDMA);  //配置DMA CH1参数
  63.     DrvPDMA_EnableInt(eDRVPDMA_CHANNEL_1, eDRVPDMA_BLKD );
  64.     DrvPDMA_InstallCallBack(eDRVPDMA_CHANNEL_1,eDRVPDMA_BLKD,(PFN_DRVPDMA_CALLBACK)PFN_DRVPDMA1_callback);
  65. }
  66. /**************************************************************** Function name:       main
  67. ** Descriptions:        usart
  68. ** input parameters:    无
  69. ** output parameters:   无
  70. ** Returned value:      无
  71. *************************************************************/
  72. int main (void)
  73. {
  74. Set_System(); //封装一些初始化模块

  75. PDMA0_Configuration(); //配置发送DMA
  76. PDMA1_Configuration(); //配置接收DMA
  77. DrvPDMA_CHEnableTransfer(eDRVPDMA_CHANNEL_1); //开始接收
  78. while(1)
  79. {
  80.   ;
  81. }
  82. }
工程压缩包:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
xyz549040622 发表于 2012-6-24 22:50 | 显示全部楼层
顶,没用过PDMa
chenshichao541 发表于 2012-6-28 12:20 | 显示全部楼层
顶一下,没用过,呵呵.....
 楼主| jxc827 发表于 2012-7-6 22:44 | 显示全部楼层
自己顶一个
litongda 发表于 2012-8-1 14:53 | 显示全部楼层
那个R5,R6电阻为什么要焊掉才能显示啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

53

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部