C# 직렬 통신 예제 튜토리얼

零下一度
풀어 주다: 2017-06-24 09:51:52
원래의
4873명이 탐색했습니다.

릴레이의 직렬 포트 제어가 필요한 소규모 프로젝트에 참여했기 때문에 지난 이틀 동안 기본적인 직렬 포트 프로그래밍을 배웠습니다. 동료가 JAVA 직렬 통신 패키지를 가지고 있는데 인터넷에서 다운로드한 것인데 상당히 지저분하고 직렬 통신의 과정과 내용을 정확하게 파악하기 어렵습니다. 그래서 온라인 전문가들의 방법을 배우며 직접 C#을 활용한 기본적인 직렬통신 프로그래밍을 구현해보았습니다. 학습 결과는 아래와 같습니다. 모든 분들께 도움이 되기를 바랍니다.

1. 직렬 통신 소개

직렬 인터페이스(직렬 포트)는 CPU에서 받은 병렬 데이터 문자를 연속적인 직렬 데이터 스트림으로 변환하여 동시에 전송할 수 있는 유형입니다. , 수신된 직렬 데이터 스트림은 장치가 병렬 데이터 문자로 변환되어 CPU에 공급될 수 있습니다. 일반적으로 이 기능을 완성하는 회로를 직렬 인터페이스 회로라고 합니다.

직렬 통신의 개념은 매우 간단합니다. 직렬 포트는 비트 단위로 바이트를 보내고 받습니다. 바이트별 병렬 통신보다 속도는 느리지만 직렬 포트는 한 회선에서 데이터를 보내고 다른 회선에서 데이터를 수신할 수 있습니다. 직렬 통신의 가장 중요한 매개변수는 전송 속도, 데이터 비트, 정지 비트 및 패리티입니다. 두 포트가 통신하려면 이러한 매개변수가 일치해야 합니다.

1. 전송 속도(Baud rate): 기호 전송 속도를 측정하는 매개변수입니다. 신호가 변조된 후 단위 시간의 변화, 즉 단위 시간당 반송파 매개 변수 변경 수를 나타냅니다. 예를 들어 초당 960개의 문자가 전송되고 각 문자 형식에는 10비트(1개 시작 비트, 1개)가 포함됩니다. 정지 비트, 8 데이터 비트), 이때 전송 속도는 960Bd, 비트 속도는 10비트 * 960비트/초 = 9600bps입니다.

2. 데이터 비트: 통신 시 실제 데이터 비트를 측정하는 매개변수입니다. 컴퓨터가 정보 패킷을 보낼 때 실제 데이터는 8비트가 아닌 경우가 많습니다. 표준 값은 6, 7, 8비트입니다. 표준 ASCII 코드는 0~127(7비트)이고, 확장 ASCII 코드는 0~255(8비트)입니다.

3. 정지 비트: 단일 패킷의 마지막 몇 비트를 나타내는 데 사용됩니다. 일반적인 값은 1, 1.5, 2비트입니다. 데이터는 전송 라인에서 시간이 측정되고 각 장치에는 자체 시계가 있으므로 통신 중에 두 장치 간에 작은 비동기화가 발생할 수 있습니다. 따라서 정지 비트는 전송의 끝을 나타낼 뿐만 아니라 컴퓨터에 시계 동기화를 수정할 수 있는 기회도 제공합니다.

4. 체크 디지트 : 시리얼 통신에서의 간단한 에러 검출 방식. 오류 감지 모드에는 짝수, 홀수, 높음, 낮음의 네 가지가 있습니다. 물론 체크 숫자가 없을 수도 있습니다.

2. C# 직렬 포트 프로그래밍 클래스

.NET Framework 2.0부터 C#에서는 직렬 포트 제어를 위한 SerialPort 클래스를 제공합니다. 네임스페이스:System.IO.Ports. 자세한 회원 소개는 MSDN 문서를 참고하세요. 다음은 일반적으로 사용되는 필드, 메소드 및 이벤트를 소개합니다.

1. 공통 필드:

Name Description
PortName 통신 포트 가져오기 또는 설정
BaudRate 가져오기 또는 설정 string Line Baud Rate
DataBits 바이트당 표준 데이터 비트 길이 가져오기 또는 설정
Parity 패리티 검사 프로토콜 가져오기 또는 설정
StopBits 바이트당 표준 정지 비트 수를 가져오거나 설정합니다

2. 일반적으로 사용되는 방법:

입력 버퍼Write에 데이터 쓰기
Name Description
Close 포트 연결을 닫고 IsOpen을 설정합니다. 속성 false에 대한 속성 및 내부 스트림 객체를 릴리스
getportNames 현재 컴퓨터의 직렬 포트 이름 배열 가져옵니다.
Read Read from SerialPort
직렬 포트 출력 버퍼

3. 일반 이벤트:

Name

Description

개체 3. 기본 사용법
DataReceived 데이터 수신 이벤트를 처리할 방법을 나타냅니다. SerialPort

기존 릴레이를 기준으로 시리얼 통신의 기본 사용법을 참고해 드립니다.

  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 }
로그인 후 복사

소프트웨어는 기본 인터페이스를 구현합니다

위 내용은 C# 직렬 통신 예제 튜토리얼의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿