




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第C#實現簡單串口通信串口通信(SerialCommunications)是指外設和計算機間通過數據信號線、地線等按位(bit)進行傳輸數據的一種通信方式,屬于串行通信方式,能夠實現遠距離通信,長度可達1200米。盡管比按字節(jié)(byte)的并行通信慢,但是串口可以在使用一根線發(fā)送數據的同時用另一根線接收數據。串口通信最重要的參數是波特率、數據位、停止位和奇偶校驗。對于兩個進行通信的端口,這些參數必須匹配。
串口通信的接口標準有很多,有RS-232C、RS-232、RS-422A、RS-485等。常用的就是RS-232和RS-485。串口通信使用的大多都是DB9接口,如下圖。
1載波檢測(DCD)2接受數據(RXD)3發(fā)出數據(TXD)4數據終端準備好(DTR)5信號地線(SG)6數據準備好(DSR)7請求發(fā)送(RTS)8清除發(fā)送(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];//地址高字節(jié)
package[4]=dataaddr[1];//地址低字節(jié)
byte[]value=IntToByteArray(data);
package[5]=value[0];//數據高字節(jié)
package[6]=value[1];//數據低字節(jié)
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;
}
//獲取串口打開狀態(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;
}
}
//讀數據
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);//發(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. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 班會春節(jié)文化課件
- 廣東省建筑施工企業(yè)安全生產管理人員安全生產(安全管理)測試題及答案(附解析)
- 2025年2月新能源汽車習題庫及參考答案解析
- 玩具行業(yè)人才激勵計劃考核試卷
- 初中語文教學設計與指導
- 稀土金屬礦選礦廠生產自動化與信息集成考核試卷
- 眼科疾病診療與視力保護考核試卷
- 曼漢教育費用分析
- 發(fā)動機結構與維修技術考核試卷
- 肉類產品陳列與貨架管理技巧考核試卷
- 跨國公司的外匯風險管理分析-以TCL科技為例
- 企業(yè)防范用工風險知識講座
- 心理健康教育課件《如何面對考試焦慮》
- 污水源熱泵方案
- 完整版江蘇省政府采購專家?guī)烊霂炜荚囶}庫(1-4套卷)
- 《唐詩中的春夏秋冬》五年級下冊詩詞鑒賞一等獎課件
- 圍擋維修施工方案
- 智能水務一體化管理系統(tǒng)項目售后服務與培訓方案
- 牛安全生產技術-牛常見心血管系統(tǒng)疾病的防治
- 口腔頜面頸部局部解剖-頸部局部解剖(口腔解剖生理學課件)
- 韓國語topik單詞-初級+中級
評論
0/150
提交評論