A. 三菱plc rs通訊指令
串列數據傳送通訊指令rs只有十六位連續執行型,此編程格式為:
rs
d200
d0
d500
d1
*d200:發送數據寄存器起始地址編號,只能用寄存器d
*d0:發送數據點數,可以用d或者數值,其范圍是:0---4096,如果不發送只接收請設為0
p.l.c.技.術.網——可編程式控制制器技術門戶
*d500:接收數據寄存器起始地址編號,只能用寄存器d
*d1:接收數據點數,可以用d或者數值,其范圍是:0---4096,如果不接收只發送設為0
注:
1、d0+d1的和要小於或等於8000
2、使用rs指令前要根據所通訊設備的要求先設定好通訊格式,設定方法為寫入特殊寄存器d8120
B. 關於串口通訊
利用串口進行數據通訊在通訊領域重佔有著重要的地位。利用RS232-RS485進行數據信號的採集和傳遞是VC編程的又一大熱點。串口通訊在通訊軟體重有著十分廣泛的應用。如電話、傳真、視頻和各種控制等。在各種開發工具中間,VC由於功能強大和靈活,同時也得到了Microsoft的最大支持,所以在一般進行涉及硬體操作的通訊編程中,大都推薦使用VC作為開發工具。然而工業控制串口通訊這個又不同於一般的串口通訊程序,因為控制外圍設備傳送的大都是十六進制數據(BYTE類型),所以,為了提高程序的運行穩定性,我們在編寫程序進行通訊時可以不考慮傳送BYTE類型數據的工作。
串口通訊目前流行的方法大概有兩種:一是利用Microsoft提供的CMSCOMM控制項進行通訊,不過現在很多程序員都覺應該放棄這種方式。二是利用WINAPI函數進行編程,這種編程的難度最高,要求你要掌握很多的API函數。三是利用現在網路上面提供的一些串口通訊控制項進行編寫,比如CSerial類等。
程序實現:
我在經過許多的項目的開發和實踐中發現,採用WIN API函數進行串口的開發能夠給程序員很大的控制項,並且程序運也很穩定。所以我將與串口接觸的函數進行封裝,然後在各個工程中進行調用,效果還是比較好的,現將各個函數和調用方法列舉出來,希望對各位有所幫助。
一、設置串口相關工作
#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; ///串口輸出時間 超時設置
DCB dcb; ///與埠匹配的設備
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("設置串口部分,串口打開失敗"); /////重疊方式 非同步通信(INVALID_HANDLE_VALUE)函數失敗。
return FALSE;
}
SetupComm(m_hCom,MAXBLOCK,MAXBLOCK); //設置緩沖區
memset(&TimeOuts,0,sizeof(TimeOuts));
TimeOuts.ReadIntervalTimeout=MAXDWORD; // 把間隔超時設為最大,把總超時設為0將導致ReadFile立即返回並完成操作
TimeOuts.ReadTotalTimeoutMultiplier=0; //讀時間系數
TimeOuts.ReadTotalTimeoutConstant=0; //讀時間常量
TimeOuts.WriteTotalTimeoutMultiplier=50; //總超時=時間系數*要求讀/寫的字元數+時間常量
TimeOuts.WriteTotalTimeoutConstant=2000; //設置寫超時以指定WriteComm成員函數中的
SetCommTimeouts(m_hCom, &TimeOuts); //GetOverlappedResult函數的等待時間*/
if(!GetCommState(m_hCom, &dcb)) ////串口打開方式、埠、波特率 與埠匹配的設備
{
AfxMessageBox("GetCommState Failed");
return FALSE;
}
dcb.fParity=TRUE; //允許奇偶校驗
dcb.fBinary=TRUE;
if(parity=="NONE")
dcb.Parity=NOPARITY;
if(parity=="ODD")
dcb.Parity=ODDPARITY;
if(parity=="EVEN")
dcb.Parity=EVENPARITY;
if(stopbit=="1")//設置波特率
dcb.StopBits=ONESTOPBIT;
//if(stopbit=="0")//設置波特率
// dcb.StopBits=NONESTOPBIT;
if(stopbit=="2")//設置波特率
dcb.StopBits=TWOSTOPBITS;
BOOL m_bEcho=FALSE; ///
int m_nFlowCtrl=0;
BOOL m_bNewLine=FALSE; ///
dcb.BaudRate=BaudRate; // 波特率
dcb.ByteSize=Databit; // 每位元組位數
// 硬體流控制設置
dcb.fOutxCtsFlow=m_nFlowCtrl==1;
dcb.fRtsControl=m_nFlowCtrl==1 ?RTS_CONTROL_HANDSHAKE:RTS_CONTROL_ENABLE;
// XON/XOFF流控制設置(軟體流控制!)
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的通訊口設置
else
{
AfxMessageBox("串口已打開,設置失敗");
return FALSE;
}
}
二、讀串口操作:
int ReadCom(HANDLE hComm, BYTE inbuff[], DWORD &nBytesRead, int ReadTime)
{
DWORD lrc; ///縱向冗餘校驗
DWORD endtime; /////////jiesuo
static OVERLAPPED ol;
int ReadNumber=0;
int numCount=0 ; //控制讀取的數目
DWORD dwErrorMask,nToRead;
COMSTAT comstat;
ol.Offset=0; ///相對文件開始的位元組偏移量
ol.OffsetHigh=0; ///開始傳送數據的位元組偏移量的高位字,管道和通信時調用進程可忽略。
ol.hEvent=NULL; ///標識事件,數據傳送完成時設為信號狀態
ol.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
endtime=GetTickCount()+ReadTime;//GetTickCount()取回系統開始至此所用的時間(毫秒)
for(int i=0;i<2000;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()取回系統開始至此所用的時間(毫秒)
while(!GetOverlappedResult(hComm,&ol,&nBytesRead,FALSE))//該函數取回重疊操作的結果
{
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; ///標識事件,數據傳送完成時,將它設為信號狀態
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("寫串口時間過長,目前串口發送緩沖區中的數據數目為空");
break;
}
if(dwError=ERROR_IO_INCOMPLETE)
continue; //未完全讀完時的正常返回結果
else
{
// 發生錯誤,嘗試恢復!
ClearCommError(hComm,&dwError,&comstat);
break;
}
}
}
}
FlushFileBuffers(hComm);
PurgeComm(hComm,PURGE_TXCLEAR);
bWrite=0;
return 1;
}
四、調用方法很簡單,只需要將你的串口參數進行簡單的設置就可以了。比如:
BOOL Main_OpenCom()//設置COM
{
int Boundrate=9600;//波特率
CString StopBits="1";//停止位
int DataBits=8;//數據位
CString Parity="ODD";//奇偶校驗
CString m_Port="COM1";
return SetCom(m_hCom1,m_Port,Boundrate,DataBits,Parity,StopBits);
}
void Main()
{
int SIZE;
DWORD BytestoRead=52*Count+6;//要11個位元組
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);
//進行湘陰的解包處理
}
C. linux串口通信代碼解釋,一句一句來
簡單說幾句吧,linux下的設備都是文件,流程也無非是open, read/write, close等
當然,串口你得設置各種屬性才行對不對,比如在win下的超級終端就設置了波特率啊,停止位啊,奇偶校驗啊什麼的,這些屬性都通過
int tcgetattr(int fd, struct termios *termios_p);
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);函數來設置。
完整代碼嗎自己去google,一把一把的,其實最重要的是設置好屬性,剩下的就是read,write的問題咯。
希望對你有用
對了,了解終端函數的詳情請在linux命令行終端獲取: man termios