[经验分享] GD32F350--体验之四(串口Usart之使用DMA发送)

RCSN   2018-8-30 22:52 楼主
上贴的串口收发是使用阻塞式收发,虽然也可以正常运行,但是对于实时性来说,还是非阻塞发送比较好点。这里楼主采用的是使用串口DMA发送,如何判断发送成功呢,就是使能发送完成中断,在中断上加以发送成功标志位来此判断发送成功,也就是说我只要把数据塞给DMA,即可不需要MCU去干预。这样对于发送的效率也就大大提高。
这里的编程思路主要参考官方的参考手册的“采用DMA方式实现Usary数据发送配置步骤”图。在这里我写了通用F350的两个串口,初始化的时候只要传入相对应的串口,即可使用相对应的串口进行DMA发送,当然两个都初始化同样也能使用。
   2343.png
1084534438 欢迎交流  [加油,一切皆有可能]

回复评论 (15)

那么楼主先分享下所做的BspUsart文件的头文件,这个通过F350的两个串口。都可以利用同样的接口进行初始化以及发送接口。
445.png
  在这里说明下USART0_TDATA_ADDRESS宏定义的意思,以此类推可以分析下其他三个的宏定义。F350的两个串口的存储器映射地址为下图:
1.png
2.png

3.png
   由此我们可以知道发送数据寄存器的地址即是0x40013828。这样的宏定义的意义在于,如果不同平台下的偏移地址不同,我们可以方便修改参数。
   USART0_MAX_SEND_LEN是缓冲大小,再者我们在定义发送缓冲区大小的时候,可以通过宏定义来定义大小,这样同样也可以方便修改参数。
  下面的一些宏上,比如COM_DMAn是用来定义DMA所使用的通道数量,这里是参考官方的编程思路,我觉得不错,也照样采取。这样在初始化的时候,可以通过数组方式查找相对应的DMA通道,比如在初始化中,传参是串口1,则使用COM1_DMA,也就是DMA通道3。
   下面那些接口,也相对做了通用接口,以及两个重定向printf发送接口。均采用DMA进行发送


1084534438 欢迎交流  [加油,一切皆有可能]
点赞  2018-8-30 23:09
学习了
点赞  2018-8-30 23:16
那么楼主继续解析GD32的串口DMA是如何初始化的,我这里初始化串口外设,还是使用官方的gd32f3x0_eval.c文件的gd_eval_com_init函数接口,只是官方的接口把波特率设置完全写死,这里我使用baud作为传参,这样可以初始化得时候方便调整波特率。 345.png 在这里我又加入了串口0的支持,支持了两个串口的外设初始化。 566.png 123124.png 本帖最后由 RCSN 于 2018-8-30 23:22 编辑
1084534438 欢迎交流  [加油,一切皆有可能]
点赞  2018-8-30 23:16
调整好之后,我们需要在使用下DMA,这里我使用的是官方的串口DMA发送例子的DMA初始化部分,验证也是没问题的。在使用之前一定要使能DMA时钟,这点细节我差点忘了,不使能时钟发送不了。两个串口的发送DMA通道并不一样,详细可看数据手册,这里楼主的UsartDmaSendInit支持串口1和串口0的DMA初始化。之后禁止循环模式,并不需要自动装载DMA的计数寄存器,所以在发送的时候需要手动加载这个计数寄存器,也就是你要发送的数据长度。这样能保证数据发送无误。之后再使能DMA通道,要注意的是,当使能了相对应的DMA通道,相关的寄存器位是不允许操作配置的,比如数据地址配置到DMA基地址寄存器、计数器等等都不允许操作。   123455.png
   楼主的代码如下,DMA初始化部分之所以定义为静态函数,是由于除了本文件需要使用,外部的文件并不需要使用。头文件的函数声明都为外部文件需要用的接口。
4325435.png

1084534438 欢迎交流  [加油,一切皆有可能]
点赞  2018-8-30 23:32
那么DMA初始化完成之后,即可进行下一步,清除发送完成标志,并且使能发送完成中断。所以楼主的串口初始化就是做了以上的相关配置。
1234.png
1084534438 欢迎交流  [加油,一切皆有可能]
点赞  2018-8-30 23:35
  按照前面的官方的思路图,我们建立一个静态全局变量,来确定是否发送完成。这个标志位主要是在发送时候和发送完成的时候翻转状态的。
  static uint8_t DMA_Send_ComFlag = 1; //串口发送标志,为1准备发送,为2发送完成
456.png
  在截图中可看,根据上述的描述,完成一次发送。不需要进行阻塞判断DMA或者串口的发送标志,标志交给中断处理。提高了实时性。但是不要在连续语句当中使用发送接口,这样会导致发送完成中断还未到导致其余的发送不成功。要么就是同个发送接口发送多点数据。
1084534438 欢迎交流  [加油,一切皆有可能]
点赞 (1) 2018-8-30 23:42
接口实现效果如下。下按按键,连续发送数据,不丢包, P80830-235013.gif 本帖最后由 RCSN 于 2018-8-30 23:52 编辑
1084534438 欢迎交流  [加油,一切皆有可能]
点赞  2018-8-30 23:44
   下一个体验,使用串口接收硬件FIFO+接收中断+空闲中断+块尾中断接收一帧完整的modbus协议数据。
123434.png


1084534438 欢迎交流  [加油,一切皆有可能]
点赞  2018-8-30 23:46
这么好的帖子居然没有人跟帖...
水不撩不知深浅 人不拼怎知输赢
点赞  2018-9-1 22:16
引用: wo4fisher 发表于 2018-9-1 22:16
这么好的帖子居然没有人跟帖...

哈哈。可能大家都知道这玩意吧
1084534438 欢迎交流  [加油,一切皆有可能]
点赞  2018-9-2 00:23
自定义串口全局中断是什么?
点赞  2019-5-8 15:39
接收硬件FIFO有多大
点赞  2019-5-10 09:41

自定义串口全局中断是什么?

点赞  2019-12-14 21:31

沙发,现在就试

点赞 (1) 2021-7-30 11:04

质量很高的帖子,而且五年了楼主还作了更新,很有收获

点赞  2023-8-24 14:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复