0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

串口是如何发送数据和接收数据的?

STM32嵌入式开发 ? 来源:可以吃的鱼 ? 作者:可以吃的鱼 ? 2021-06-21 15:23 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

串口发送数据

1、串口发送数据最直接的方式就是标准调用库函数 。

voidUSART_SendData(USART_TypeDef*USARTx,uint16_tData);

第一个参数是发送的串口号,第二个参数是要发送的数据了。但是用过的朋友应该觉得不好用,一次只能发送单个字符,所以我们有必要根据这个函数加以扩展:


pYYBAGDRpwmAcoybAABzkOBzWrA152.jpg

以上程序的形参就是我们调用该函数时要发送的字符串,这里通过循环调用USART_SendData来一 一发送我们的字符串。

poYBAGDRpxOAAGVXAAAudgxUhs8213.jpg

这句话有必要加,他是用于检查串口是否发送完成的标志,如果不加这句话会发生数据丢失的情况。这个函数只能用于串口1发送。有些时候根据需要,要用到多个串口发送那么就还需要改进这个程序。如下:

poYBAGDRpx2AQPKPAABvQN8sIgk200.jpg

这样就可实现任意的串口发送。但有一点,我在使用实时操作系统的时候(如UCOS,Freertos等),需考虑函数重入的问题。

当然也可以简单的实现把该函数复制一下,然后修改串口号也可以避免该问题。然而这个函数不能像printf那样传递多个参数,所以还可以在改进,最终程序如下:

pYYBAGDRpy2ADfuUAAD8g70VFrA165.jpg

poYBAGDRpzWADfm4AADFeTcylJg666.jpg

poYBAGDRpzyAClCqAADOfBkvaEQ370.jpg

该函数就可以像printf使用可变参数,方便很多。通过观察函数但这个函数只支持了%d,%s的参数,想要支持更多,可以仿照printf的函数写法加以补充。

2、 直接使用printf函数。

很多朋友都知道想要STM32要直接使用printf不行的。需要加上以下的重映射函数:

如果不想添加以上代码,也可以勾选以下的Use MicroLI选项来支持printf函数使用:

串口接收数据

串口接收最后应有一定的协议,如发送一帧数据应该有头标志或尾标志,也可两个标志都有。

这样在处理数据时既能能保证数据的正确接收,也有利于接收完后我们处理数据。串口的配置在这里就不在赘述,这里我以串口2接收中断服务程序函数且接收的数据包含头尾标识为例。

pYYBAGDRp32AZJjDAAFTP7axwgU371.jpg

数据的头标识为“ ”,即换行符,尾标识为“+”。该函数将串口接收的数据存放在USART_Buffer数组中,然后先判断当前字符是不是尾标识,如果是说明接收完毕,然后再来判断头标识是不是“+”号,如果还是那么就是我们想要的数据,接下来就可以进行相应数据的处理了。但如果不是那么就让Usart2_Rx=0重新接收数据。

这样做的有以下好处:

可以接受不定长度的数据,最大接收长度可以通过Max_BUFF_Len来更改

可以接受指定的数据

防止接收的数据使数组越界

这里我的把接受正确数据直接打印出来,也可以通过设置标识位,然后在主函数里面轮询再操作。

以上的接收形式,是中断一次就接收一个字符,这在UCOS等实时内核系统中频繁的中断,非常消耗CPU资源,在有些时候我们需要接收大量数据时且波特率很高的情况下,长时间中断会带来一些额外的问题。

所以以DMA形式配合串口的IDLE(空闲中断)来接受数据将会大大的提高CPU的利用率,减少系统资源的消耗。首先还是先看代码。

poYBAGDRp5uAGh91AAFaABY78iQ338.jpg

之前的串口中断是一个一个字符的接收,现在改为串口空闲中断,就是一帧数据过来才中断进入一次。而且接收的数据时候是DMA来搬运到我们指定的缓冲区(也就是程序中的USART1_RECEIVE_DMABuffer数组),是不占用CPU时间资源的。

最后在讲下DMA的发送:

poYBAGDRp7KARX87AACHqPG_k34918.jpg

这里需要注意下DMA_Cmd(DMA1_Channel4,DISABLE)函数需要在设置传输大小之前调用一下,否则不会重新启动DMA发送。

有了以上的接收方式,对一般的串口数据处理是没有问题的了。下面再讲一下,在ucosiii中我使用信号量+消息队列+储存管理的形式来处理我们的串口数据。先来说一下这种方式对比其他方式的一些优缺点。

一般对串口的处理形式是"生产者"和"消费者"的模式,即本次接收的数据要马上处理,否则当数据大量涌进的时候,就来不及"消费"掉生产者(串口接收中断)的数据,那么就会丢失本次的数据处理。所以使用队列就能够很方便的解决这个问题。

在下面的程序中,对数据的处理是先接受,在处理,如果在处理的过程中,有串口中断接受数据,那么就把它依次放在队列中,队列的特征是先进先出,在串口中就是先处理先接受的数据,所以根据生产和消费的速度,定义不同大小的消息队列缓冲区就可以了。缺点就是太占用系统资源,一般51单片机是没可能了。下面是从我做的项目中截取过来的程序:

poYBAGDRp-eAEuklAAHjGbmF_nI461.jpg

pYYBAGDRp--ATaPXAAFKbXT8Hbw965.jpg

上面被注释掉的代码为我是为了防止当分区中没有空闲的存储块时加入信号量,打印出报警信息。当然我们也可以将存储块直接设置大一点,但是还是无法避免当没有可有存储块时会程序会崩溃现象。希望懂的朋友能告知下~。

下面是串口数据处理任务,这里删去了其他代码,只把他打印出来了而已。

pYYBAGDRqB2AanMLAAFhDyqm3W8055.jpg

责任编辑:lq6

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 串口
    +关注

    关注

    15

    文章

    1593

    浏览量

    80485
  • 接收数据
    +关注

    关注

    0

    文章

    7

    浏览量

    6253

原文标题:STM32串口发送数据和接收数据方式总结

文章出处:【微信号:c-stm32,微信公众号:STM32嵌入式开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CYT2B7串口接收会漏接数据怎么解决?

    串口中断方式接收会漏接数据串口工具发送 :1234567芯片接收到 :1357硬件是CYTVI
    发表于 08-14 07:29

    STM32串口发送数据,USART_FLAG_TC无法置位怎么解决?

    STM32串口发送数据,在经过一段时间的数据发送,大概200ms发送一下,一次
    发表于 07-29 11:44

    【RA-Eco-RA4M2开发板评测】使用RA4M2的串口实现任意任意类型任意长度的数据接收,并将接收到的数据显示在串口助手上

    一帧完整的数据串口发送数据有长有短,如果没有接收完整,肯定会影响后续业务的处理。为了接收
    发表于 05-04 14:11

    为UART、MCXA142实现ISP通信的主机端,发送Ping数据包并收到预期的响应,发送接收数据包的典型顺序是什么?

    我想为 UART、MCXA142 实现 ISP 通信的主机端。我发送 Ping 数据包并收到预期的响应。发送接收数据包的典型顺序是什么?
    发表于 04-03 08:05

    STM32F427串口接收发送中断同时使能,为什么会出现接收中断丢数的情况?

    STM32F427芯片,针对UART7开启串口接收缓存区非空中断RXNE和串口传输完成中断TC. 1.单测试收发都没有任何问题。 2.将串口与PC机连接,PC端通过
    发表于 03-11 07:05

    串口数据错乱?从标志位设置入手

    导读在串口通信开发中,数据错乱是常见问题。本文将快速介绍串口标志位的作用及配置方法,帮助解决数据传输错误。有用户反馈“串口应用层
    的头像 发表于 02-11 11:35 ?1001次阅读
    <b class='flag-5'>串口</b><b class='flag-5'>数据</b>错乱?从标志位设置入手

    ADC124S021用硬件SPI时,串口发送数据一直是0000,为什么?

    用G2553作为控制芯片,用IO口模拟SPI与ADC124S021通信时,再通过串口发送数据,没有问题。但是用硬件SPI时,串口发送
    发表于 12-31 06:17

    使用TSS721过程中,只能接收数据不能发送数据怎么解决?

    在使用TSS721过程中,只能接收数据,不能发送数据。手册中写会有自发自收的现象,这个现象该怎么样解决呢?
    发表于 12-17 06:33

    串口通信设备连接方法 串口通信在嵌入式开发中的应用

    硬件连接 串口通信通常涉及两个设备:一个发送器和一个接收器。连接这两个设备需要以下步骤: 选择正确的接口 :确保发送器和接收器的接口类型相
    的头像 发表于 11-22 09:07 ?2986次阅读

    为什么通信要使用虚拟串口串口助手?

    串口助手和虚拟串口是什么?串口助手和虚拟串口串口通信中很常见。串口助手是用于
    的头像 发表于 11-15 01:04 ?3943次阅读
    为什么通信要使用虚拟<b class='flag-5'>串口</b>和<b class='flag-5'>串口</b>助手?

    【代码分享】基于乐鑫ESP32的串口不定长数据接收方法

    【代码分享】基于乐鑫ESP32的串口不定长数据接收方法
    的头像 发表于 11-15 01:02 ?1579次阅读
    【代码分享】基于乐鑫ESP32的<b class='flag-5'>串口</b>不定长<b class='flag-5'>数据</b><b class='flag-5'>接收</b>方法

    ADS8689接收数据怎么和发送数据一样?为什么?

    读取地址14h,发送0xC8140000,并在下一帧读取数据,得到C8140000?
    发表于 11-13 08:13

    socket 发送接收数据方法

    1. Socket 基本概念 在网络编程中,socket 是一个通信端点。它允许程序发送接收数据。根据通信协议的不同,socket 可以分为以下几种类型: 流式 socket
    的头像 发表于 11-12 14:07 ?2024次阅读

    当AIC3204做master模式时,发送正常,但是接收时没有数据产生,为什么?

    使用C5517EVM,AIC3204做slave模式,数据接收发送正常,此时BCLK,WCLK都有DSP提供。 当AIC3204做master模式时,发送正常,但是接收时没有
    发表于 10-23 08:03

    使用STM32通过串口向PGA460芯片发送数据,PGA460没有任何数据回复怎么解决?

    、配套软件,PGA460是能够正常工作的 但是使用STM32,通过串口,向PGA460芯片发送数据,PGA460没有任何数据回复 为BOOSTXL-PGA460上的PGA460模块供电
    发表于 10-11 07:35