lougon

导航

serialport串口采集

using System; 
using System.IO.Ports; 
using System.Windows.Forms; 

namespace SPC 

    
/// <summary> 
    
/// 串口控制   
    
/// </summary> 

    public class PortControl 

    

        
private string _portname; 
        
private double _timeout = 0.8
        
private byte[] bin_return = new byte[] {}
        
private string hex_return = ""//收到数据后把十六进制存到这个字符串中。 
        public Exception LastException; 

        
/// <summary> 
        
/// 定义一个串口类 
        
/// </summary> 

        private  static SerialPort MyPort; 

        
public bool Received = false//是否收到了信息。 发送完数据,如果需要车检器返回数据,该属性设置为false; 

        
/// <summary> 
        
/// 初始化类 
        
/// </summary> 

        public PortControl() 
        

            MyPort 
= new SerialPort(); 
            setup(); 
        }
 

        
/// <summary> 
        
/// 直接使用给某个串口 
        
/// </summary> 
        
/// <param name="port">COM1,COM2。。。。。。</param> 

        public PortControl(string port) 
        

            _portname 
= port; 
            MyPort 
= new SerialPort(_portname); 

            setup(); 
        }
 

        
/// <summary> 
        
/// 端口名称 
        
/// </summary> 
        
/// <example>COM1 COM2</example> 

        public string PortName 
        

            
get return _portname; } 
            
set { _portname = value; } 
        }
 

        
/// <summary> 
        
/// 最后收到的信息 
        
/// </summary> 

        public string LastReceived 
        

            
get return hex_return; } 
        }
 

        
public double TimeOut 
        

            
get return _timeout; } 
            
set { _timeout = value; } 
        }
 

        
private void setup() 
        

            MyPort.DataReceived 
+= DataReceived; 
        }
 

          
   
        
public bool Open() 
        

            
try 
            

                MyPort.Close(); 
                
if (MyPort.IsOpen != true
                

                    MyPort.Open(); 
                }
 
                ; 
                
return true
            }
 
            
catch 
            

                MyPort.Close(); 
                
return false
            }
 
        }
 

        
public void Open(string port) 
        

            MyPort.PortName 
= _portname; 
            MyPort.Open(); 
        }
 

        
public void Close() 
        

           MyPort.Close(); 
        }
 

        
/// <summary> 
        
/// 向端口中发送命令。 
        
/// </summary> 
        
/// <param name="cmdstring">"0A 46 0B 31 30 30 32 35"</param> 
        
/// <example>  Send("0A 46 0B 31 30 30 32 35")</example> 
        
/// <remarks>超时设置为5秒,一般来说,端口速度不会延时超过1秒。</remarks> 
        
/// <summary> 
        
/// 向端口中发送命令。 
        
/// </summary> 
        
/// <param name="cmdstring">"0A 46 0B 31 30 30 32 35"</param> 
  
        
/// <example>  Send("0A 46 0B 31 30 30 32 35")</example> 

        public string Send(string cmdstring) 
        

            
byte[] buff = Funs.HexStringToBinary(cmdstring.Trim()); //转换命令字符串为字节数组 
            hex_return = ""//十六进制返回设置为空。 
            bin_return = new byte[] {}//重新初始化返回字节数组。 
            Received = false//设置标识为没有接受到信息 
            MyPort.Write(buff, 0, buff.Length); //写入串口命令。 
            double tmpx = DateTime.Now.TimeOfDay.TotalSeconds; //记录下当前总计秒数 

            
do 
            

                Application.DoEvents(); 
//释放CPU 
            }
 while ((Received != true&& (DateTime.Now.TimeOfDay.TotalSeconds - tmpx < _timeout)); 
            
if (Received == false
            

                
return null
            }
 
            
//如果接受到了数据或者已超时就不再循环。 
            string rt; //初始化返回内容。 
            int sum = 0//初始化命令总数。 
            for (int i = 3; i < bin_return.Length - 2; i++
            

                sum 
+= bin_return[i]; 
            }
 
            
int sum1 = bin_return[bin_return.Length - 2+ bin_return[bin_return.Length - 1]*256
            
if ( 
                sum 
!= sum1 
                
&& 
                bin_return[bin_return.Length 
- 3== 3 
                ) 
            

                rt 
= null
            }
 
            
else 
            

                rt 
= Funs.BinaryToHexString(bin_return); 
            }
 
            MyPort.Close(); 
            
return rt; 
        }
 


        
/// <summary> 
        
/// 如果接受到了数据。 
        
/// </summary> 
        
/// <param name="sender">发送者</param> 
        
/// <param name="e">时间参数</param> 

        private void DataReceived(object sender, SerialDataReceivedEventArgs e) 
        

            
//MyPort.DiscardInBuffer(); //丢弃事件发生前的数据。 
            int n = MyPort.BytesToRead; //读取当前有多少数据可读。 
            byte[] binary = new byte[n]; //新建内容。 
            MyPort.Read(binary, 0, n); //读取 
            Array.Resize(ref bin_return, bin_return.Length + n); //改写数组大小 
            if (bin_return.Length < 1
            

                
return
            }
 

            binary.CopyTo(bin_return, bin_return.Length 
- binary.Length); //复制数据。 
            int infleng = 0
            
//16 16 02 10 01 02 00 07 00 03 1D 00   
            if (bin_return.Length > 7//基本信息头应该是7个字节。 
            
                
if (bin_return[0== bin_return[1&& bin_return[0== 22 && bin_return[2== 2
                    
//如果第零字节和第一字节相等,并且第二自己为0,那么表示信息的开头 。  
                
                    
//计算第五字节和第六字节。这两个字节表示长度。 
                    infleng = bin_return[5+ bin_return[6]*256
                }
 
            }
 
            
else if (bin_return.Length == 3
            

                Received 
= true
                
return
            }
 

            Received 
= ((10 + infleng) == bin_return.Length); //命令基本格式包含10个字节。 
            
//加上信息长度如果等于bin接收到的长度的话。说明接受完了。接受完了就设置receive为真。 
           
// Console.WriteLine(String.Format("读取字节数:{0}:内容:{1}----{2}", n, hex_return, e.EventType)); 
        }
 
    }
 
}
 

--------------------------------------------------------

涉及到的函数 

        
/// <summary> 
        
/// 16进制字符串转换为二进制数组 
        
/// </summary> 
        
/// <param name="hexstring">字符串每个字节之间都应该有空格,大多数的串口通讯资料上面的16进制都是字节之间都是用空格来分割的。</param> 
        
/// <returns>返回一个二进制字符串</returns> 

        public static byte[] HexStringToBinary(string hexstring) 
        

            
string[] tmpary = hexstring.Trim().Split(' '); 
            
byte[] buff = new byte[tmpary.Length]; 
            
for (int i = 0; i < buff.Length; i++
            

                buff[i] 
= Convert.ToByte(tmpary[i], 16); 
            }
 
            
return buff; 
        }
 
        
/// <summary> 
        
/// 把二进制转换为十六进制字符串。 
        
/// </summary> 
        
/// <param name="buff">要被转换的二进制数组</param> 
        
/// <returns>返回十六进制字符串,以空格隔开每个字节 。</returns> 

        public static string BinaryToHexString(byte[] buff) 
        

            
string tmpstring = ""
            
foreach (byte var in buff) 
            


                tmpstring 
+= " " + Strings.Right("00" + Convert.ToString(var, 16), 2); 
            }
 
            
return tmpstring.Trim().ToUpper(); 
        }
 


--------------------------------------------------------

textBox1.Text 
+= sp2.Read(); 
文本框中的 System。Byte[] 是 你读取到的字节数组的类型。  
更多内容你可以参考 
http:
//www.mysticboy.cn/article.asp?id=32 
这是我项目里用到的类。  
我想它可以作为你的一个参考 

posted on 2007-09-14 16:55  lougon  阅读(812)  评论(0)    收藏  举报