串口控制台输出

开发单片机与开发 PC 机上软件最大的一点不同就是不像 PC 上,有丰富的调试手段。虽然今天调试器非常先进,只要有配套的 IDE,单步、断点调试已经和 PC 上体验差距不大[1],但 PC 上非常常见的日志功能在单片机上却不那么好实现。

用 ADS 在 AURIX 上在线仿真甚至能看到变量赋值滞后于程序指针的现象,也就是第 N 条语句给变量赋值,单步执行到 N+K 步变量值才实际改变。我只在调试中偶然观察到这个现象,没有仔细研究,猜测应该是由于 CPU 流水线比较深的缘故。
当然 PC 上的 printf std::cout Console.WriteLine……这类东西好用也只是 PC 上的标准库封装的好而已,不能算是天经地义的。

最常用来模拟 PC 上输入输出的是串口 UART。不同于 I2C、SPI、USB 等接口,UART 没有时钟线,用一根 R 线收、一根 T 线发。如果单片机只往外发日志,甚至可以只连一根线。由于它主要用于两设备之间点对点的通信,不形成总线,所以这种设计简单明了,也没有性能损失(当然,如果要让一个接口带多个设备就得加片选线,而且也是上下行分别加)。在 AURIX 上,200 MHz 主频下,输入串口模块的为 100 MHz,能够支撑 6.25 MHz 的串口波特率,相比常见的 9600、115200 简直不知高到哪里去了。

72 MHz 主频的 STM32F10x 系列一般支持 4.5 MHz 波特率。

实现

iLLD 提供了非常方便的仿控制台输出函数(只有输出没有输入,输入在 Shell 模块里,相对复杂一些),只需要把串口配置好,再用一个函数就可以将串口与全局的控制台对象绑定,享受 printf 的 format 功能。

只需要声明一个初始化函数:

#ifndef UART_CONSOLE_H
#define UART_CONSOLE_Hvoid initConsole(void);#endif // UART_CONSOLE_H

实现文件:

#include "ASCLIN_Shell_UART.h"#include "IfxAsclin_Asc.h"
#include "Ifx_Console.h"#define ISR_PRIORITY_ASCLIN_TX 8
#define ISR_PRIORITY_ASCLIN_RX 4
#define ISR_PRIORITY_ASCLIN_ER 12
#define ASC_TX_BUFFER_SIZE 64
#define ASC_RX_BUFFER_SIZE 64
#define ASC_BAUDRATE 6180000static IfxStdIf_DPipe stdio;static uint8 g_uartTxBuffer[ASC_TX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
static uint8 g_uartRxBuffer[ASC_RX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];// 初始化串口模块
void initConsole(void) {IfxAsclin_Asc_Config ascConf;// 默认初始化IfxAsclin_Asc_initModuleConfig(&ascConf, &MODULE_ASCLIN0);// 设置波特率// 过采样率∈[4,16]ascConf.baudrate.baudrate = ASC_BAUDRATE;ascConf.baudrate.oversampling = IfxAsclin_OversamplingFactor_16;// 采样模式:采1点或采3点// 取样位置:1点到15点(应该对应16倍过采样)ascConf.bitTiming.medianFilter = IfxAsclin_SamplesPerBit_three;ascConf.bitTiming.samplePointPosition = IfxAsclin_SamplePointPosition_8;// 中断向量和优先级配置ascConf.interrupt.txPriority = ISR_PRIORITY_ASCLIN_TX;ascConf.interrupt.rxPriority = ISR_PRIORITY_ASCLIN_RX;ascConf.interrupt.erPriority = ISR_PRIORITY_ASCLIN_ER;ascConf.interrupt.typeOfService = IfxSrc_Tos_cpu0;// 管脚配置const IfxAsclin_Asc_Pins pins = {// 关闭 CTS 和 RTS 引脚.cts = NULL_PTR,.ctsMode = IfxPort_InputMode_pullUp,.rts = NULL_PTR,.rtsMode = IfxPort_OutputMode_pushPull,// RX 和 TX 使用集成在调试管脚中的 P14.1 和 P14.0.rx = &IfxAsclin0_RXA_P14_1_IN,.rxMode = IfxPort_InputMode_pullUp,.tx = &IfxAsclin0_TX_P14_0_OUT,.txMode = IfxPort_OutputMode_pushPull,// 驱动模式和速率(默认值).pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1};ascConf.pins = &pins;// 缓冲区配置ascConf.txBuffer = g_uartTxBuffer;ascConf.txBufferSize = ASC_TX_BUFFER_SIZE;ascConf.rxBuffer = g_uartRxBuffer;ascConf.rxBufferSize = ASC_RX_BUFFER_SIZE;// 初始化串口模块 -> 初始化标准输入输出流 -> 初始化标准控制台IfxAsclin_Asc asclin;IfxAsclin_Asc_initModule(&asclin, &ascConf);IfxAsclin_Asc_stdIfDPipeInit(&stdio, &asclin);Ifx_Console_init(&stdio);
}IFX_INTERRUPT(asc0TxISR, 0, ISR_PRIORITY_ASCLIN_TX) {IfxStdIf_DPipe_onTransmit(&stdio);
}IFX_INTERRUPT(asc0RxISR, 0, ISR_PRIORITY_ASCLIN_RX) {IfxStdIf_DPipe_onReceive(&stdio);
}IFX_INTERRUPT(asc0ErrISR, 0, ISR_PRIORITY_ASCLIN_ER) {IfxStdIf_DPipe_onError(&stdio);
}

AscLin 这个词意思是 UART+SPI+LIN,这是三种在汽车里常用的(相对 CAN 简单的通信接口)简单接口。由于有一些可以复用的电路,AURIX 把这三种接口做成了一个模块,可以通过配置选择,不过暂时我只会用它的 UART 功能。

可以看到需要配置的东西比较简单,除了过采样率、采样点位置和数量一般用 UART 不会太在意之外,波特率、中断向量、管脚和缓冲区都是非常常规的配置了。实际上我进去看了一眼,默认初始化的时候除了管脚、中断向量和缓冲区之外,其他参数都有默认值:

  • 默认波特率=115200
  • 默认过采样倍数=4(手册介绍取值范围 [4,16])
  • 默认采样模式为1点采样
  • 默认采样位置=3

这些配置主要影响速率和高速率下的抗干扰能力,由于我想实验一下最高能达到什么效果,就都配置成了最稳妥的模式。

P14.0 和 P14.1 这两个脚也非常方便,它俩包括在调试器的 10 个脚里,也就是说调试器插到电脑上会映射两个设备:调试器本体和一个 USB 转串口,就不需要我们额外再插 USB 转串口了。

实验

初始化后打开中断,发送也直接调用库函数即可:

uint32 i = 0;
while (1) {Ifx_Console_print("Hello, world!(%d)n", i++);waitTime(TimeConst_1s);
}

不知道为什么 STM32 总有种改 printf 的执念,搞得很复杂,直接换一个函数名不也挺好的吗?Ifx_Console_print 这个函数提供了 format 的功能,直接调用即可。

经过实测,最大的波特率可以写道 6'180'000,即 6.18 MHz,再高的话似乎是被调试器上的 USB 转串口限制了。我尝试了用 6250000 发,也只能用 6180000 收(收到是对的,估计 8 位一同步能应付这种程度的时钟不准),串口助手的配置只要超过这个值就收不到了。不过差的不多,也就差了 7 个 9600 吧……

串口助手如图所示:

顺便说一句,这个友善串口调试助手是个国产软件,制作非常良心,各种功能都非常好用。比如可以不关串口直接修改波特率等设置(应该是后台重新初始化了,但很快,感觉不到暂停),大家有需要可以去官网免费下载:

Alithon​www.alithon.com

参考

  1. ^尴尬,知乎这编辑器怎么只能添加注释不能删除注释啊

为什么printf可以直接uart输出_AURIX 学习笔记(6)标准库中串口控制台输出相关推荐

  1. 【JavaScript学习笔记2】JS中常见的输出方式-控制台输出信息

    引言 在编程开发的过程中,输出信息是非常必要的.JS中提供了四种输出方式:弹出显示框.控制台输出.弹出输入框.弹出判断显示框 弹出显示框 这种方式在上一篇笔记中已经详细介绍,有需要学习的朋友可以跳转到 ...

  2. Go语言学习笔记—golang标准库xml包

    文章目录 一 核心函数 1.1 将struct转码成xml 1.2 将xml转码成struct 二 核心结构体 2.1 从输入流读取并解析xml 2.2 写xml到输出流 三 综合实例 3.1 将st ...

  3. Go语言学习笔记—golang标准库log包

    文章目录 一 log简介 二 log简单使用 2.1 log.Print/Println/Printf函数 2.2 log.Panic/Panicf/Panicln函数 2.3 log.Fatal/F ...

  4. 【C++学习笔记】标准库类型vector

      标准库类型vector表示对象的集合,其中多有对象的类型都相同,集合中的每个对象都有一个与之对象的索引用来访问对象,需要注意的是引用不是对象,所以不存在包含引用的vector,因其用来容纳着其他对 ...

  5. 【C++学习笔记】标准库类型string

      标准库类型string表示可变长的字符序列,使用string类型必须先包含string头文件,string定义在命名空间std. #include <string> using std ...

  6. Go语言学习笔记—golang标准库builtin包

    文章目录 一 常用函数 1.1 append 1.2 len 1.3 print.println 二 重点常用函数 2.1 panic 2.2 new和make 2.2.1 new 2.2.2 mak ...

  7. Go语言学习笔记—golang标准库math包

    文章目录 一 常量 二 常用函数 2.1 IsNaN函数 2.2 Ceil函数 2.3 Floor函数 2.4 Trunc函数 2.5 Abs函数 2.6 Max函数 2.7 Min函数 2.8 Di ...

  8. Android(java)学习笔记133:Eclipse中的控制台不停报错Can't bind to local 8700 for debugger...

    [DDMS] Can't bind to local 8600 for debugger  经常出现这种问题,这是因为电脑中某个进程占了8600的端口,可能是电脑分配进程占用这个8600端口(这个进程 ...

  9. Go语言开发学习笔记(持续更新中)

    Go语言开发学习笔记(持续更新中) 仅供自我学习 更好的文档请选择下方 https://studygolang.com/pkgdoc https://www.topgoer.com/go%E5%9F% ...

最新文章

  1. Real World Kanban作者访谈
  2. 计算机右键管理中没有用户管理,我的电脑右键菜单中没有管理选项如何解决? 我的电脑右键菜单中没有管理选项解决的方法有哪些?...
  3. codeforces G - Almost Increasing Array 动态规划、动态开点线段树
  4. python实时读plc数据_python snap7读写西门子S系列PLC寄存器的值(PLC的I、Q、M、DB区)...
  5. 长短期记忆网络_思维导图:长短期记忆模型
  6. linux man 手册翻译,close (linux man) 翻译
  7. observable java_java源码阅读Observable(观察者模式)
  8. JQuery动态增加删除元素
  9. html 两个表合并,SQL中将两个表合并成一个新表
  10. 【译】Jep 文档(2)——基本用法(Basic Usage)
  11. C语言ascll码表值和字符的互相转换的程序
  12. RGB颜色 取色器/拾色器 颜色混搭
  13. Vue实战笔记(一) 引入Ant Design
  14. int 几个字节 java_java中int是几个字节
  15. grub.exe和grldr的区别和联系
  16. 解决everything只能搜索C盘的问题
  17. C++上机实验六第2题
  18. win7/win10上安装谷歌官方无广告的安卓模拟器 - Android Studio - 下载安装AVD虚拟机
  19. Rouge的安装与使用
  20. Win10应用商店、应用打不开或闪退的解决方法

热门文章

  1. 机器学习中的生成模型与判别模型
  2. win10安装CCSv8,mcsdk,seedxds560v2,软仿
  3. win10防火墙删除的文件在哪里_Win10系统瘦身指南:删除C盘这些文件,让你的电脑秒变新机!...
  4. D. The Enchanted Forest
  5. Python3+Selenium3自动化测试框架——②流程梳理及代码封装
  6. QQ安全防护驱动(QQProtect)彻底删除方法
  7. 魔兽世界是用什么语言写的
  8. godaddy添加域名解析
  9. 达人评测 小米ea552022款怎么样
  10. Win7让老P4焕发青春