在写个程序,想通过PC的串口控制一台仪器(电压供应器)进行操作(操作步骤:先将仪器设成远程控制模式---》再将仪器输出状态设为ON ---》最后读取仪器的输出电压及电流值),因为该仪器输出的为TTL电平信号,所以仪器是通过配套的一根TTL-RS232通讯电缆连接到PC串口的,连接好后,我先用从网上下载的一个串口调试器来调试了一下,在字符串输入框输入命令:AA002001000000000000000000000000000000000000000000CB,选择Hex发送,然后点击发送按钮,仪器就能被设置成远程控制模式,然后再发送命令AA002101000000000000000000000000000000000000000000CC,就能如愿的把仪器输出状态设为ON。但是我在c#程序中,我分别使用过Write(string)以及WriteLine(string)等方法来发送如上命令,仪器却无任何反应,程序是显示发送成功的。
请问大侠们,会是什么原因?
我用Write("AA002001000000000000000000000000000000000000000000CB"),
WriteLine("AA002001000000000000000000000000000000000000000000CB"),

解决方案 »

  1.   

    补充一下,我c#程序中设置的串口通讯协议是正确的,9600,8位,1位,None
      

  2.   

    选择Hex发送这步不解,windows自带的那个超级终端(自带,不要下载)里没有选择Hex发送这个操作。
      

  3.   

    昨天刚学习了串口,我觉得你的问题应该是吧,你要write的东西,转化16进制之后再发发送吧
      

  4.   

    那就是你用错方法了,.NET内部自带的这个方法,当你传递字符串时,只能是以字符串形式发送,不会认为是16进制,你必须手动转换为16进制来发送。
    给段示例说明下吧(下次回复快速点,不然直接无视你这个问题帖了。):        /// <summary>
            /// 普通方法——字符串转字节数组,最容易想到
             /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static byte[] StringToBytes(string input)
            {
                int len = input.Length;
                if (len % 2 != 0)
                {
                    throw new Exception("输入的字符串长度有误,必须是偶数。");
                }
                byte[] bytes = new byte[len / 2];
                for (int i = 0; i < len / 2; i++)
                {
                    if (!byte.TryParse(input.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber, null, out bytes[i]))
                    {
                        throw new Exception(string.Format("在位置{0}处的字符无法转换为16进制字节", i * 2 + 1));
                    }
                }
                return bytes;
            }        /// <summary>
            /// 普通方法——字节数组转字符串,最容易想到
             /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static string BytesToString(byte[] input)
            {
                StringBuilder sb = new StringBuilder();
                foreach (byte b in input)
                {
                    sb.Append(b.ToString("X2"));
                }
                return sb.ToString();
            }
                byte[] bytes = StringToBytes("AA002001000000000000000000000000000000000000000000CB");
                serialPort.Write(bytes, 0, bytes.Length);
      

  5.   

    qldsrx,太感谢你了,谢谢!因为有别的事情耽误了,所以回复慢了点。呵见谅啊!
      

  6.   

    我用串口给PLC发指令的时候也遇到过类似问题
    通过RS232-485转接头转换,用C++调用WriteFile可以正常通信,用C#就不行
    分析可能是因为转接时只用了2个针脚,而C#的用了其他针脚。但是对硬件不是很熟悉吗,不能确定
      

  7.   

    qldsrx, 我刚试了你的程序,执行了字符串转换成字节数组后,bytes数组里面竟然是:
    [0x00000000] 0xaa
    [0x00000001] 0x00
    [0x00000002] 0x20 ...
    我有些不明白,这并没有转换成字节呀?正常的话,转换成字节后,数组中第一个元素应该是170,第二个0...
    怎么回事???晕了,会不会是我程序选择的编码有问题?
      

  8.   

    WRITE()好像里面的参数是byte[]要将string 转换成BYTE【】,保证下发的协议没有问题基本上都没有问题
      

  9.   

    另外你看到的这个byte数组就是所需的数组,传递过去即可
      

  10.   

    肯定是你发送的字符格式不对,通信协议需要发送的是16进制的数据,而你发送的却是一个16进制的字符串,这样是错误。
    你首先将格式的16进制数据:AA002001000000000000000000000000000000000000000000CB,转换为字符串,然后再将转换好的字符串发送出去就OK了
      

  11.   

    传递过去不起作用,仪器没反应,就是没有被成功设置成remote控制模式。
    是不是我理解有误?我觉得把AA002001...这个16进制数据转换成字节型数组后,数组里面应该是{170,0,32,1...}。
      

  12.   

    0xaa和170是相等的,你强制类型转换下是等价的,因此数组的构建没问题。
    {170,0,32,1...}这是int[]
    {0xaa,0x00,0x20,...}这是byte[]
    两者在数值上相等,不是可以byte b = (byte)170;吗?结果就是0xaa没作用的话,检查其它地方是否有误,别老钻在一个方面,说不定你还有其它错误,例如这么长的数据中是否少个0,SerialPort的属性设置是否正确。
      

  13.   

    你理解错误,你用串口通信调试的时候就选择了hex发送,何为hex?
    传递过去出错,说明就是你发送的问题。
      

  14.   

    谢谢大家的回答!尤其是qldsrx,谢谢你的帮忙!分都给你吧!
    问题解决了,是serialPort控件的问题,我换成MSComm控件,发送同样的命令,就可以控制仪器,汗颜...!