⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modbus.c

📁 基于Hitech和C166的Modbus协议
💻 C
📖 第 1 页 / 共 2 页
字号:
				temp2 &= temp1;
				temp1 = temp5 + 2;
				Asc1_Tx_BUF[temp1] = temp2;
				Deal_all_OK = 1;
				//读取离散输出是否正常
				if (Deal_all_OK == 0)
				{
					Asc1_Tx_BUF[1] = 0x81;
					Asc1_Tx_BUF[2] = 0x04;
					Asc1_Tx_lengh = 3;
				}
			}
		}
	}

	if (Deal_all_OK == 1)
	{
		Deal_all_OK = 0;
		//计算发送缓冲区
		Asc1_Tx_lengh = 3 + temp5;
		crc_cal( Asc1_Tx_BUF, Asc1_Tx_lengh );
		Asc1_Tx_lengh += 2;
		//发送缓冲区数据
		Send_Asc0_Tx_buf();
	}
	else
	{
		//计算发送缓冲区
		crc_cal( Asc1_Tx_BUF, Asc1_Tx_lengh );
		Asc1_Tx_lengh += 2;
		//发送缓冲区数据
		Send_Asc0_Tx_buf();
	}
}


//****************************************************************************
// @Function  	  void Deal_WRITE_One_Coilr()
// @Description       写单个线圈
//****************************************************************************
__inline void Deal_WRITE_One_Coilr()
{
	bit	Deal_all_OK	= 0;
	ubyte	temp1, temp2, temp5;
	uword	temp3, temp4;
	//判定功能码是否合法(05,但是帧长超出8个字节)
	if (Asc1_Rx_lengh != 8)
	{
		Asc1_Tx_BUF[1] = 0x85;
		Asc1_Tx_BUF[2] = 0x01;
		Asc1_Tx_lengh = 3;
	}
	else
	{
		//判定寄存器值是否合法(0 ---0xFFFF)
		temp3 = ( uword ) Asc1_Rx_BUF[4] * 256 + Asc1_Rx_BUF[5];
		if (temp3 != 0xFF00 && temp3 != 0x0000)
		{
			Asc1_Tx_BUF[1] = 0x85;
			Asc1_Tx_BUF[2] = 0x03;
			Asc1_Tx_lengh = 3;
		}
		else
		{
			//判定寄存器地址是否合法
			temp4 = ( uword ) Asc1_Rx_BUF[2] * 256 + Asc1_Rx_BUF[3];
			if (temp4 >= ModBus_PLC_Bit_max)						//---------------------------------
			{
				Asc1_Tx_BUF[1] = 0x85;
				Asc1_Tx_BUF[2] = 0x02;
				Asc1_Tx_lengh = 3;
			}
			else
			{
				//处理写请求
				temp2 = Asc1_Rx_BUF[3] / 8;		//数组的第几个字节
				temp1 = ( ubyte ) ( Asc1_Rx_BUF[3] % 8 );	//对应字节的第几位
				temp5 = ( 0x01 ) << ( temp1 );
				if (temp3 == 0xFF00)
				{
					PLC_Bit_Buffer_all.PLC_Bit_Buffer[temp2] += temp5;
				}
				else
				{
					temp5 = ~temp5;
					PLC_Bit_Buffer_all.PLC_Bit_Buffer[temp2] &= temp5;
				}					
				Deal_all_OK = 1;
				//写取离散输出是否正常
				if (Deal_all_OK == 0)
				{
					Asc1_Tx_BUF[1] = 0x85;
					Asc1_Tx_BUF[2] = 0x04;
					Asc1_Tx_lengh = 3;
				}
			}
		}
	}
	if (Deal_all_OK == 1)
	{
		Deal_all_OK = 0;
		Send_Asc0_Rx_buf_Back();
	}
	else
	{
		//计算发送缓冲区
		crc_cal( Asc1_Tx_BUF, Asc1_Tx_lengh );
		Asc1_Tx_lengh += 2;
		//发送缓冲区数据
		Send_Asc0_Tx_buf();
	}
}

//****************************************************************************
// @Function  	  void Deal_WRITE_One_Register()
// @Description       写一个保持寄存器
//****************************************************************************
__inline void Deal_WRITE_One_Register()
{
	bit	Deal_all_OK	= 0;
	//ubyte temp1,temp2;
	uword	temp3, temp4;
	//判定功能码是否合法(06,但是帧长超出8个字节)
	//测试数组01 06 00 01 00 50 00 36 5A
	if (Asc1_Rx_lengh != 8)
	{
		Asc1_Tx_BUF[1] = 0x86;
		Asc1_Tx_BUF[2] = 0x01;
		Asc1_Tx_lengh = 3;
	}
	else
	{
		//判定寄存器值是否合法(0 ---0xFFFF)
		//测试数组
		temp3 = ( uword ) Asc1_Rx_BUF[2] * 256 + Asc1_Rx_BUF[3];
		if (temp3 > ModBus_PLC_Word_max)
		{
			Asc1_Tx_BUF[1] = 0x86;
			Asc1_Tx_BUF[2] = 0x03;
			Asc1_Tx_lengh = 3;
		}
		else
		{
			//判定寄存器地址是否合法
			//测试数组01 06 01 01 00 50 D9 CA
			temp4 = temp3;
			if (temp4 > ModBus_PLC_Word_max)						//-------
			{
				Asc1_Tx_BUF[1] = 0x86;
				Asc1_Tx_BUF[2] = 0x02;
				Asc1_Tx_lengh = 3;
			}
			else
			{
				//处理写请求
				temp3 = temp3 * 2;
				PLC_Word_Buffer.U_W_B_A.word_int[temp3] = Asc1_Rx_BUF[5];
				temp3++;
				PLC_Word_Buffer.U_W_B_A.word_int[temp3] = Asc1_Rx_BUF[4];
				Deal_all_OK = 1;
			}
		}
	}
	if (Deal_all_OK == 1)
	{
		Deal_all_OK = 0;
		Send_Asc0_Rx_buf_Back();
	}
	else
	{
		//计算发送缓冲区
		crc_cal( Asc1_Tx_BUF, Asc1_Tx_lengh );
		Asc1_Tx_lengh += 2;
		//发送缓冲区数据
		Send_Asc0_Tx_buf();
	}
}

//****************************************************************************
// @Function  	  void Deal_READ_Hold_Registers()
// @Description       读保持寄存器
//     			01 03 00 0A 00 01 A4 08
//     			01 03 00 0E 00 04 25 CA
//****************************************************************************
__inline void Deal_READ_Hold_Registers()
{
	bit	Deal_all_OK	= 0;
	ubyte	temp1, temp2;
	uword	temp3, temp4;
	//PLC_Word_Buffer.U_W_B_A.uword_value[13]++;
	//PLC_Word_Buffer.U_W_B_A.uword_value[14]++;
	//PLC_Word_Buffer.U_W_B_A.uword_value[15]++;
	//判定功能码是否合法(03,但是帧长超出8个字节)
	if (Asc1_Rx_lengh != 8)
	{
		Asc1_Tx_BUF[1] = 0x83;
		Asc1_Tx_BUF[2] = 0x01;
		Asc1_Tx_lengh = 3;
	}
	else
	{
		//判定读取首地址是否合法
		if (Asc1_Rx_BUF[2] > 0 || Asc1_Rx_BUF[3] > ModBus_PLC_Word_max)
		{
			Asc1_Tx_BUF[1] = 0x83;
			Asc1_Tx_BUF[2] = 0x03;
			Asc1_Tx_lengh = 3;
		}
		else
		{
			//判定读取末地址是否合法
			temp3 = ( uword ) Asc1_Rx_BUF[4] * 256 + Asc1_Rx_BUF[5];
			temp4 = temp3 + Asc1_Rx_BUF[3];
			if (temp4 > ModBus_PLC_Word_max || Asc1_Rx_BUF[4] > 0)
			{
				Asc1_Tx_BUF[1] = 0x83;
				Asc1_Tx_BUF[2] = 0x02;
				Asc1_Tx_lengh = 3;
			}
			else
			{
				//处理读请求
				Asc1_Tx_BUF[0] = 0x01;
				Asc1_Tx_BUF[1] = 0x03;
				temp1 = ( ubyte ) ( Asc1_Rx_BUF[5] * 2 );
				Asc1_Tx_BUF[2] = temp1;

				temp3 = Asc1_Rx_BUF[3] * 2;
				//temp4 = temp1+3;	
				Asc1_Tx_lengh = temp1 + 3;					
				Asc1_Tx_BUF_point = &( Asc1_Tx_BUF[3] );
				for (temp2 = temp1 / 2; temp2 > 0; temp2--)
				{
					Asc1_Tx_BUF_point++;
					*Asc1_Tx_BUF_point = PLC_Word_Buffer.U_W_B_A.word_int[temp3++];
					Asc1_Tx_BUF_point--;
					*Asc1_Tx_BUF_point = PLC_Word_Buffer.U_W_B_A.word_int[temp3--];
					temp3 += 2;
					Asc1_Tx_BUF_point += 2;
				}
				Deal_all_OK = 1;
			}
		}
	}
	if (Deal_all_OK == 1)
	{
		Deal_all_OK = 0;
		//计算发送缓冲区
		//Asc1_Tx_lengh =  (ubyte)(temp4);
		crc_cal( Asc1_Tx_BUF, Asc1_Tx_lengh );
		Asc1_Tx_lengh += 2;
		//发送缓冲区数据
		Send_Asc0_Tx_buf();
	}
	else
	{
		Deal_all_OK = 0;
		//计算发送缓冲区
		crc_cal( Asc1_Tx_BUF, Asc1_Tx_lengh );
		Asc1_Tx_lengh += 2;
		//发送缓冲区数据
		Send_Asc0_Tx_buf();
	}
}

//****************************************************************************
// @Function  	  void Deal_WRITE_Some_Coil()
// @Description      强制多个线圈
//     			
//     			
//****************************************************************************
__inline void Deal_WRITE_Some_Coil()
{
}

//****************************************************************************
// @Function  	  void Deal_WRITE_Some_Register()
// @Description      预置多寄存器  			
//****************************************************************************
__inline void Deal_WRITE_Some_Register()
{
	bit	Deal_all_OK	= 0;
	ubyte	temp1, temp2;//,temp5;
	uword	temp3, temp4;
	//判定功能码是否合法(16,但是帧长超出8个字节)
	//包长=  Node + FunCode + StarAdd + RegNum + Hbyte + Infmation + LCR
	//           =   1     +      1       +      2      +      2      +  1	+     N	  +   2
	//           =   N+9
	temp1 = Asc1_Rx_BUF[6] + 9;	
	if (Asc1_Rx_lengh != temp1)
	{
		Asc1_Tx_BUF[1] = 0x90;
		Asc1_Tx_BUF[2] = 0x01;
		Asc1_Tx_lengh = 3;
	}
	else
	{
		//判定寄存器起始地址是否正确
		temp3 = ( uword ) Asc1_Rx_BUF[2] * 256 + Asc1_Rx_BUF[3];
		if (temp3 > ModBus_PLC_Word_max)
		{
			Asc1_Tx_BUF[1] = 0x90;
			Asc1_Tx_BUF[2] = 0x03;
			Asc1_Tx_lengh = 3;
		}
		else
		{
			//判定最后一个寄存器地址是否正确
			temp4 = ( uword ) Asc1_Rx_BUF[4] * 256 + Asc1_Rx_BUF[5];
			//temp5 = (ubyte)(temp4 - temp3)+1;
			//temp5 *= 2;
			temp4 = Asc1_Rx_BUF[3] + Asc1_Rx_BUF[5] - 1;
			if (temp4 > ModBus_PLC_Word_max)
			{
				Asc1_Tx_BUF[1] = 0x90;
				Asc1_Tx_BUF[2] = 0x02;
				Asc1_Tx_lengh = 3;
			}
			else
			{
				//处理写请求					
				temp3 = Asc1_Rx_BUF[3] * 2;		//确定开始字节数组号
				temp2 = 8;						//接受信息字节号

				for (; temp4 > 0; temp4--)
				{
					//写字的低字节
					PLC_Word_Buffer.U_W_B_A.word_int[temp3] = Asc1_Rx_BUF[temp2];
					temp3++;
					temp2--;
					//写字的高字节
					PLC_Word_Buffer.U_W_B_A.word_int[temp3] = Asc1_Rx_BUF[temp2];
					temp2 += 3;
					temp3++;
				}
				Deal_all_OK = 1;
			}
		}
	}
	if (Deal_all_OK == 1)
	{
		Deal_all_OK = 0;
		for (temp1 = 0; temp1 < 6; temp1++)
		{
			Asc1_Tx_BUF[temp1] = Asc1_Rx_BUF[temp1];
		}
		Asc1_Tx_lengh = 6;
		crc_cal( Asc1_Tx_BUF, Asc1_Tx_lengh );
		Asc1_Tx_lengh += 2;
		//发送缓冲区数据
		Send_Asc0_Tx_buf();
	}
	else
	{
		//计算发送缓冲区
		crc_cal( Asc1_Tx_BUF, Asc1_Tx_lengh );
		Asc1_Tx_lengh += 2;
		//发送缓冲区数据
		Send_Asc0_Tx_buf();
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -