c++ - 在微 Controller 上编写 UART 控制台时的 UTF-8 问题

标签 c++ utf-8 uart

我目前正在 ATMega1284p 上编写 uart 控制台。它应该回显字符,以便计算机端控制台实际看到正在键入的内容,现在就是这样。

问题是:使用 ASCII 时它工作得很好,但是如果我发送任何超出 ASCII 的内容,例如a '§' 我的迷你电脑显示“§” '�' 无效,或者 '§' 以防一切正常。但是将两者结合起来让我感到困惑,我目前不知道问题出在哪里!

这是我的代码的一部分:

    char c;
    while(m_uart->recv(c) > 0) {
        m_lineBuff[m_lineIndex++] = c;
        if(c == '\r') {
            c = '\n';
            m_lineBuff[m_lineIndex++] = c;
            m_sendCount = 2;
        } else {
            m_sendCount = 1;
        }
        this->send();
        if(c == '\n') {
            m_lineBuff[m_lineIndex++] = '\0';
            // invoke some callbacks that handle the line at some point
            m_lineIndex = 0;
        }
    }

m_lineBuff 是一个自行编写(并经过测试)的字符 vector 。 m_uart 是一个用于微型内部硬件 uart 的自编写(也经过测试)的 UART 驱动程序。 this->send 使用 m_uart 发送 m_sendCount 个字节。

到目前为止我尝试过的: 我验证了minicom的波特率和我的micro匹配(115200)。我验证频率在 2% 范围内(micro 运行在 20MHz)。 minicom 和 micro 均设置为 8n1。 我通过将 minicom 连接到我手边的一 block 小板上来验证它的工作原理。在该板上任何 utf-8 数字都可以正常工作。

有人看到我的错误吗?或者有人知道我没有考虑到什么吗?

如果你们对它感兴趣,我很乐意提供我的所有代码。

编辑/阐述:

观察 1(开始此项目之前)

PC端程序(minicom)可以发送和接收字符。来自微 Controller 。但它不显示发送的字符。

结论 1(开始该项目之前)

微 Controller 端需要将字符发送回PC,以便您拥有控制台的行为。 因此,我立即发回我收到的任何字符。

观察 2(实现后)

当我按“§”(或任何其他包含超过 1 个字节的字符)(使用 minicom)时,我会看到“�§”。

结论2(实现后)

发生了一些我无法用我的知识解释的事情。也许构成字符的两个字节之间的小延迟会导致 minicom 首先打印“�”,因为第一个字节本身确实是一个无效字符,当第二个字符进入 minicom 时,它意识到它实际上是“§”,但是minicom 不会删除/覆盖“�”。 如果这是问题所在,那么我该如何解决呢?我的微 Controller 是否需要在字符之间做出更快的 react /更少的延迟?

编辑2:

我替换了“?”使用复制和粘贴功能将实际字符“�”替换为实际字符“�”。

我做了更多测试

我尝试了“😹”这个字符,正如我所解释的(它支持我的结论 2),我得到了“���😹”。顺便说一下,'😹' 是一个 4 字节字符。 将 micro 和 minicom 的波特率设置为 9600:完全相同的行为。 我设法将 minicom 设置为十六进制模式:它定期发送但输出十六进制...当我发送 '😹' 时,我得到“f0 9f 98 b9”(至少根据 this site )是正确的...是支持吗我的结论2?更重要的是:我如何摆脱这种行为。它适用于我的小 Linux 板,而不是我的微 Controller 。

最佳答案

EDIT: the op discovered on his own that the odd behaviour he discovered is (probably) a bug of minicom itself. This post of mine clearly looses its value, unless the community thinks that it should be removed I would leave it here as a witness of possible workarounds when experiencing similar problems.


tl;dr:您的电脑应用程序可能无法正确解释UTF-8,正如它所显示的那样。


如果我们看看 ISO 8859-1 定义的扩展 ASCII 代码,

A7 10100111 § § => Section sign

根据这个page ,§ 的 UTF-8 编码为

U+00A7 § c2 a7 => SECTION SIGN

所以我的有根据的猜测是该符号仍然可以正确打印,因为它属于具有相同值a7扩展ASCII代码

您的最终应用程序无法正确解释 UTF-8 U (c2) 符号,这就是为什么您会得到 < em>? 打印出来,或者中间的组件无法向前传递正确的值。我倾向于相信您的输出是第一种情况的一个实例。


您声称minicom可以工作,我无法反驳这种说法,但我建议您先尝试以下操作:

  1. 尝试发送属于 UTF-8 但不属于 ISO 8859-1 标准的符号:如果它不起作用,这应该排除您的< em>结论#2很快;
  2. 尝试将速度降低到尽可能低的值,9600 波特率
  3. 检查文档,验证 minicom 是否正确配置以解释 UTF-8 字符;
  4. 尝试使用一些其他应用程序从您的微 Controller 获取数据并查看结果是否一致;
  5. 验证您发送的 unicode 符号 U 是否正确

注意:这是一个不完整的答案,但我无法在评论中获得所有内容。如果您足够耐心,请用您的发现更新您的问题,并评论此答案以通知我。我会回到这里并相应地更新我的答案。

关于c++ - 在微 Controller 上编写 UART 控制台时的 UTF-8 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36551036/

相关文章:

c++ - Box2D 矩形碰撞

将 uint8_t 转换为 ascii 字符串 C

c - arm cortex m4上的总线错误调试

C交叉编译: sprintf only writes "\0" character after array of size [512][4] number [111][1] is initialized to 0

C++:将 std::string 传递给要更改字符串的 C 函数的正确实现?

c++ - 使QWidget在点击后消失

c++ - 在OpenCV中查找具有已知纵横比的矩形的距离

php - 这是使用 MySQL 和 UTF8 使用 UTF8 编码获取数据的正确方法吗

c++ - 使用 std::codecvt_xxx 将 C++ std::wstring 转换为 utf8

java - 使用 Java 和 UTF-8 编码生成有效的 XML