




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第C#實現簡單串口通信串口通信(SerialCommunications)是指外設和計算機間通過數據信號線、地線等按位(bit)進行傳輸數據的一種通信方式,屬于串行通信方式,能夠實現遠距離通信,長度可達1200米。盡管比按字節(byte)的并行通信慢,但是串口可以在使用一根線發送數據的同時用另一根線接收數據。串口通信最重要的參數是波特率、數據位、停止位和奇偶校驗。對于兩個進行通信的端口,這些參數必須匹配。
串口通信的接口標準有很多,有RS-232C、RS-232、RS-422A、RS-485等。常用的就是RS-232和RS-485。串口通信使用的大多都是DB9接口,如下圖。
1載波檢測(DCD)2接受數據(RXD)3發出數據(TXD)4數據終端準備好(DTR)5信號地線(SG)6數據準備好(DSR)7請求發送(RTS)8清除發送(CTS)9振鈴指示(RI)
這里我們以RS-232接口進行演示。
1、數據包格式定為(10bytes):
幀頭(0xAA,0x55),命令字(1byte),地址位(2bytes),數據位(2bytes),校驗位(1byte,和校驗),幀尾(0xFE,0xFE)
地址位和數據位都是高位在前。
數據封裝方法:
//數據打包
privatebyte[]DataPackage(bytecmd,intaddr,intdata)
{
byte[]package=newbyte[10];
package[0]=0xAA;//幀頭
package[1]=0x55;
package[2]=cmd;//命令字
byte[]dataaddr=IntToByteArray(addr);
package[3]=dataaddr[0];//地址高字節
package[4]=dataaddr[1];//地址低字節
byte[]value=IntToByteArray(data);
package[5]=value[0];//數據高字節
package[6]=value[1];//數據低字節
package[7]=CheckSum(package);//校驗位
package[8]=0xFE;//幀尾
package[9]=0xFE;
returnpackage;
}
//將int轉換成2位數組
privatestaticbyte[]IntToByteArray(intvalue)
{
inthvalue=(value8)0xFF;
intlValue=value0xFF;
byte[]arr=newbyte[]{(byte)hvalue,(byte)lValue};
returnarr;
}
//得到和校驗碼
privatebyteCheckSum(byte[]package)
{
bytechecksum=0;
for(inti=0;ipackage.Length;i++)
{
checksum+=package[i];
}
returnchecksum;
}
2、串口調用封裝類CommHelper.cs
internalclassCommHelper
{
//委托
publicdelegatevoidEventHandle(byte[]readBuffer);
publiceventEventHandleDataReceived;
publicSerialPortserialPort;
privateThreadthread;
volatilebool_keepReading;
publicCommHelper()
{
serialPort=newSerialPort();
thread=null;
_keepReading=false;
serialPort.ReadTimeout=-1;
serialPort.WriteTimeout=1000;
}
//獲取串口打開狀態
publicboolIsOpen
{
get
{
returnserialPort.IsOpen;
}
}
//開始讀取
privatevoidStartReading()
{
if(!_keepReading)
{
_keepReading=true;
thread=newThread(newThreadStart(ReadPort));
thread.Start();
}
}
//停止讀取
privatevoidStopReading()
{
if(_keepReading)
{
_keepReading=false;
thread.Join();
thread=null;
}
}
//讀數據
privatevoidReadPort()
{
while(_keepReading)
{
if(serialPort.IsOpen)
{
intcount=serialPort.BytesToRead;
if(count0)
{
byte[]readBuffer=newbyte[count];
try
{
Application.DoEvents();
serialPort.Read(readBuffer,0,count);
DataReceived.Invoke(readBuffer);
Thread.Sleep(100);
}
catch(TimeoutException)
{
}
}
}
}
}
//寫數據
publicvoidWritePort(byte[]send,intoffSet,intcount)
{
if(IsOpen)
{
serialPort.Write(send,offSet,count);
}
}
//打開
publicvoidOpen()
{
Close();
try
{
serialPort.Open();
serialPort.RtsEnable=true;
if(serialPort.IsOpen)
{
StartReading();
}
else
{
MessageBox.Show("串口打開失敗!");
}
}
catch
{
}
}
//關閉
publicvoidClose()
{
StopReading();
serialPort.Close();
}
}
3、調用(模擬測試讀寫硬件版本號)
//地址存儲信息定義
privatestaticintHARD_VERSION=0;
//硬件版本號
//命令定義
privatestaticbyteRD_HV=0;
//讀硬件版本
privatestaticbyteWR_HV=1;
//寫硬件版本
privateCommHelpercomm=newCommHelper();
privateboolGetCorrect=false;//用來標識是否已經接收到返回值
privateListbytebuffer=newListbyte(1024);//默認分配1M內存,限制不能超過
privatebyte[]binary_data=newbyte[10];//指定格式的某個完整數據
//串口初始化
privatevoidInitComm()
{
comm.serialPort.PortName="COM1";
comm.serialPort.BaudRate=19200;
try
{
comm.Open();
}
catch(Exceptionex)
{
MessageBox.Show(ex.Message);
}
if(comm.IsOpen)
{
comm.DataReceived+=newCommHelper.EventHandle(comm_DataReceived);
}
}
//數據接收后處理
privatevoidcomm_DataReceived(byte[]readBuffer)
{
try
{
buffer.AddRange(readBuffer);//將數據放到緩存中
//完整性判斷
while(buffer.Count=10)
{
//查找數據頭
if(buffer[0]==0xAAbuffer[1]==0x55)
{
//和校驗
bytechecksum=0;
for(inti=0;ii++)
{
checksum+=buffer[i];
}
if(checksum!=buffer[7])
{
buffer.RemoveRange(0,10);//如果校驗失敗,從緩存中刪除這一包數據
continue;
}
buffer.CopyTo(0,binary_data,0,10);//復制一條完整的數據到具體的數據緩存
//讀取硬件版本號
if(binary_data[2]==RD_HVByteArrayToInt(binary_data[3],binary_data[4])==HARD_VERSION)//命令字為讀RD_HV,地址HARD_VERSION
{
GetCorrect=true;
stringdata=ByteArrayToString(binary_data[5],binary_data[6]);
//這里可以處理數據更新界面展示
}
buffer.RemoveRange(0,10);
}
else
{
GetCorrect=false;
buffer.RemoveAt(0);//如果數據開始不是頭,則刪除數據
}
}
}
catch
{
}
}
//將2位數組轉換成字符串
privatestaticstringByteArrayToString(bytearr1,bytearr2)
{
intvalue=ByteArrayToInt(arr1,arr2);
stringstr=Convert.ToString(value,10);
returnstr;
}
//將2位數組轉換成10進制數
privatestaticintByteArrayToInt(bytearr1,bytearr2)
{
byte[]arr=newbyte[]{arr1,arr2};
intvalue=(int)((arr[0]0xFF)8)
|(arr[1]0xFF);
returnvalue;
}
//讀取硬件版本號
privatevoidReadHV()
{
GetCorrect=false;
try
{
comm.WritePort(DataPackage(RD_HV,HARD_VERSION,0),0,10);//發送RD_E2P命令,地址HARD_VERSION
Delay(100);
if(GetCorrect==true)
{
MessageBox.Show("硬件版本號讀取成功!");
}
else
{
MessageBox.Show("硬件版本號讀取失敗!");
}
}
catch(Exceptionex)
{
MessageBox.Show(ex.Message);
}
}
//寫入硬件版本號
privatevoidWriteHV()
{
if(tbVersion.Text.Length==4isLegal(tbVersion.Text))//限定只能寫入4個字符且輸入合法
{
try
{
intbuf=Convert.ToInt32(tbVersion.Text);
GetCorrect=false;
comm.WritePort(DataPackage(WR_HV,HARD_VERSION,buf),0,10);//發送WR_HV命令,地址HARD_VERSION
Delay(100);
if(GetCorrect==true)
{
MessageBox.Show("硬件版本號寫入成
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年海南從業資格考試題
- 2020年學生用文具產品質量廣西監督抽查實施細則
- 合作社互助資金借款協議
- 對老師深深的感激之情抒情作文6篇
- 國際旅行健康證明及出入境記錄證明書(5篇)
- 2025年導游資格證考試筆試模擬試卷:旅游政策法規解讀解析題
- 北京稅務局股權轉讓協議
- 個人成長故事及感想(15篇)
- 環保事件背后的思考議論文(11篇)
- 2025年安全評價師(初級)職業技能鑒定案例分析解析卷
- eps泡沫生產工藝圖
- 拒絕假努力讓努力更高效-2023-2024學年熱點主題班會大觀園(全國通用)課件
- 新視野大學英語(第四版)讀寫教程2(思政智慧版)課件 Unit 4 Mission and exploration of our time Section A
- 五年級下冊語文試題課外名著閱讀之《三國演義》閱讀訓練(含答案)部編版
- 支原體感染后護理查房課件
- DB63-T 2220-2023 風積沙填筑路基技術規范
- 工程股權轉讓協議
- 高位截癱的護理查房
- 北京大學考博英語歷年真題及詳解
- lemontree中英文對照打印版
- 手術物品清點手術室護理實踐指南課件
評論
0/150
提交評論