commoccoom
V2EX  ›  问与答

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

  •  
  •   commoccoom · Mar 2, 2021 · 1472 views
    This topic created in 1905 days ago, the information mentioned may be changed or developed.

    因为有几个设备是 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 没多久😂

    Supplement 1  ·  Mar 3, 2021

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

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

    1.png

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

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

    啊当然这也不是你的责任。你能解决问题就好~
    pkookp8
        9
    pkookp8  
       Mar 2, 2021 via Android
    换一种思路
    可以在算 crc 的时候把输入数据打印出来
    就会发现你的输入(字符串转换的 acsii)和你的预期(你的 16 进制数据)不匹配
    但是你会发现有一个字符(空格)每隔几个字符就出现一次,就能想到这个问题了
    commoccoom
        10
    commoccoom  
    OP
       Mar 2, 2021
    @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  
       Mar 3, 2021 via iPhone
    串口可以按字节发送啊,但是有很多不可打印字符,要转成 hex,如,printf 的 %02x
    commoccoom
        12
    commoccoom  
    OP
       Mar 3, 2021
    @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  
       Mar 3, 2021
    @commoccoom 我错了,我只是路过的,,,,我也不熟悉这个方面。
    然后,
    数是从低往高数,字节码从前往后数,,顺序没问题啊。。。符合预期。
    lu 是十进制吧,十六进制是 lX 啊。。。然后我也不了解你这个输出。

    然后,
    没有然后了。这已经过于细节了。。。。我先走了~
    commoccoom
        14
    commoccoom  
    OP
       Mar 3, 2021
    @wzb0909 好吧,现在已经解决了,还剩个小问题再研究下了😂
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2436 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 16:05 · PVG 00:05 · LAX 09:05 · JFK 12:05
    ♥ Do have faith in what you're doing.