注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题

wo4fisher的个人空间 http://home.eeworld.com.cn/space-uid-296469.html [收藏] [复制] [分享] [RSS]

日志

[GD32F350]第三弹:USART使用DMA+IDLE中断方式不定长字节数据收发

已有 175 次阅读2018-9-8 21:41 |个人分类:GD32

      本次实现的功能时配置gd32实现usart+dma实现串口收发数据,接收使用IDLE中断来实现接收不定长数据字节。
一、硬件简介
1、1       DMA简介(配图)
1、2       DMA操作简介(配图)
1、3       DMA通道配置(配图)
1、4       DMA请求映射及个通道请求表(配图)
1、5       DMA寄存器(配图)
每个通道有下边一组6个寄存器。
二、功能实现
2.1可以借鉴的例程(配图)
图中usart_printf例程实现了串口使用printf格式化输出,程序包含串口的基本初始化过程;05_USART_HyperTerminal_Interrupt实现了串口收发数据回环测试,使用了TBE和RBNE中断,程序包含串口的初始化过程、中断的使能过程已经中断服务函数的使用;06_USART_DMA实现了串口通过DMA方式发送和接收数据的数据回环测试,包含串口的初始化、DMA通道的配置过程、串口DMA方式发送数据和接收数据的配置过程。
2.2使用GD32官方库的功能实现
串口数据收发保存数据结构定义:
  1. #define RX_LEN 300  
  2. #define TX_LEN 300
  3. typedef struct
  4. {  
  5. uint8_t  RX_flag:1;        //IDLE receive flag
  6. uint16_t RX_Size;          //receive length   
  7. uint8_t  RX_pData[RX_LEN]; //DMA receive buffer
  8. }USART_RECEIVETYPE;
  9. typedef struct  
  10. {  
  11. uint8_t  TX_flag:1;        //IDLE tx flag
  12. uint16_t TX_Size;          //tx length   
  13. uint8_t  TX_pData[RX_LEN]; //DMA tx buffer
  14. }USART_TRANSBYTE;  
  15. USART_RECEIVETYPE Usart_ReceiveStruct;
  16. USART_TRANSBYTE   Usart_TransStruct;
复制代码
  1. USART_RECEIVETYPE Usart_ReceiveStruct;
  2. USART_TRANSBYTE   Usart_TransStruct;
复制代码

USART串口DMA发送指定长度数据函数:
  1. void UART_Transmit_DMA(uint8_t *pData, uint16_t Size)
  2. {
  3.     /*****************  DMA_TX_CONFIG   ****************/
  4.     dma_parameter_struct dma_init_struct;
  5.     /* enable the DMA clock */
  6.     rcu_periph_clock_enable(RCU_DMA);
  7.     /* configure the USART TX DMA channel */
  8.     dma_deinit(DMA_CH3);
  9.     dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
  10.     dma_init_struct.memory_addr = (uint32_t)pData;
  11.     dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  12.     dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  13.     dma_init_struct.number = Size;
  14.     dma_init_struct.periph_addr = USART1_TDATA_ADDRESS;
  15.     dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  16.     dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  17.     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  18.     dma_init(DMA_CH3, dma_init_struct);
  19.     /* configure DMA mode */
  20.     dma_circulation_disable(DMA_CH3);
  21.     dma_memory_to_memory_disable(DMA_CH3);
  22.     /*****************  END  DMA_TX_CONFIG  ****************/
  23.     /* enable the DMA channel1 and channel3 */
  24.     dma_channel_enable(DMA_CH3);
  25.     /* USART DMA enable for transmission */
  26.     usart_dma_transmit_config(EVAL_COM1, USART_DENT_ENABLE); //USART配置DMA发送
  27. }
复制代码

USART串口DMA方式接收数据函数实现:
  1. void UART_Receive_DMA(uint8_t *pData, uint16_t Size)
  2. {
  3.     /*****************  DMA_RX_CONFIG   ****************/
  4.     dma_parameter_struct dma_init_struct;
  5.     /* enable the DMA clock */
  6.     rcu_periph_clock_enable(RCU_DMA);

  7.     /* configure the USART RX DMA channel */
  8.     dma_deinit(DMA_CH4);
  9.     dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
  10.     dma_init_struct.memory_addr = (uint32_t)pData;
  11.     dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
  12.     dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
  13.     dma_init_struct.number = Size;
  14.     dma_init_struct.periph_addr = USART1_RDATA_ADDRESS;
  15.     dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
  16.     dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
  17.     dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
  18.     dma_init(DMA_CH4, dma_init_struct);
  19.     /* configure DMA mode */
  20.     dma_circulation_disable(DMA_CH4);
  21.     dma_memory_to_memory_disable(DMA_CH4);
  22.     /*****************  END  DMA_RX_CONFIG  ****************/
  23.     dma_channel_enable(DMA_CH4);
  24.     usart_dma_receive_config(EVAL_COM1, USART_DENR_ENABLE);  //USART配置DMA接收
  25. }
复制代码

串口中断服务函数实现:


  1.     UsartReceive_IDLE(&Usart_ReceiveStruct);
  2. }

  3. void UsartReceive_IDLE(USART_RECEIVETYPE *Usart_ReceiveStruct)
  4. {
  5.     if(usart_interrupt_flag_get(EVAL_COM1, USART_INT_FLAG_IDLE)) //检测到空闲线
  6.     {
  7.         usart_interrupt_flag_clear(EVAL_COM1, USART_INT_FLAG_IDLE);
  8.         dma_channel_disable(DMA_CH4);  //CHEN位为0时才能配置DMA
  9.         Usart_ReceiveStruct->RX_Size =  RX_LEN - dma_transfer_number_get(DMA_CH4);
  10.         Usart_ReceiveStruct->RX_flag = 1;
  11.         UART_Transmit_DMA(Usart_ReceiveStruct->RX_pData, Usart_ReceiveStruct->RX_Size);
  12.         UART_Receive_DMA(Usart_ReceiveStruct->RX_pData, RX_LEN);

  13.     }
  14. }
复制代码

       功能,把串口dma接收到的数据保存后,获取接收到的数据长度,然后再原样发送出去。

      结果见图:
图中为自定义10组数据,GD32接收后,返回上位机接收到的字符个数,带有时间戳。
图中为自定义10组数据,数据长度不一,接收到数据后原样通过串口再发送给上位机。

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2018-12-17 12:54 , Processed in 0.033690 second(s), 10 queries , Gzip On, MemCache On.

Powered by EEWORLD电子工程世界

© 2018 http://bbs.eeworld.com.cn/

返回顶部