V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
commoccoom
V2EX  ›  问与答

请教一下, C 语言中如何直接发送 16 进制到串口

  •  
  •   commoccoom · 2021-03-02 14:51:26 +08:00 · 1088 次点击
    这是一个创建于 1364 天前的主题,其中的信息可能已经有所发展或是发生改变。

    因为有几个设备是 RS485 通讯的,奇怪在于使用了几个现成的 Modbus 库,总是在最后的 CRC 出错,所以想直接发送数据到设备。

    # 但是无论是
    unsigned char *data = "01 03 00 00 00 01 84 0A";
    # 还是
    unsigned char *data = "0x01 0x03 0x00 0x00 0x00 0x01 0x84 0x0A";
    

    发送到串口都不是 16 进制的数据

    向各位大佬来请教一下,刚接触 C 没多久😂

    第 1 条附言  ·  2021-03-03 15:02:10 +08:00

    经过一段时间的搜索,拼拼凑凑终于有了一定的结果了,后续再改进了

    库是使用 https://sigrok.org/wiki/Libserialport ,直接用的 send_receive.c这个示例 [自己再缝合了一些] 运行结果:

    1.png

    后续要做的就是把 FF796501020301这个顺序给正过来

    14 条回复    2021-03-03 15:02:55 +08:00
    Hconk
        1
    Hconk  
       2021-03-02 14:53:28 +08:00
    你定义的都是字符串,= =..
    unsigned char *data = [0x01,0x03,0x00,0x00,0x00,0x01,0x84,0x0A];
    Hconk
        2
    Hconk  
       2021-03-02 14:57:35 +08:00
    @Hconk 发出去就看到我写的有毛病了。。=_=
    unsigned char data[] ={0x01,0x03,0x00,0x00,0x00,0x01,0x84,0x0A};
    clef
        3
    clef  
       2021-03-02 14:59:14 +08:00
    {0x01, 0x03};
    or
    "\x01\x03"
    commoccoom
        4
    commoccoom  
    OP
       2021-03-02 15:00:18 +08:00
    @Hconk 这是什么数据类型啊?
    Hconk
        5
    Hconk  
       2021-03-02 15:03:03 +08:00
    @commoccoom #4 data 是存 unsigned char 的数组
    wzb0909
        6
    wzb0909  
       2021-03-02 15:09:59 +08:00
    你问一个语言的问题之前,总该把语法先搞明白吧,浪费别人感情点进来~
    commoccoom
        7
    commoccoom  
    OP
       2021-03-02 15:14:28 +08:00
    @wzb0909 我对这个问题也是思考了很久,但是可能水平太差,浪费了各位时间了,抱歉
    wzb0909
        8
    wzb0909  
       2021-03-02 15:29:13 +08:00
    @commoccoom 啊对不起,我也是听你讲串口什么的,我比较好奇点进来。
    要是能有更多一点信息,比如,你的工作的更细节的情况啊(先尝试了什么,又尝试了什么,遇到了哪些问题,具体在什么地方发现问题),能满足大家的好奇心,回答问题就会更开心些。

    啊当然这也不是你的责任。你能解决问题就好~
    pkookp8
        9
    pkookp8  
       2021-03-02 15:43:27 +08:00 via Android
    换一种思路
    可以在算 crc 的时候把输入数据打印出来
    就会发现你的输入(字符串转换的 acsii)和你的预期(你的 16 进制数据)不匹配
    但是你会发现有一个字符(空格)每隔几个字符就出现一次,就能想到这个问题了
    commoccoom
        10
    commoccoom  
    OP
       2021-03-02 16:02:25 +08:00
    @wzb0909 工作就是在 Linux 上通过串口把使用 ModBus485 协议的传感器的数据获取到。之前是 Python 写的,但是传感器数量多了之后,性能不好,所以想用 C 来写了。

    大部分传感器都是可以用 libmodbus 这个库来解决的,但有几个类型的传感器在最后的 CRC 校验里出问题( Python 版也一样),所以想直接发送指令到串口了。

    在网上找了 Libserialport 这个库,但是看它的示例程序里面 https://sigrok.org/api/libserialport/unstable/a00046.html 都是发送字符串数据的。也包括 这个 https://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c

    像这种 串口助手里十六进制发送到底是怎么实现的

    因为刚接触 C,所以是缝合怪,东拼西凑的,还望指教啊😂
    junyee
        11
    junyee  
       2021-03-03 05:29:47 +08:00 via iPhone
    串口可以按字节发送啊,但是有很多不可打印字符,要转成 hex,如,printf 的 %02x
    commoccoom
        12
    commoccoom  
    OP
       2021-03-03 14:00:53 +08:00
    @Hconk
    @wzb0909

    经过一番搜索之后,只要 unsigned long value = strtoul("010300000001840A",NULL,16); 这样就可以了,但是我接收到的数据却是“0A84010000000301”这样的倒叙,不知道为什么,另外,我从串口助手发送到 linux 的 数据 用 int ret = snprintf(buffer, 50, "%lu", *buf); 转换之后 是这样的 "\220\356\377\377\177\000\000\000\344\306\345\267\177\000\000\000\000d" 怎么才能变成"010300000001840A" 这样的字符串形式呢😂
    wzb0909
        13
    wzb0909  
       2021-03-03 14:36:38 +08:00
    @commoccoom 我错了,我只是路过的,,,,我也不熟悉这个方面。
    然后,
    数是从低往高数,字节码从前往后数,,顺序没问题啊。。。符合预期。
    lu 是十进制吧,十六进制是 lX 啊。。。然后我也不了解你这个输出。

    然后,
    没有然后了。这已经过于细节了。。。。我先走了~
    commoccoom
        14
    commoccoom  
    OP
       2021-03-03 15:02:55 +08:00
    @wzb0909 好吧,现在已经解决了,还剩个小问题再研究下了😂
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5799 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 107ms · UTC 06:10 · PVG 14:10 · LAX 22:10 · JFK 01:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.