1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.IO.Ports; 10 using System.Threading; 11 using Microsoft.Win32; 12 using System.IO; 13 14 namespace 串口端口读取地磅 15 { 16 public partial class Form1 : Form 17 { 18 public Form1() 19 { 20 InitializeComponent(); 21 } 22 private SerialPort SerialPort1 = new SerialPort();//串口资源对象 23 public delegate void HandleInterfaceUpdataDelegate(string text); //委托,此为重点 24 private HandleInterfaceUpdataDelegate interfaceUpdataHandle; 25 private int FanChongQuChangDu = 15;//读取缓冲区指定长度 26 27 /* 28 *特别注意:地磅电子秤如果输出接口接错,收到的则是乱码 29 */ 30 31 public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 32 { 33 try 34 { 35 if (SerialPort1.IsOpen)//端口打开中 36 { 37 string strTemp = ""; 38 //程序等待0.5秒让缓冲区获取串口数据 39 double iSecond = 0.5; 40 41 DateTime dtOld = System.DateTime.Now; 42 DateTime dtNow = System.DateTime.Now; 43 TimeSpan dtInter; 44 dtInter = dtNow - dtOld; 45 46 int i = SerialPort1.BytesToRead; 47 if (i > 0) 48 { 49 try 50 { 51 strTemp = SerialPort1.ReadExisting(); 52 } 53 catch 54 { } 55 if (strTemp.ToLower().IndexOf("\r") < 0) 56 { 57 i = 0; 58 } 59 else 60 { 61 this.Invoke(interfaceUpdataHandle, strTemp); 62 } 63 } 64 while (dtInter.TotalSeconds < iSecond && i <= 0) 65 { 66 dtNow = System.DateTime.Now; 67 dtInter = dtNow - dtOld; 68 i = SerialPort1.BytesToRead; 69 if (i > 0) 70 { 71 try 72 { 73 strTemp += SerialPort1.ReadExisting(); 74 } 75 catch 76 { } 77 if (strTemp.ToLower().IndexOf("\r") < 0) 78 { 79 i = 0; 80 } 81 else 82 { 83 this.Invoke(interfaceUpdataHandle, strTemp); 84 } 85 } 86 } 87 } 88 } 89 catch (Exception cw) 90 { 91 MessageBox.Show(cw.ToString()); 92 return ; 93 } 94 95 } 96 97 private void UpdateTextBox(string text) 98 { 99 100 txtShiShiZhongLiang.Text = text; 101 102 if (SerialPort1.IsOpen)//端口打开 103 { 104 txtState.Text = "端口连接中"; 105 } 106 else 107 { 108 txtState.Text = "端口已断开"; 109 } 110 } 111 112 /// <summary> 113 /// 执行AT指令并返回 成功失败 114 /// </summary> 115 /// <param name="ATCmd">AT指令</param> 116 /// <param name="StCmd">AT指令标准结束标识</param> 117 /// <returns></returns> 118 private void ATCommand3(string ATCmd, string StCmd) 119 { 120 string response = ""; 121 response = ATCommand(ATCmd, StCmd); 122 } 123 124 /// <summary> 125 /// 执行AT指令并返回结果字符 126 /// </summary> 127 /// <param name="ATCmd">AT指令</param> 128 /// <param name="StCmd">AT指令标准结束标识</param> 129 /// <returns></returns> 130 private string ATCommand(string ATCmd, string StCmd) 131 { 132 string response = ""; 133 int i; 134 if (!ATCmd.EndsWith("\x01a")) 135 { 136 if (!(ATCmd.EndsWith("\r") || ATCmd.EndsWith("\r\n"))) 137 { 138 ATCmd = ATCmd + "\r"; 139 } 140 } 141 SerialPort1.WriteLine(ATCmd); 142 143 //第一次读响应数据 144 if (SerialPort1.BytesToRead > 0) 145 { 146 response = SerialPort1.ReadExisting(); 147 148 //去除前端多可能多读取的字符 149 if (response.IndexOf(ATCmd) > 0) 150 { 151 response = response.Substring(response.IndexOf(ATCmd)); 152 } 153 else 154 { 155 156 } 157 158 if (response == "" || response.IndexOf(StCmd) < 0) 159 { 160 if (response != "") 161 { 162 if (response.Trim() == "ERROR") 163 { 164 //throw vError = new UnknowException("Unknown exception in sending command:" + ATCmd); 165 } 166 if (response.IndexOf("+CMS ERROR") >= 0) 167 { 168 string[] cols = new string[100]; 169 cols = response.Split(';'); 170 if (cols.Length > 1) 171 { 172 string errorCode = cols[1]; 173 } 174 } 175 } 176 } 177 } 178 179 //读第一次没有读完的响应数据,直到读到特征数据或超时 180 for (i = 0; i < 3; i++) 181 { 182 Thread.Sleep(1000); 183 response = response + SerialPort1.ReadExisting(); 184 if (response.IndexOf(StCmd) >= 0) 185 { 186 break; 187 } 188 } 189 190 return response; 191 192 193 } 194 195 /// <summary> 196 /// 从注册表获取系统串口列表 197 /// </summary> 198 private void GetComList() 199 { 200 RegistryKey keyCom = Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm"); 201 if (keyCom != null) 202 { 203 string[] sSubKeys = keyCom.GetValueNames(); 204 this.cbxDuanKouHao.Items.Clear(); 205 foreach (string sName in sSubKeys) 206 { 207 string sValue = (string)keyCom.GetValue(sName); 208 this.cbxDuanKouHao.Items.Add(sValue); 209 } 210 } 211 } 212 213 private void cmID_DropDown(object sender, EventArgs e) 214 { 215 GetComList(); 216 } 217 218 private void Form1_Load(object sender, EventArgs e) 219 { 220 221 GetComList(); 222 btPause.Enabled = false; 223 } 224 225 //暂停监听读取数值 226 private void btPause_Click(object sender, EventArgs e) 227 { 228 SerialPort1.Close(); 229 if (SerialPort1.IsOpen)//端口打开 230 { 231 txtState.Text = "端口连接中"; 232 } 233 else 234 { 235 txtState.Text = "端口已断开"; 236 } 237 btENT.Enabled = true; 238 btPause.Enabled = false; 239 240 } 241 //一直监听读取数值 242 private void btENT_Click(object sender, EventArgs e) 243 { 244 if ((this.cbxDuanKouHao.Text.Trim() != "") && (this.cbxBoTeLv.Text != "")) 245 { 246 if (SerialPort1 != null ) 247 { 248 interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象 249 SerialPort1.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived); 250 //串口更改 251 if (SerialPort1.PortName != this.cbxDuanKouHao.Text.Trim()) 252 { 253 SerialPort1.Close(); 254 SerialPort1.Dispose(); 255 SerialPort1 = new SerialPort();//串口资源对象 256 interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象 257 SerialPort1.PortName = this.cbxDuanKouHao.Text.Trim(); 258 SerialPort1.BaudRate = Convert.ToInt32(this.cbxBoTeLv.Text.Trim()); 259 SerialPort1.Parity = JiaoYanWei(cbxJiaoYanWei.Text); 260 SerialPort1.StopBits = TingZhiWei(cbxTingZhiWei.Text); 261 SerialPort1.Encoding = Encoding.ASCII;//获取传输字符编码 262 SerialPort1.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived); 263 SerialPort1.ReceivedBytesThreshold = 1; 264 try 265 { 266 SerialPort1.Open(); 267 268 ATCommand3("AT+CLIP=1\r", "OK"); 269 270 271 btPause.Enabled = true; 272 btENT.Enabled = false; 273 } 274 catch (Exception) 275 { 276 MessageBox.Show("端口" + this.cbxDuanKouHao.Text.Trim() + "打开失败!"); 277 } 278 } 279 else//串口未更改 280 { 281 if(SerialPort1.IsOpen)//端口已打开 282 { 283 btPause.Enabled = true; 284 btENT.Enabled = false; 285 } 286 else 287 { 288 SerialPort1.Open(); 289 btPause.Enabled = true; 290 btENT.Enabled = false; 291 } 292 } 293 } 294 else 295 { 296 interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//实例化委托对象 297 SerialPort1.PortName = this.cbxDuanKouHao.Text.Trim(); 298 SerialPort1.BaudRate = Convert.ToInt32(this.cbxBoTeLv.Text.Trim()); 299 SerialPort1.Parity = JiaoYanWei(cbxJiaoYanWei.Text); 300 SerialPort1.StopBits = TingZhiWei(cbxTingZhiWei.Text); 301 SerialPort1.Encoding = Encoding.ASCII;//获取传输字符编码 302 SerialPort1.DataReceived += new SerialDataReceivedEventHandler(Sp_DataReceived); 303 SerialPort1.ReceivedBytesThreshold = 1; 304 try 305 { 306 SerialPort1.Open(); 307 308 ATCommand3("AT+CLIP=1\r", "OK"); 309 310 311 btPause.Enabled = true; 312 btENT.Enabled = false; 313 } 314 catch (Exception) 315 { 316 MessageBox.Show("端口" + this.cbxDuanKouHao.Text.Trim() + "打开失败!"); 317 } 318 } 319 } 320 else 321 { 322 MessageBox.Show("请输入正确的端口号和波特率!"); 323 this.cbxDuanKouHao.Focus(); 324 } 325 } 326 327 /// <summary> 328 /// 读一次数:注意电子秤设置的发送信息规则:如果不是连续发送,是稳定后发送,则有时候读不到数 329 /// </summary> 330 /// <param name="sender"></param> 331 /// <param name="e"></param> 332 private void btnDuYiCi_Click(object sender, EventArgs e) 333 { 334 try 335 { 336 if ((this.cbxDuanKouHao.Text.Trim() != "") && (this.cbxBoTeLv.Text != "")) 337 { 338 if (SerialPort1 != null) 339 { 340 SerialPort1.Close(); 341 SerialPort1.Dispose(); 342 SerialPort1 = new SerialPort();//重新创建串口资源对象,否则导致程序卡死 343 //串口更改 344 if (SerialPort1.PortName != this.cbxDuanKouHao.Text.Trim()) 345 { 346 SerialPort1.PortName = this.cbxDuanKouHao.Text.Trim(); 347 SerialPort1.BaudRate = Convert.ToInt32(this.cbxBoTeLv.Text.Trim()); 348 SerialPort1.Parity = JiaoYanWei(cbxJiaoYanWei.Text); 349 SerialPort1.StopBits = TingZhiWei(cbxTingZhiWei.Text); 350 SerialPort1.Encoding = Encoding.ASCII;//获取传输字符编码 351 SerialPort1.ReceivedBytesThreshold = 1; 352 try 353 { 354 SerialPort1.Open(); 355 356 ATCommand3("AT+CLIP=1\r", "OK"); 357 this.txtShiShiZhongLiang.Text = dushu(); 358 } 359 catch (Exception) 360 { 361 MessageBox.Show("端口" + this.cbxDuanKouHao.Text.Trim() + "打开失败!"); 362 } 363 } 364 else//串口未更改 365 { 366 if (SerialPort1.IsOpen)//端口已打开 367 { 368 ATCommand3("AT+CLIP=1\r", "OK"); 369 this.txtShiShiZhongLiang.Text = dushu(); 370 } 371 else 372 { 373 SerialPort1.Open(); 374 ATCommand3("AT+CLIP=1\r", "OK"); 375 this.txtShiShiZhongLiang.Text = dushu(); 376 } 377 } 378 } 379 else 380 { 381 382 SerialPort1.PortName = this.cbxDuanKouHao.Text.Trim(); 383 SerialPort1.BaudRate = Convert.ToInt32(this.cbxBoTeLv.Text.Trim()); 384 SerialPort1.Parity = JiaoYanWei(cbxJiaoYanWei.Text); 385 SerialPort1.StopBits = TingZhiWei(cbxTingZhiWei.Text); 386 387 SerialPort1.ReceivedBytesThreshold = 1; 388 try 389 { 390 SerialPort1.Open(); 391 392 ATCommand3("AT+CLIP=1\r", "OK"); 393 this.txtShiShiZhongLiang.Text = dushu(); 394 } 395 catch (Exception) 396 { 397 MessageBox.Show("端口" + this.cbxDuanKouHao.Text.Trim() + "打开失败!"); 398 } 399 } 400 } 401 else 402 { 403 MessageBox.Show("请输入正确的端口号和波特率!"); 404 this.cbxDuanKouHao.Focus(); 405 } 406 if (SerialPort1.IsOpen) 407 { 408 SerialPort1.Close(); 409 } 410 } 411 catch (Exception) 412 { 413 414 return; 415 } 416 417 } 418 /// <summary> 419 /// 读取缓冲区指定长度数值 420 /// </summary> 421 /// <param name="changdu"></param> 422 /// <returns></returns> 423 private string dushu() 424 { 425 string strTemp = ""; 426 try 427 { 428 if (SerialPort1.IsOpen)//端口打开中 429 { 430 431 int i = SerialPort1.BytesToRead;//获取缓冲区字节数 432 433 #region 程序等待0.5秒让缓冲区获取串口数据 434 double iSecond = 0.5; 435 436 DateTime dtOld = System.DateTime.Now; 437 DateTime dtNow = System.DateTime.Now; 438 TimeSpan dtInter; 439 dtInter = dtNow - dtOld; 440 441 while (dtInter.TotalSeconds < iSecond && i <= 0) 442 { 443 dtNow = System.DateTime.Now; 444 dtInter = dtNow - dtOld; 445 i = SerialPort1.BytesToRead; 446 } 447 #endregion 448 if (i > 0) 449 { 450 try 451 { 452 453 byte[] buf = new byte[FanChongQuChangDu];// 定义接收缓冲区 454 SerialPort1.Read(buf, 0, FanChongQuChangDu); 455 for (int j = 0; j < FanChongQuChangDu; j++) 456 { 457 458 ASCIIEncoding ASCIITochar = new ASCIIEncoding(); 459 char[] ascii = ASCIITochar.GetChars(buf); // 将接收字节解码为ASCII字符数组 460 strTemp += ascii[j]; 461 //已读到换行符就跳出 462 if (strTemp.ToLower().IndexOf("\r") > 0) 463 { 464 break; 465 } 466 } 467 } 468 catch 469 { } 470 } 471 } 472 } 473 catch (Exception) 474 { 475 476 return strTemp; 477 } 478 return strTemp; 479 } 480 481 private void btnZhuaQu_Click(object sender, EventArgs e) 482 { 483 this.txtZhuaQuZhi.Text = this.txtShiShiZhongLiang.Text; 484 } 485 /// <summary> 486 /// 返回校验位 487 /// </summary> 488 /// <param name="zhi"></param> 489 /// <returns></returns> 490 private Parity JiaoYanWei(string zhi) 491 { 492 switch (zhi) 493 { 494 case "Even": return Parity.Even; 495 case "Mark": return Parity.Mark; 496 case "None": return Parity.None; 497 case "Odd": return Parity.Odd; 498 case "Space": return Parity.Space; 499 default: return Parity.None; 500 } 501 } 502 /// <summary> 503 /// 返回停止位 504 /// </summary> 505 /// <param name="zhi"></param> 506 /// <returns></returns> 507 private StopBits TingZhiWei(string zhi) 508 { 509 switch (zhi) 510 { 511 case "0": return StopBits.None; 512 case "1": return StopBits.One; 513 case "1.5": return StopBits.OnePointFive; 514 case "2": return StopBits.Two; 515 default: return StopBits.One; 516 } 517 } 518 /// <summary> 519 /// ASCII码转字符 520 /// </summary> 521 /// <param name="asciiCode"></param> 522 /// <returns></returns> 523 public static string asciiToString(int asciiCode) 524 { 525 if (asciiCode >= 0 && asciiCode <= 255) 526 { 527 System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding(); 528 byte[] byteArray = new byte[] { (byte)asciiCode }; 529 string strCharacter = asciiEncoding.GetString(byteArray); 530 return (strCharacter); 531 } 532 else 533 { 534 throw new Exception("ASCII Code is not valid."); 535 } 536 } 537 //用封装对象来实现 538 private void button1_Click(object sender, EventArgs e) 539 { 540 try 541 { 542 mycom mycom1 = new mycom(); 543 mycom1.PortNum = cbxDuanKouHao.Text; 544 mycom1.BaudRate = Convert.ToInt32(cbxBoTeLv.Text); 545 mycom1.StopBits = 8; 546 mycom1.Parity = 0; 547 mycom1.StopBits = Convert.ToByte(cbxTingZhiWei.Text); 548 mycom1.ReadTimeout = 10; 549 550 mycom1.Open(); 551 string dushu = ""; 552 byte[] buf = mycom1.Read(12); 553 554 for (int j = 0; j < 12; j++) 555 { 556 557 ASCIIEncoding ASCIITochar = new ASCIIEncoding(); 558 char[] ascii = ASCIITochar.GetChars(buf); // 将接收字节解码为ASCII字符数组 559 dushu += ascii[j]; 560 561 } 562 563 txtShiShiZhongLiang.Text = dushu; 564 565 mycom1.Close(); 566 } 567 catch (Exception cuowu) 568 { 569 MessageBox.Show(cuowu.Message); 570 return ; 571 } 572 573 } 574 } 575 }