Heim > Artikel > Backend-Entwicklung > Beispiel-Tutorial zur seriellen C#-Kommunikation
Da ich an einem kleinen Projekt teilgenommen habe, das die Steuerung von Relais über die serielle Schnittstelle erforderte, habe ich in den letzten zwei Tagen die grundlegende Programmierung der seriellen Schnittstelle gelernt. Ein Kollege hat ein serielles JAVA-Kommunikationspaket, das jedoch aus dem Internet heruntergeladen wurde. Es ist ziemlich chaotisch und es ist schwierig, den Prozess und Inhalt der seriellen Kommunikation genau zu verstehen. Daher habe ich persönlich grundlegende serielle Kommunikationsprogramme mit C# implementiert, indem ich die Methoden von Online -Experten lernte. Die Lernergebnisse sind unten zusammengefasst. Ich hoffe, dass sie für alle hilfreich sind.
1. Einführung in die serielle Kommunikation
Die serielle Schnittstelle (serielle Schnittstelle) ist eine Art Schnittstelle, die parallele Datenzeichen von der CPU in kontinuierliche umwandeln kann seriell Der Datenstrom wird ausgesendet und der empfangene serielle Datenstrom kann in parallele Datenzeichen umgewandelt und dem CPU-Gerät zugeführt werden. Im Allgemeinen wird die Schaltung, die diese Funktion ausführt, als serielle Schnittstellenschaltung bezeichnet.
Das Konzept der seriellen Kommunikation ist sehr einfach. Der serielle Port sendet und empfängt Bytes Stück für Stück. Obwohl langsamer als die parallele Byte-für-Byte-Kommunikation, kann ein serieller Port Daten auf einem Kabel senden und gleichzeitig Daten auf einem anderen Kabel empfangen. Die wichtigsten Parameter der seriellen Kommunikation sind Baudrate, Datenbits, Stoppbits und Parität. Damit zwei Ports kommunizieren können, müssen diese Parameter übereinstimmen.
1. Baudrate: Dies ist ein Parameter, der die Symbolübertragungsrate misst. Es bezieht sich auf die Änderung der Zeiteinheit nach der Modulation des Signals, dh auf die Anzahl der Trägerparameteränderungen pro Zeiteinheit. Beispielsweise werden 960 Zeichen pro Sekunde übertragen, und jedes Zeichenformat enthält 10 Bits (1 Startbit, 1 Stoppbit, 8 Datenbits), die Baudrate beträgt zu diesem Zeitpunkt 960 Bd und die Bitrate beträgt 10 Bit * 960 Bit/Sekunde = 9600 Bit/s.
2. Datenbits: Dies ist ein Parameter, der die tatsächlichen Datenbits in der Kommunikation misst. Wenn ein Computer ein Informationspaket sendet, betragen die tatsächlichen Daten häufig 8 Bit. Der Standard-ASCII-Code ist 0–127 (7 Bit) und der erweiterte ASCII-Code ist 0–255 (8 Bit).
3. Stop -Bit: Wird verwendet, um die letzten Teile eines einzelnen Pakets darzustellen. Typische Werte sind 1, 1,5 und 2 Bit. Da die Daten auf der Übertragungsleitung zeitgesteuert werden und jedes Gerät über eine eigene Uhr verfügt, kann es während der Kommunikation zu einer geringfügigen Desynchronisation zwischen den beiden Geräten kommen. Das Stoppbit zeigt also nicht nur das Ende der Übertragung an, sondern bietet dem Computer auch die Möglichkeit, die Taktsynchronisation zu korrigieren.
4. Prüfziffer: Eine einfache Fehlererkennungsmethode in der seriellen Kommunikation. Es gibt vier Fehlererkennungsmodi: sogar, ungerade, hoch und niedrig. Natürlich ist es auch möglich, keine Überprüfung zu haben.
2. C#-Klasse zur Programmierung serieller Ports
Ab .NET Framework 2.0 stellt C# die SerialPort-Klasse für die serielle Port-Steuerung bereit. Namespace:System.IO.Ports. Eine ausführliche Einführung in die Mitglieder finden Sie in der MSDN-Dokumentation. Im Folgenden werden seine häufig verwendeten Felder, Methoden und Ereignisse vorgestellt.
1. Häufig verwendete Felder:
名称 | 说明 |
PortName | 获取或设置通信端口 |
BaudRate | 获取或设置串行波特率 |
DataBits | 获取或设置每个字节的标准数据位长度 |
Parity | 获取或设置奇偶校验检查协议 |
StopBits | 获取或设置每个字节的标准停止位数 |
2. Häufig verwendete Methoden:
名称 | 说明 |
Close | 关闭端口连接,将 IsOpen 属性设置为 false,并释放内部 Stream 对象 |
GetPortNames | 获取当前计算机的串行端口名称数组 |
Open | 打开一个新的串行端口连接 |
Read | 从 SerialPort 输入缓冲区中读取 |
Write | 将数据写入串行端口输出缓冲区 |
3. Häufige Ereignisse:
名称 | 说明 |
DataReceived | 表示将处理 SerialPort 对象的数据接收事件的方法 |
3. Grundlegende Verwendung
Das Folgende wird in Kombination mit einem vorhandenen angegeben Relais Grundlegende Verwendung der seriellen Kommunikation als Referenz.
1 using System; 2 using System.Windows.Forms; 3 using System.IO.Ports; 4 using System.Text; 5 6 namespace Traveller_SerialPortControl 7 { 8 public partial class Form1 : Form 9 { 10 //定义端口类 11 private SerialPort ComDevice = new SerialPort(); 12 public Form1() 13 { 14 InitializeComponent(); 15 InitralConfig(); 16 } 17 /// <summary> 18 /// 配置初始化 19 /// </summary> 20 private void InitralConfig() 21 { 22 //查询主机上存在的串口 23 comboBox_Port.Items.AddRange(SerialPort.GetPortNames()); 24 25 if (comboBox_Port.Items.Count > 0) 26 { 27 comboBox_Port.SelectedIndex = 0; 28 } 29 else 30 { 31 comboBox_Port.Text = "未检测到串口"; 32 } 33 comboBox_BaudRate.SelectedIndex = 5; 34 comboBox_DataBits.SelectedIndex = 0; 35 comboBox_StopBits.SelectedIndex = 0; 36 comboBox_CheckBits.SelectedIndex = 0; 37 pictureBox_Status.BackgroundImage = Properties.Resources.red; 38 39 //向ComDevice.DataReceived(是一个事件)注册一个方法Com_DataReceived,当端口类接收到信息时时会自动调用Com_DataReceived方法 40 ComDevice.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived); 41 } 42 43 /// <summary> 44 /// 一旦ComDevice.DataReceived事件发生,就将从串口接收到的数据显示到接收端对话框 45 /// </summary> 46 /// <param name="sender"></param> 47 /// <param name="e"></param> 48 private void Com_DataReceived(object sender, SerialDataReceivedEventArgs e) 49 { 50 //开辟接收缓冲区 51 byte[] ReDatas = new byte[ComDevice.BytesToRead]; 52 //从串口读取数据 53 ComDevice.Read(ReDatas, 0, ReDatas.Length); 54 //实现数据的解码与显示 55 AddData(ReDatas); 56 } 57 58 /// <summary> 59 /// 解码过程 60 /// </summary> 61 /// <param name="data">串口通信的数据编码方式因串口而异,需要查询串口相关信息以获取</param> 62 public void AddData(byte[] data) 63 { 64 if (radioButton_Hex.Checked) 65 { 66 StringBuilder sb = new StringBuilder(); 67 for (int i = 0; i < data.Length; i++) 68 { 69 sb.AppendFormat("{0:x2}" + " ", data[i]); 70 } 71 AddContent(sb.ToString().ToUpper()); 72 } 73 else if (radioButton_ASCII.Checked) 74 { 75 AddContent(new ASCIIEncoding().GetString(data)); 76 } 77 else if (radioButton_UTF8.Checked) 78 { 79 AddContent(new UTF8Encoding().GetString(data)); 80 } 81 else if (radioButton_Unicode.Checked) 82 { 83 AddContent(new UnicodeEncoding().GetString(data)); 84 } 85 else 86 { 87 StringBuilder sb = new StringBuilder(); 88 for (int i = 0; i < data.Length; i++) 89 { 90 sb.AppendFormat("{0:x2}" + " ", data[i]); 91 } 92 AddContent(sb.ToString().ToUpper()); 93 } 94 } 95 96 /// <summary> 97 /// 接收端对话框显示消息 98 /// </summary> 99 /// <param name="content"></param>100 private void AddContent(string content)101 {102 BeginInvoke(new MethodInvoker(delegate103 { 104 textBox_Receive.AppendText(content); 105 }));106 }107 108 /// <summary>109 /// 串口开关110 /// </summary>111 /// <param name="sender"></param>112 /// <param name="e"></param>113 private void button_Switch_Click(object sender, EventArgs e)114 {115 if (comboBox_Port.Items.Count <= 0)116 {117 MessageBox.Show("未发现可用串口,请检查硬件设备");118 return;119 }120 121 if (ComDevice.IsOpen == false)122 {123 //设置串口相关属性124 ComDevice.PortName = comboBox_Port.SelectedItem.ToString();125 ComDevice.BaudRate = Convert.ToInt32(comboBox_BaudRate.SelectedItem.ToString());126 ComDevice.Parity = (Parity)Convert.ToInt32(comboBox_CheckBits.SelectedIndex.ToString());127 ComDevice.DataBits = Convert.ToInt32(comboBox_DataBits.SelectedItem.ToString());128 ComDevice.StopBits = (StopBits)Convert.ToInt32(comboBox_StopBits.SelectedItem.ToString());129 try130 {131 //开启串口132 ComDevice.Open();133 button_Send.Enabled = true;134 }135 catch (Exception ex)136 {137 MessageBox.Show(ex.Message, "未能成功开启串口", MessageBoxButtons.OK, MessageBoxIcon.Error);138 return;139 }140 button_Switch.Text = "关闭";141 pictureBox_Status.BackgroundImage = Properties.Resources.green;142 }143 else144 {145 try146 {147 //关闭串口148 ComDevice.Close();149 button_Send.Enabled = false;150 }151 catch (Exception ex)152 {153 MessageBox.Show(ex.Message, "串口关闭错误", MessageBoxButtons.OK, MessageBoxIcon.Error);154 }155 button_Switch.Text = "开启";156 pictureBox_Status.BackgroundImage = Properties.Resources.red;157 }158 159 comboBox_Port.Enabled = !ComDevice.IsOpen;160 comboBox_BaudRate.Enabled = !ComDevice.IsOpen;161 comboBox_DataBits.Enabled = !ComDevice.IsOpen;162 comboBox_StopBits.Enabled = !ComDevice.IsOpen;163 comboBox_CheckBits.Enabled = !ComDevice.IsOpen;164 }165 166 167 /// <summary>168 /// 将消息编码并发送169 /// </summary>170 /// <param name="sender"></param>171 /// <param name="e"></param>172 private void button_Send_Click(object sender, EventArgs e)173 {174 if (textBox_Receive.Text.Length > 0)175 {176 textBox_Receive.AppendText("\n");177 }178 179 byte[] sendData = null;180 181 if (radioButton_Hex.Checked)182 {183 sendData = strToHexByte(textBox_Send.Text.Trim());184 }185 else if (radioButton_ASCII.Checked)186 {187 sendData = Encoding.ASCII.GetBytes(textBox_Send.Text.Trim());188 }189 else if (radioButton_UTF8.Checked)190 {191 sendData = Encoding.UTF8.GetBytes(textBox_Send.Text.Trim());192 }193 else if (radioButton_Unicode.Checked)194 {195 sendData = Encoding.Unicode.GetBytes(textBox_Send.Text.Trim());196 }197 else198 {199 sendData = strToHexByte(textBox_Send.Text.Trim());200 }201 202 SendData(sendData);203 }204 205 /// <summary>206 /// 此函数将编码后的消息传递给串口207 /// </summary>208 /// <param name="data"></param>209 /// <returns></returns>210 public bool SendData(byte[] data)211 {212 if (ComDevice.IsOpen)213 {214 try215 {216 //将消息传递给串口217 ComDevice.Write(data, 0, data.Length);218 return true;219 }220 catch (Exception ex)221 {222 MessageBox.Show(ex.Message, "发送失败", MessageBoxButtons.OK, MessageBoxIcon.Error);223 }224 }225 else226 {227 MessageBox.Show("串口未开启", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);228 }229 return false;230 }231 232 /// <summary>233 /// 16进制编码234 /// </summary>235 /// <param name="hexString"></param>236 /// <returns></returns>237 private byte[] strToHexByte(string hexString)238 {239 hexString = hexString.Replace(" ", "");240 if ((hexString.Length % 2) != 0) hexString += " ";241 byte[] returnBytes = new byte[hexString.Length / 2];242 for (int i = 0; i < returnBytes.Length; i++)243 returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Replace(" ", ""), 16);244 return returnBytes;245 }246 247 //以下两个指令是结合一款继电器而设计的248 private void button_On_Click(object sender, EventArgs e)249 {250 textBox_Send.Text = "005A540001010000B0";251 }252 253 private void button_Off_Click(object sender, EventArgs e)254 {255 textBox_Send.Text = "005A540002010000B1";256 }257 }258 }
Software implementiert grundlegende Schnittstelle
Das obige ist der detaillierte Inhalt vonBeispiel-Tutorial zur seriellen C#-Kommunikation. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!