11442|4

862

帖子

2

TA的资源

纯净的硅(初级)

楼主
 

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

      本次实现的功能时配置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组数据,数据长度不一,接收到数据后原样通过串口再发送给上位机。

此帖出自GD32 MCU论坛

最新回复

正好也想着通过dma和空闲中断实现串口数据的收发处理   详情 回复 发表于 2023-8-24 20:27
点赞 关注(2)
个人签名水不撩不知深浅 人不拼怎知输赢
 

回复
举报

1

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
楼主可否发下整个代码工程文件作下参考呢? 164227186@qq.com   
此帖出自GD32 MCU论坛

点评

见第六弹  详情 回复 发表于 2018-12-10 13:29
 
 
 

回复

862

帖子

2

TA的资源

纯净的硅(初级)

板凳
 
Lls159152 发表于 2018-12-7 15:51
楼主可否发下整个代码工程文件作下参考呢?

见第六弹
此帖出自GD32 MCU论坛
 
个人签名水不撩不知深浅 人不拼怎知输赢
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

4
 

谁还有示例代码吗?

此帖出自GD32 MCU论坛
 
 
 

回复

16

帖子

0

TA的资源

一粒金砂(中级)

5
 

正好也想着通过dma和空闲中断实现串口数据的收发处理

此帖出自GD32 MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表