三菱PLC 串口通信開發心得經驗

三菱PLC 串口通信開發心得

 

備註:

記得兩年前剛開始從事軟件開發工作時,第一份任務就是開發一個程序能夠實現與三菱PLC 串口通信。所謂通信,其實質主要是對PLC 的D寄存器(dword)讀寫操作。但是因爲日本爲了保護其產品,並不開發串口通信協議。在不開發通信協議的情況,如果想實現通信,首先需要做的便是通過數據分析,破解其通信協議。

這裏就不講解如何破解了,主要是介紹下當時博主開發程序的背景。

寫這篇博客的主要目的是爲了分享過去自己的開發經驗,因爲自己在開發的過程中曾經接受過很多開源軟件的幫助,也算是將開源精神延續下去吧

現在這是轉入正題。

 

涉及字節流數據通信,必然要涉及通信協議。鑑於當時的開發需求,博主僅對D 寄存器的讀寫協議分析過。其他寄存器理論上是相似,有興趣的同學可以自行分析數據進行測試。

D 寄存器的通信協議相對比較簡單

主要可以分爲:

1        問候應答協議

2        狀態查詢協議

3        狀態配置協議

4        數據反饋協議







在PLC 通信過程中主要的三個難點在於  寄存器的加密解密, 數據信息加密和解密, 以及字符的校驗。 


寄存器地址 加密過程:

<span style="font-size:18px;">void PLC_dataparse::Encrypt_toPLCaddress( BYTE *parray , const UINT paddress )
{

	int encode_address = 0x1000 + paddress * 2;           

	BYTE encrypt_key = encode_address & 0xf;
	parray[3] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);
	encrypt_key = (encode_address >> 4) & 0xf;
	parray[2] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);
	encrypt_key = (encode_address >> 8) & 0xf;
	parray[1] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);
	encrypt_key = (encode_address >> 12) & 0xf;
	parray[0] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);

}
</span>

數據信息的加密過程:

<span style="font-size:18px;">void PLC_dataparse::Encrypt_toPLCcontent( BYTE * parray , const UINT pcontent )
{

	BYTE encrypt_key = pcontent & 0xf;

	parray[1] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);
	encrypt_key = (pcontent >> 4) & 0xf;
	parray[0] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);
	encrypt_key = (pcontent >> 8) & 0xf;
	parray[3] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);
	encrypt_key = (pcontent >> 12) & 0xf;
	parray[2] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);



}
</span>

添加校驗碼:

<span style="font-size:18px;">void PLC_dataparse::Add_checkcode( BYTE * pdest , BYTE * psrc , const UINT plenth )
{
	int sumtemp = 0;
	for ( unsigned int i = 0; i< plenth; i++)
	{
		sumtemp += (*(psrc + i));
	}

	BYTE encrypt_key = sumtemp & 0xf;			// get low 4 bit 
	pdest[1] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);
	encrypt_key = (sumtemp >> 4) & 0xf;				// get high 4 bit 
	pdest[0] = (encrypt_key<10) ? (encrypt_key + 0x30) : (encrypt_key + 0x41 - 0xa);

}
</span>

提取數據信息:

<span style="font-size:18px;">double PLC_dataparse::Get_content( BYTE *parray , UINT plenth )
{
	BYTE dl_data[4];
	BYTE pre_data[4];
	double pow_numb;

	for (int j = 0; j<4; j++)                     //剔除雜碼
	{
		pre_data[j] = parray[j + 1];
	}

	//////////////////////////////////////////////////////////////////////////
	dl_data[1] = (pre_data[0]<0x40) ? (pre_data[0] - 0x30) : (pre_data[0] - 0x41 + 0x0a);
	dl_data[0] = (pre_data[1]<0x40) ? (pre_data[1] - 0x30) : (pre_data[1] - 0x41 + 0x0a);
	dl_data[3] = (pre_data[2]<0x40) ? (pre_data[2] - 0x30) : (pre_data[2] - 0x41 + 0x0a);
	dl_data[2] = (pre_data[3]<0x40) ? (pre_data[3] - 0x30) : (pre_data[3] - 0x41 + 0x0a);


	for (int i = 0; i<4; i++)
	{
		dl_data[i] = dl_data[i] & 0xf;
	}

	pow_numb = dl_data[3] * pow(16.0, 3.0) + dl_data[2] * pow(16.0, 2.0) + dl_data[1] * 16 + dl_data[0];
	return pow_numb;

}
</span>

校驗接受數據校驗碼:

int PLC_dataparse::Check_checkcode( BYTE *parray , UINT plenth )
{
	int  error_code  = PLC_SUCCESS;
	const int  legal_lenth = 8;           //the define legal lenth  

	if (plenth != legal_lenth)
	{
		error_code = PLC_CRCERROR;
		return error_code;
	}
	//////////////////////////////////////////////////////////////////////////
	//check  code 
	else
	{
		BYTE *pbyte = new BYTE[2];
		// split out  head mark , tail check out 
		Add_checkcode(&pbyte[0], &parray[1], plenth - 3);    //calculate the check code 
	
		for (int j = 0; j<2; j++)
		{
			if (pbyte[j] != parray[plenth - 2 + j])
			{
				error_code = PLC_CRCERROR;
				break;
			}
		}
		// release the pointer and it's stack
		delete pbyte;
		pbyte = NULL;
		return error_code;
	}

}


上述代碼是使用PLC 窗口通信的最大的難點。 一旦掌握幾大難點,基本PLC 的串口通信就


另附上一份當時自己開發的 三菱PLC D寄存器調試程序。 


備註: 該調試工具 僅支持xp 系統


歡迎關注我的github: https://github.com/lionm117

一起學習,共同成長



測試程序下載鏈接:http://download.csdn.net/detail/hesiyuan4/8304407

動態鏈接庫下載鏈接: http://download.csdn.net/detail/hesiyuan4/8394939

源碼庫下載鏈接:    http://download.csdn.net/detail/hesiyuan4/8394961




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章