在数据传输或者数据下载过程中,通常要保证数据的可靠性和安全性,所以,发送方和接收方要约定共同的协议,而这个协议中常常会出现校验和的运算。
C代码如下:
1 unsigned char calc_nmea_checksum(const char * setence) 2 { 3 unsigned char checksum = 0; 4 while(* setence) 5 { 6 checksum ^= (unsigned char)* setence++; 7 } 8 9 return checksum; 10 }
实际应用代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using System.IO.Ports; using System.Threading; using System.Diagnostics; namespace serialport { public partial class MainForm : Form { // public Thread threadReceive = null; string Download_path = null; public static SerialPort com = null; public static int serialIndex = 0; public static int baudrateIndex = 1; public static string PortName = "com1"; public static int BaudRate = 9600; bool IsTryToClosePort = false; bool IsReceiving = false; StringBuilder line_buffer = new StringBuilder(255); enum line { wait_start, wait_cr, wait_lf }; int line_status = (int)line.wait_start; public static MainForm formMain; byte[] write_buffer = new byte[227]; bool isFileOpen = false; FileStream fs; bool isPackWriten = false; //byte[] buffer = new byte[216]; int count = 0; int tmpnum = 0; int receive_count = 0; byte[] result = new byte[] { 0x04, 0x24, 0x0C, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x0E, 0x0D, 0x0A }; byte[] receive_buffer = new byte[12]; public MainForm() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { formMain = this; //IsMdiContainer = true; com = new SerialPort(); com.DataBits = 8; com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived); FileStream fs; try { string fold = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + "\\BDTestTools.ini"; fs = new FileStream(fold, FileMode.Open); try { StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default); serialIndex = int.Parse(sr.ReadLine()); baudrateIndex = int.Parse(sr.ReadLine()); PortName = sr.ReadLine(); BaudRate = int.Parse(sr.ReadLine()); Download_path = sr.ReadLine(); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { fs.Close(); } } catch (Exception ex) { try { string fold = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + "\\BDTestTools.ini"; fs = new FileStream(fold, FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.WriteLine(serialIndex.ToString()); sw.WriteLine(baudrateIndex.ToString()); sw.WriteLine(PortName); sw.WriteLine(BaudRate.ToString()); sw.WriteLine(Download_path); sw.Close(); } catch (Exception ex1) { MessageBox.Show(ex1.Message); } } label2.Text = PortName + ":" + BaudRate.ToString(); } private void com_DataReceived(object sender, SerialDataReceivedEventArgs e) { if (IsTryToClosePort) { return; } if (!isPackWriten) return; while (receive_count < 12) { int n = com.BytesToRead; if (n == 0) return; com.Read(receive_buffer, receive_count, 1); if (receive_buffer[receive_count] == result[receive_count]) receive_count++; for (int i = 0; i < 5000; i++) ; } if (!WritePack()) { write_buffer[6] = 0xff; write_buffer[7] = 0xff; Array.Clear(write_buffer, 8, 219); int checksum = 0; for (int i = 2; i < 224; i++) { checksum ^= write_buffer[i]; } write_buffer[224] = (byte)checksum; write_buffer[225] = 0x0d; write_buffer[226] = 0x0a; com.Write(write_buffer, 0, 227); fs.Close(); isPackWriten = false; com.Close(); MessageBox.Show("下载完成"); } } private void ComToolStripMenuItem_Click(object sender, EventArgs e) { SetComForm formSetCom = new SetComForm(); formSetCom.ShowDialog(); } private void FileToolStripMenuItem_Click(object sender, EventArgs e) { string file; OpenFileDialog fileDialog = new OpenFileDialog(); fileDialog.FileName = Download_path; fileDialog.Filter = "EPO文件|*.EPO"; if (fileDialog.ShowDialog() == DialogResult.OK) { isFileOpen = false; file = fileDialog.FileName; try { fs = new FileStream(file, FileMode.Open, FileAccess.Read); fs.Close(); Download_path = file; try { string fold = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + "\\BDTestTools.ini"; fs = new FileStream(fold, FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.WriteLine(serialIndex.ToString()); sw.WriteLine(baudrateIndex.ToString()); sw.WriteLine(PortName); sw.WriteLine(BaudRate.ToString()); //label3.Text = Download_path; sw.WriteLine(Download_path); sw.Flush(); sw.Close(); } catch (Exception ex1) { MessageBox.Show(ex1.Message); } } catch (Exception ex) { fs.Close(); MessageBox.Show(ex.Message); } } } private void DownloadToolStripMenuItem_Click(object sender, EventArgs e) { try { fs = new FileStream(Download_path, FileMode.Open, FileAccess.Read); } catch (Exception ex) { fs.Close(); MessageBox.Show(ex.Message); return; } if (MainForm.com.IsOpen) { IsTryToClosePort = true; while (IsReceiving) { System.Windows.Forms.Application.DoEvents(); } try { MainForm.com.Close(); IsTryToClosePort = false; // ConnectToolStripMenuItem1.Text = "连接"; } catch (Exception ex) { MessageBox.Show(ex.Message); } } else { com.PortName = PortName; com.BaudRate = BaudRate; //com.NewLine = ""; try { //打开串口 com.Open(); try { string fold = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) + "\\BDTestTools.ini"; FileStream fs = new FileStream(fold, FileMode.OpenOrCreate); StreamWriter sw = new StreamWriter(fs); sw.WriteLine(serialIndex.ToString()); sw.WriteLine(baudrateIndex.ToString()); sw.WriteLine(PortName); sw.WriteLine(BaudRate.ToString()); sw.WriteLine(Download_path); sw.Close(); label2.Text = PortName + ":" + BaudRate.ToString(); // ConnectToolStripMenuItem1.Text = "断开"; } catch (Exception ex1) { MessageBox.Show(ex1.Message); } } catch (Exception ex) { //捕获到异常信息,创建一个新的comm对象,之前的不能用了 //com = new SerialPort(); //现实异常信息给客户 MessageBox.Show(ex.Message); fs.Close(); return; } } receive_count = 0; WriteBuadeRate(); WritePack(); //启动线程 Thread fthread = new Thread(new ThreadStart(SleepT)); fthread.Start(); isPackWriten = true; } public static string ToHexString(byte[] bytes) { string hexString = string.Empty; if (null != bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.Length; i++) { sb.Append(bytes[i].ToString("X2") + ‘ ‘); } hexString = sb.ToString(); } return hexString; } public static void WriteFile(string context) { FileStream f = new FileStream(@"D:\EPOdownload.LOG", FileMode.OpenOrCreate, FileAccess.Write); StreamWriter sw = new StreamWriter(f); sw.BaseStream.Seek(0, SeekOrigin.End); sw.WriteLine(context); sw.Flush(); sw.Close(); f.Close(); } private void WriteBuadeRate() { byte[] buadeRate = new byte[] { 0x24, 0x50, 0x4D, 0x54, 0x4B, 0x32, 0x35, 0x33, 0x2C, 0x31, 0x2C, 0x30, 0x2A, 0x33, 0x37, 0x0D, 0x0A }; try { com.Write(buadeRate, 0, 17); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private bool WritePack() { if (fs.Read(write_buffer, 8, 216) == 0) { return false; } write_buffer[0] = 0x04; write_buffer[1] = 0x24; write_buffer[2] = 0xE3; write_buffer[3] = 0x00; write_buffer[4] = 0xD3; write_buffer[5] = 0x02; write_buffer[6] = (byte)count; write_buffer[7] = (byte)(count / 0x100); count++; int checksum = 0; for (int i = 2; i < 224; i++) { checksum ^= write_buffer[i];//校验和算法 } write_buffer[224] = (byte)checksum; write_buffer[225] = 0x0d; write_buffer[226] = 0x0a; result[6] = write_buffer[6]; result[7] = write_buffer[7]; checksum = 0; for (int i = 2; i <= 8; i++) { checksum ^= result[i]; } result[9] = (byte)checksum; try { com.Write(write_buffer, 0, 227); } catch (Exception ex) { MessageBox.Show(ex.Message); } receive_count = 0; // WriteFile(ToHexString(write_buffer)); // WriteFile(ToHexString(result)); return true; } //private void progressBar1_Click(object sender, EventArgs e) //{ // Thread fthread = new Thread(new ThreadStart(SleepT)); // fthread.Start(); // } private delegate void SetPos(int ipos); private void SetTextMessage(int ipos) { if (this.InvokeRequired) { SetPos setpos = new SetPos(SetTextMessage); this.Invoke(setpos, new object[] { ipos }); } else { this.label.Text = ipos.ToString() + "%"; this.progressBar1.Value = Convert.ToInt32(ipos); this.label1.Text = "已下载"; } } private void SleepT() { for (int i = 0; i < 500; i++) { System.Threading.Thread.Sleep(60);//没什么意思,单纯的执行延时 SetTextMessage(100 * i / 500); } } }
时间: 2024-10-05 00:23:57