版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第C#實現(xiàn)簡單串口通信串口通信(SerialCommunications)是指外設和計算機間通過數(shù)據信號線、地線等按位(bit)進行傳輸數(shù)據的一種通信方式,屬于串行通信方式,能夠實現(xiàn)遠距離通信,長度可達1200米。盡管比按字節(jié)(byte)的并行通信慢,但是串口可以在使用一根線發(fā)送數(shù)據的同時用另一根線接收數(shù)據。串口通信最重要的參數(shù)是波特率、數(shù)據位、停止位和奇偶校驗。對于兩個進行通信的端口,這些參數(shù)必須匹配。
串口通信的接口標準有很多,有RS-232C、RS-232、RS-422A、RS-485等。常用的就是RS-232和RS-485。串口通信使用的大多都是DB9接口,如下圖。
1載波檢測(DCD)2接受數(shù)據(RXD)3發(fā)出數(shù)據(TXD)4數(shù)據終端準備好(DTR)5信號地線(SG)6數(shù)據準備好(DSR)7請求發(fā)送(RTS)8清除發(fā)送(CTS)9振鈴指示(RI)
這里我們以RS-232接口進行演示。
1、數(shù)據包格式定為(10bytes):
幀頭(0xAA,0x55),命令字(1byte),地址位(2bytes),數(shù)據位(2bytes),校驗位(1byte,和校驗),幀尾(0xFE,0xFE)
地址位和數(shù)據位都是高位在前。
數(shù)據封裝方法:
//數(shù)據打包
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];//地址高字節(jié)
package[4]=dataaddr[1];//地址低字節(jié)
byte[]value=IntToByteArray(data);
package[5]=value[0];//數(shù)據高字節(jié)
package[6]=value[1];//數(shù)據低字節(jié)
package[7]=CheckSum(package);//校驗位
package[8]=0xFE;//幀尾
package[9]=0xFE;
returnpackage;
}
//將int轉換成2位數(shù)組
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;
}
//獲取串口打開狀態(tài)
publicboolIsOpen
{
get
{
returnserialPort.IsOpen;
}
}
//開始讀取
privatevoidStartReading()
{
if(!_keepReading)
{
_keepReading=true;
thread=newThread(newThreadStart(ReadPort));
thread.Start();
}
}
//停止讀取
privatevoidStopReading()
{
if(_keepReading)
{
_keepReading=false;
thread.Join();
thread=null;
}
}
//讀數(shù)據
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)
{
}
}
}
}
}
//寫數(shù)據
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];//指定格式的某個完整數(shù)據
//串口初始化
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);
}
}
//數(shù)據接收后處理
privatevoidcomm_DataReceived(byte[]readBuffer)
{
try
{
buffer.AddRange(readBuffer);//將數(shù)據放到緩存中
//完整性判斷
while(buffer.Count=10)
{
//查找數(shù)據頭
if(buffer[0]==0xAAbuffer[1]==0x55)
{
//和校驗
bytechecksum=0;
for(inti=0;ii++)
{
checksum+=buffer[i];
}
if(checksum!=buffer[7])
{
buffer.RemoveRange(0,10);//如果校驗失敗,從緩存中刪除這一包數(shù)據
continue;
}
buffer.CopyTo(0,binary_data,0,10);//復制一條完整的數(shù)據到具體的數(shù)據緩存
//讀取硬件版本號
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]);
//這里可以處理數(shù)據更新界面展示
}
buffer.RemoveRange(0,10);
}
else
{
GetCorrect=false;
buffer.RemoveAt(0);//如果數(shù)據開始不是頭,則刪除數(shù)據
}
}
}
catch
{
}
}
//將2位數(shù)組轉換成字符串
privatestaticstringByteArrayToString(bytearr1,bytearr2)
{
intvalue=ByteArrayToInt(arr1,arr2);
stringstr=Convert.ToString(value,10);
returnstr;
}
//將2位數(shù)組轉換成10進制數(shù)
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);//發(fā)送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);//發(fā)送WR_HV命令,地址HARD_VERSION
Delay(100);
if(GetCorrect==true)
{
MessageBox.Show("硬件版本號寫入成
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 管理學考研面試題及答案
- 醫(yī)院感染管理辦法試題含參考答案
- 前列腺增生護理中的健康教育效果評價
- 福建省福州市教師職稱考試(理論知識)在線模擬題庫及答案
- 24年初會考試真題及答案解析,速查
- 同等學力工商管理學考試真題及答案完整版
- 哲理的試題及答案
- 行政事業(yè)單位內控知識競賽試題及答案
- 2025年新版藥品管理法培訓試題含答案
- 海南省事業(yè)單位招聘考試公共基礎知識理論考試考試練習題及答案
- 頭發(fā)白轉黑課件
- 醫(yī)院藥劑科窗口服務規(guī)范化培訓
- 家紡產品綠色生命周期管理
- 消化內鏡治療進修匯報
- 2025-2030塞爾維亞電力行業(yè)市場現(xiàn)狀供需分析及重點企業(yè)投資評估規(guī)劃分析研究報告
- 設備日常點檢管理制度
- QGDW11059.2-2018氣體絕緣金屬封閉開關設備局部放電帶電測試技術現(xiàn)場應用導則第2部分特高頻法
- (高清版)DB62∕T 25-3128-2017 定型臺架綁扎預制箱梁鋼筋骨架施工規(guī)程
- 電梯更換配件勞務合同(2篇)
- 冀人版四年級科學上冊復習資料(分課)
- 區(qū)塊鏈技術助力企業(yè)數(shù)據安全與合規(guī)性管理
評論
0/150
提交評論