go語言串口通訊怎么設(shè)置 go語言通道

go語言做串口通信,我應(yīng)該從什么地方入手,IO是什

//創(chuàng)建一個串口通訊 SerialPort CurrentPort = null; CurrentPort = new SerialPort(); CurrentPortReadBufferSize = 128; CurrentPortPortName = comName; //端口號 CurrentPortBaudRate = bandRate; //比特率 CurrentPortParity =parity;/go語言做串口通信,我應(yīng)該從什么地方入手,IO是什

創(chuàng)新互聯(lián)是一家企業(yè)級云計算解決方案提供商,超15年IDC數(shù)據(jù)中心運(yùn)營經(jīng)驗(yàn)。主營GPU顯卡服務(wù)器,站群服務(wù)器,綿陽電信機(jī)房,海外高防服務(wù)器,機(jī)柜大帶寬、租用·托管,動態(tài)撥號VPS,海外云手機(jī),海外云服務(wù)器,海外服務(wù)器租用托管等。

golang開發(fā)modbus-rtu通信

用到的gomodbus包是壇友slzm40編寫和共享的,感謝他的無私分享,本帖只是拋磚引玉,將我自己學(xué)習(xí)的一些經(jīng)歷分享給大家;有關(guān)modbus包可以直接向slzm40請教或一起討論;

包地址"github.com/thinkgos/gomodbus";

添加一對虛擬串口

打開modbus-slave從機(jī)軟件,用來測試從機(jī);

需要注意設(shè)置通信地址和讀取寄存器的地址和數(shù)量;

查看可用串口,因?yàn)樘摂M串口選擇com1和com2,虛擬中我選擇使用/dev/ttyS1

編譯運(yùn)行,會提示串口打開失敗,這是因?yàn)閘inux對設(shè)備的權(quán)限做了限制

獲取串口讀寫、運(yùn)行等權(quán)限

我們已經(jīng)能正確讀取03寄存器的值;其他功能可以自行測試;

package main

import (

"fmt"

modbus "github.com/thinkgos/gomodbus"

"github.com/thinkgos/gomodbus/mb"

"time"

)

func main(){

//調(diào)用RTUClientProvider的構(gòu)造函數(shù),返回結(jié)構(gòu)體指針

p := modbus.NewRTUClientProvider()

p.Address = "/dev/ttyS1"

p.BaudRate = 115200

p.DataBits = 8

p.Parity = "N"

p.StopBits = 1

p.Timeout = 100 * time.Millisecond

client := mb.NewClient(p)

client.LogMode(true)

err := client.Start()

if err != nil {

fmt.Println("start err,", err)

return

}

for {

value, err := client.ReadHoldingRegisters(1, 1, 3)

if err != nil {

fmt.Println("readHoldErr,", err)

} else {

fmt.Printf("%#v\n", value)

}

time.Sleep(time.Second * 3)

}

}

關(guān)于串口通訊

利用串口進(jìn)行數(shù)據(jù)通訊在通訊領(lǐng)域重占有著重要的地位。利用RS232-RS485進(jìn)行數(shù)據(jù)信號的采集和傳遞是VC編程的又一大熱點(diǎn)。串口通訊在通訊軟件重有著十分廣泛的應(yīng)用。如電話、傳真、視頻和各種控制等。在各種開發(fā)工具中間,VC由于功能強(qiáng)大和靈活,同時也得到了Microsoft的最大支持,所以在一般進(jìn)行涉及硬件操作的通訊編程中,大都推薦使用VC作為開發(fā)工具。然而工業(yè)控制串口通訊這個又不同于一般的串口通訊程序,因?yàn)榭刂仆鈬O(shè)備傳送的大都是十六進(jìn)制數(shù)據(jù)(BYTE類型),所以,為了提高程序的運(yùn)行穩(wěn)定性,我們在編寫程序進(jìn)行通訊時可以不考慮傳送BYTE類型數(shù)據(jù)的工作。

串口通訊目前流行的方法大概有兩種:一是利用Microsoft提供的CMSCOMM控件進(jìn)行通訊,不過現(xiàn)在很多程序員都覺應(yīng)該放棄這種方式。二是利用WINAPI函數(shù)進(jìn)行編程,這種編程的難度最高,要求你要掌握很多的API函數(shù)。三是利用現(xiàn)在網(wǎng)絡(luò)上面提供的一些串口通訊控件進(jìn)行編寫,比如CSerial類等。

程序?qū)崿F(xiàn):

我在經(jīng)過許多的項(xiàng)目的開發(fā)和實(shí)踐中發(fā)現(xiàn),采用WIN API函數(shù)進(jìn)行串口的開發(fā)能夠給程序員很大的控件,并且程序運(yùn)也很穩(wěn)定。所以我將與串口接觸的函數(shù)進(jìn)行封裝,然后在各個工程中進(jìn)行調(diào)用,效果還是比較好的,現(xiàn)將各個函數(shù)和調(diào)用方法列舉出來,希望對各位有所幫助。

一、設(shè)置串口相關(guān)工作

#define MAXBLOCK 2048

#define XON 0x11

#define XOFF 0x13

BOOL SetCom(HANDLE m_hCom, const char *m_sPort, int BaudRate, int Databit, CString parity, CString stopbit)

{

COMMTIMEOUTS TimeOuts; ///串口輸出時間 超時設(shè)置

DCB dcb; ///與端口匹配的設(shè)備

m_hCom=CreateFile(m_sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,

NULL); // 以重疊方式打開串口

if(m_hCom==INVALID_HANDLE_VALUE)

{

AfxMessageBox("設(shè)置串口部分,串口打開失敗"); /////重疊方式 異步通信(INVALID_HANDLE_VALUE)函數(shù)失敗。

return FALSE;

}

SetupComm(m_hCom,MAXBLOCK,MAXBLOCK); //設(shè)置緩沖區(qū)

memset(TimeOuts,0,sizeof(TimeOuts));

TimeOuts.ReadIntervalTimeout=MAXDWORD; // 把間隔超時設(shè)為最大,把總超時設(shè)為0將導(dǎo)致ReadFile立即返回并完成操作

TimeOuts.ReadTotalTimeoutMultiplier=0; //讀時間系數(shù)

TimeOuts.ReadTotalTimeoutConstant=0; //讀時間常量

TimeOuts.WriteTotalTimeoutMultiplier=50; //總超時=時間系數(shù)*要求讀/寫的字符數(shù)+時間常量

TimeOuts.WriteTotalTimeoutConstant=2000; //設(shè)置寫超時以指定WriteComm成員函數(shù)中的

SetCommTimeouts(m_hCom, TimeOuts); //GetOverlappedResult函數(shù)的等待時間*/

if(!GetCommState(m_hCom, dcb)) ////串口打開方式、端口、波特率 與端口匹配的設(shè)備

{

AfxMessageBox("GetCommState Failed");

return FALSE;

}

dcb.fParity=TRUE; //允許奇偶校驗(yàn)

dcb.fBinary=TRUE;

if(parity=="NONE")

dcb.Parity=NOPARITY;

if(parity=="ODD")

dcb.Parity=ODDPARITY;

if(parity=="EVEN")

dcb.Parity=EVENPARITY;

if(stopbit=="1")//設(shè)置波特率

dcb.StopBits=ONESTOPBIT;

//if(stopbit=="0")//設(shè)置波特率

// dcb.StopBits=NONESTOPBIT;

if(stopbit=="2")//設(shè)置波特率

dcb.StopBits=TWOSTOPBITS;

BOOL m_bEcho=FALSE; ///

int m_nFlowCtrl=0;

BOOL m_bNewLine=FALSE; ///

dcb.BaudRate=BaudRate; // 波特率

dcb.ByteSize=Databit; // 每字節(jié)位數(shù)

// 硬件流控制設(shè)置

dcb.fOutxCtsFlow=m_nFlowCtrl==1;

dcb.fRtsControl=m_nFlowCtrl==1 ?RTS_CONTROL_HANDSHAKE:RTS_CONTROL_ENABLE;

// XON/XOFF流控制設(shè)置(軟件流控制!)

dcb.fInX=dcb.fOutX=m_nFlowCtrl==2;

dcb.XonChar=XON;

dcb.XoffChar=XOFF;

dcb.XonLim=50;

dcb.XoffLim=50;

if(SetCommState(m_hCom, dcb))

return TRUE; ////com的通訊口設(shè)置

else

{

AfxMessageBox("串口已打開,設(shè)置失敗");

return FALSE;

}

}

二、讀串口操作:

int ReadCom(HANDLE hComm, BYTE inbuff[], DWORD nBytesRead, int ReadTime)

{

DWORD lrc; ///縱向冗余校驗(yàn)

DWORD endtime; /////////jiesuo

static OVERLAPPED ol;

int ReadNumber=0;

int numCount=0 ; //控制讀取的數(shù)目

DWORD dwErrorMask,nToRead;

COMSTAT comstat;

ol.Offset=0; ///相對文件開始的字節(jié)偏移量

ol.OffsetHigh=0; ///開始傳送數(shù)據(jù)的字節(jié)偏移量的高位字,管道和通信時調(diào)用進(jìn)程可忽略。

ol.hEvent=NULL; ///標(biāo)識事件,數(shù)據(jù)傳送完成時設(shè)為信號狀態(tài)

ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

endtime=GetTickCount()+ReadTime;//GetTickCount()取回系統(tǒng)開始至此所用的時間(毫秒)

for(int i=0;i2000;i++)

inbuff[i]=0;

Sleep(ReadTime);

ClearCommError(hComm,dwErrorMask,comstat);

nToRead=min(2000,comstat.cbInQue);

if(int(nToRead)2)

goto Loop;

if(!ReadFile(hComm,inbuff,nToRead,nBytesRead,ol))

{

if((lrc=GetLastError())==ERROR_IO_PENDING)

{

///////////////////

endtime=GetTickCount()+ReadTime;//GetTickCount()取回系統(tǒng)開始至此所用的時間(毫秒)

while(!GetOverlappedResult(hComm,ol,nBytesRead,FALSE))//該函數(shù)取回重疊操作的結(jié)果

{

if(GetTickCount()endtime)

break;

}

}

}

return 1;

Loop: return 0;

}

三、寫串口命令

int WriteCom(HANDLE hComm, BYTE Outbuff[], int size, int bWrite[])

{

DWORD nBytesWrite,endtime,lrc;

static OVERLAPPED ol;

DWORD dwErrorMask,dwError;

COMSTAT comstat;

ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

ol.Offset=0;

ol.OffsetHigh=0;

ol.hEvent=NULL; ///標(biāo)識事件,數(shù)據(jù)傳送完成時,將它設(shè)為信號狀態(tài)

ClearCommError(hComm,dwErrorMask,comstat);

if(!WriteFile(hComm,Outbuff,size,nBytesWrite,ol))

{

if((lrc=GetLastError())==ERROR_IO_PENDING)

{

endtime=GetTickCount()+1000;

while(!GetOverlappedResult(hComm,ol,nBytesWrite,FALSE))

{

dwError=GetLastError();

if(GetTickCount()endtime)

{

AfxMessageBox("寫串口時間過長,目前串口發(fā)送緩沖區(qū)中的數(shù)據(jù)數(shù)目為空");

break;

}

if(dwError=ERROR_IO_INCOMPLETE)

continue; //未完全讀完時的正常返回結(jié)果

else

{

// 發(fā)生錯誤,嘗試恢復(fù)!

ClearCommError(hComm,dwError,comstat);

break;

}

}

}

}

FlushFileBuffers(hComm);

PurgeComm(hComm,PURGE_TXCLEAR);

bWrite=0;

return 1;

}

四、調(diào)用方法很簡單,只需要將你的串口參數(shù)進(jìn)行簡單的設(shè)置就可以了。比如:

BOOL Main_OpenCom()//設(shè)置COM

{

int Boundrate=9600;//波特率

CString StopBits="1";//停止位

int DataBits=8;//數(shù)據(jù)位

CString Parity="ODD";//奇偶校驗(yàn)

CString m_Port="COM1";

return SetCom(m_hCom1,m_Port,Boundrate,DataBits,Parity,StopBits);

}

void Main()

{

int SIZE;

DWORD BytestoRead=52*Count+6;//要11個字節(jié)

int BWRITE[2];

int ReadTime=2000;

BYTE Outbuff[12]={0xff,0x00,0xea,0xff,0xea,0xff,0,0,0,0,0,0};

SIZE=sizeof(Outbuff);

WriteCom(m_hCom,Outbuff,SIZE,BWRITE);

ReadCom(m_hCom,m_Inbuff,BytestoRead,ReadTime);

//進(jìn)行湘陰的解包處理

}

文章名稱:go語言串口通訊怎么設(shè)置 go語言通道
當(dāng)前路徑:http://muchs.cn/article36/doeossg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、企業(yè)建站、虛擬主機(jī)搜索引擎優(yōu)化、靜態(tài)網(wǎng)站、網(wǎng)頁設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司