| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> 嵌入式 -> 关于串口发送的重定向 -> 正文阅读 |
|
|
[嵌入式]关于串口发送的重定向 |
|
这一节我们讲一讲怎样将串口的输出重定向到printf。 对应printf这个函数大家一定非常熟悉,这个函数用于打印输出。一般c语言编程的入门程序,就是用printf打印hello world。 而在单片机中,裸机编程的条件下,并没有一套直接可以调用的打印输出函数,需要我们自己去实现。 这里我们以之前实现的串口为基础,在它上面改写,实现串口输出的数据从printf函数输出。 1)轮询形式的串口重定向到printf printf函数是在stdio.h文件中定义的,它又会调用更底层的fputc这个函数,去一个个地打印出字符;所以,我们只要将fputc函数实现,就可以使用printf函数方便地输出了。 具体实现的代码如下:
其实质就是把串口发送一个字符的函数,封装到了fputc函数中。 这样我们再设置一下工程,选上lib,就设置好了:
之后就可以直接调用printf函数了,代码和运行情况见下图:
可以看出,printf函数的功能它都已经具备了,可以打印字符串、整型数、也可以打印转义字符。 上述的使用方法虽然很简单、很方便,但是有个致命的问题,效率不高,因为它重写fputc函数的时候,使用的是轮询的方法,执行这个函数的时候,几乎需要一直等到串口数据完全发完才能向后执行。 由于这个fputc函数每调用一次是发送一个字符,直接用HAL_UART_Transmit_IT中断或DMA发送的函数也是不行的;因为cubemx生成的中断或DMA发送的实现方式,是一次性只能发送一串数据,再次调用时,要等到上次的一串数都发完,才能正确发送下一次。对于fputc这种每发送一个字符要调用一次的用法,中断发送、DMA发送和轮询发送的效率是一样的,几乎都是要一直等到所有数据都发完。 2)发送中断和fifo实现的方法 一种提高效率的办法是使用发送fifo缓冲区,例如我们之前讲到的方法:将要发送的数据都放入fifo,由发送完中断自动从fifo中取数发送,这样就不用一直等到数据发完。下次有新数据来时,也是填入fifo中,不需要等待。 例如在我们之前改写的uart中断和fifo的工程下,如下改写fputc就可以了。
其中send_uart_byte函数内部实现过程大致如下: (具体实现过程可以参见我之前的文章《串口中断和fifo环形队列》的讲解)
然后就可以调用printf函数使用了。这种实现方法效率高,只要发送fifo不溢出,使用基本没有什么限制,是非常方便的。 3)自己编写重定向函数 另一种方法是自己编写一个重定向的函数。既然标准的重定向函数fputc的用法受限,那么我们可以自己定义一个函数,去实现printf的功能,底层实现时跳过fputc的限制。 在usart.c文件中添加如下代码:(定义数组 print_temp 时也可以更大一些以免溢出)
这部分代码实际上是将要发送的一串数据,转存到了printf_temp中,然后再使用HAL_UART_Transmit_IT发送出去(使用DMA方式也是可以的),这样就不用等到每个字符都发送完。 然后就可以使用Uart1_printf这个函数了,用法和printf函数一样,如下图:
但是,仍然需要注意的是,HAL_UART_Transmit_IT这个函数连续发送两串数据时,仍然需要等待前一串数据发完才能发送后一串,否则后面的数据会丢失。 如下图,连续调用两次printf,后一次的数据有可能会覆盖到第一次的数据上:
综合上述的几种方法,我们可以选择自己最合适的实现方式: 如果系统简单,串口一直等待也无妨,就使用方法1,实现起来最简单;如果系统里不会短时间调用两次printf可以使用方法3,这样可以提高效率;如果可能发生短时间多次调用printf,而且追求高效率,可以使用方法2,但是改写和添加的代码会多一些。 好了,这一节就讲到这里。 欢迎大家关注我的公众号,更多学习资源分享:
|
|
|
| 嵌入式 最新文章 |
| 基于高精度单片机开发红外测温仪方案 |
| 89C51单片机与DAC0832 |
| 基于51单片机宠物自动投料喂食器控制系统仿 |
| 《痞子衡嵌入式半月刊》 第 68 期 |
| 多思计组实验实验七 简单模型机实验 |
| CSC7720 |
| 启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
| STM32初探 |
| STM32 总结 |
| 【STM32】CubeMX例程四---定时器中断(附工 |
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年12日历 | -2025/12/1 5:25:12- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |