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

📄 modbus16.c

📁 sci_loopback_interrupts(Modbus),基于TMS320F2812 DSP芯片的Modbus串口通讯程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		Cputime_Start=0;
		//软件复位SCI
		SciaRegs.SCICTL1.bit.SWRESET=0;
	    SciaRegs.SCICTL1.bit.SLEEP=1;
	    SciaRegs.SCICTL1.bit.SWRESET=1;
				
		SciaRegs.SCIFFTX.bit.SCIRST = 0;
		SciaRegs.SCIFFTX.bit.SCIRST = 1; //SCI FIFO resume transmit or receive.

		ResolveModbus();
	}
}

Uint16 Crc16(Uint16 *puchMsg, Uint16 usDataLen) 
{ 
	Uint16 uchCRCHi = 0xFF ;              /* 高CRC字节初始化  */ 
	Uint16 uchCRCLo = 0xFF ;              /* 低CRC 字节初始化 */ 
	Uint32 uIndex ;                      /* CRC循环中的索引  */ 
	while (usDataLen--)                  /* 传输消息缓冲区   */ 
	{ 
		uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC          */ 
		uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ; 
		uchCRCLo = auchCRCLo[uIndex] ; 
	} 
	return (uchCRCHi << 8 | uchCRCLo) ; 
}

//接收数据从机地址检查
Uint16 AddrCheck(Uint16 AddrStart,Uint16 Num,Uint16 AddrMax)
{
	Uint16 Result=0;

	//错误2:查询中的数据地址对于从机来说是非法的	
	if(AddrStart<0 || Num<=0 || AddrStart+Num>AddrMax)
	{
		ModbusExcep(RdataA[1],ILLEGAL_DATA_ADDRESS);
		SciaTx_Response();
		Result=1;
	}

	return Result;
}


//读线圈状态01H
void ReadCoil(void)
{
	Uint16 AddrStart=0;			    //起始地址
	Uint16 TempAddr=0;        
	Uint16 CoilCount=0;         //线圈数目
	Uint16  ByteCount=0;         //读取数据区字节个数
	Uint16 CRCCheck=0;          //CRC校验码
	Uint16 TempData=0;
	Uint16  i=0,k=0;	

	
	AddrStart = (RdataA[2]<<8) + RdataA[3];
	CoilCount = (RdataA[4]<<8) + RdataA[5];	
	ByteCount = CoilCount/8;				
	if(CoilCount%8 != 0)       //不足8位的,当作一个字节
		ByteCount+=1;

	if(AddrCheck(AddrStart,CoilCount,MaxQ))
	{//有错误
		return;
	}
	
	TempAddr=AddrStart;								
	for(k=0;k<ByteCount;k++)
	{
		SdataA[k + 3] = 0;

		for(i=0;i<8;i++)
		{
			GetCoilVal(TempAddr,&TempData);

			SdataA[k + 3] |= TempData << i;
			TempAddr++;

			if(TempAddr >= AddrStart+CoilCount)
			{	//读完
				goto Label;
			}	
		}
	}

Label:	
	SdataA[0] = Local;
	SdataA[1] = RdataA[1];	
	SdataA[2] = ByteCount;

	CRCCheck = Crc16(SdataA,ByteCount+3);	
	SdataA[ByteCount+3] = CRCCheck >> 8;
	SdataA[ByteCount+4] = CRCCheck & 0xff;

	SdataA_Num = ByteCount+5;
	
	SciaTx_Response();		
}


//读输入状态02H
void ReadInputState(void)
{
	Uint16 AddrStart=0;				  //起始地址
	Uint16 TempAddr=0;
	Uint16 InputCount=0;			  //读取数字输入量个数
	Uint16  ByteCount=0;             //读取数据区字节个数
	Uint16 CRCCheck=0;              //CRC校验码
	Uint16 TempData=0;
	Uint16  i=0,k=0;	
	
	AddrStart = (RdataA[2]<<8) + RdataA[3];	    
	TempAddr=AddrStart;
	InputCount = (RdataA[4]<<8) + RdataA[5];
	ByteCount = InputCount / 8;			
	if(InputCount%8 != 0)
		ByteCount+=1;
						
	if(AddrCheck(AddrStart,InputCount,MaxI))
	{//有错误
		return;
	}
				
	for(k=0;k<ByteCount;k++)
	{
		SdataA[k + 3] = 0;

		for(i=0;i<8;i++)
		{
			GetInputVal(TempAddr,&TempData);
			
			SdataA[k + 3] |= TempData << i;
			TempAddr++;

			if(TempAddr >= AddrStart+InputCount)
			{	//读完
				goto Label;
			}	
		}
	}

Label:	
	SdataA[0] = Local;
	SdataA[1] = RdataA[1];	
	SdataA[2] = ByteCount;

	CRCCheck = Crc16(SdataA,ByteCount+3);	
	SdataA[ByteCount+3] = CRCCheck >> 8;
	SdataA[ByteCount+4] = CRCCheck & 0xff;

	SdataA_Num = ByteCount+5;	
	
	SciaTx_Response();	
}


//读保持寄存器03H
void ReadHoldRegisters(void)
{
	Uint16 AddrStart=0;			               //4X寄存器起始地址
	Uint16 TempAddr=0;
	Uint16 CRCCheck=0;
	Uint16  RegistersCount=0;				   //要读寄存器的个数
	Uint16  ByteCount=0;					   //字节计?
	Uint16 TempData=0;
	Uint16 i=0;		
	
	AddrStart = (RdataA[2]<<8) + RdataA[3];   
	TempAddr=AddrStart; 	        
	RegistersCount = (RdataA[4]<<8) + RdataA[5];	
	ByteCount = RegistersCount * 2;                 
	
	if(AddrCheck(AddrStart,RegistersCount,MaxHold))
	{//有错误
		return;
	}

	for(i=0;i<ByteCount;i+=2,TempAddr++)
	{
		GetRegisterVal(TempAddr,&TempData);				
		SdataA[i+3] = TempData >> 8;				   		
		SdataA[i+4] = TempData & 0xff;			
	}

	
	SdataA[0] = Local;
	SdataA[1] = RdataA[1];
	SdataA[2] = ByteCount;
	CRCCheck = Crc16(SdataA,ByteCount+3);
	SdataA[ByteCount+3] = CRCCheck >> 8;
	SdataA[ByteCount+4] = CRCCheck & 0xff;	
	SdataA_Num = ByteCount + 5;

	SciaTx_Response();
}//void readRegisters(void)


//读输入寄存器04H
void ReadInputRegisters(void)
{
	Uint16 AddrStart=0;			               //寄存器起始地址
	Uint16 TempAddr=0;
	Uint16 CRCCheck=0;
	Uint16  RegistersCount=0;				   //要读寄存器的个数
	Uint16  ByteCount=0;					   //字节计数	
	Uint16 TempData = 0;
	Uint16 i=0;
			
	AddrStart = (RdataA[2]<<8) + RdataA[3];   
	TempAddr=AddrStart;  	          
	RegistersCount = (RdataA[4]<<8) + RdataA[5];
	ByteCount = RegistersCount * 2;                 
	
	if(AddrCheck(AddrStart,RegistersCount,MaxAI))
	{//有错误
		return;
	}

	for(i=0;i<ByteCount;i+=2,TempAddr++)
	{
		GetInputRegisterVal(TempAddr,&TempData);				
		SdataA[i+3] = TempData >> 8;				   		
		SdataA[i+4] = TempData & 0xff;			
	}

	
	SdataA[0] = Local;
	SdataA[1] = RdataA[1];
	SdataA[2] = ByteCount;
	CRCCheck = Crc16(SdataA,ByteCount+3);
	SdataA[ByteCount+3] = CRCCheck >> 8;
	SdataA[ByteCount+4] = CRCCheck & 0xff;	
	SdataA_Num = ByteCount + 5;

	SciaTx_Response();
}


//强制单个线圈
void ForceSingleCoil(void)
{
	Uint16  AddrStart=0;
	Uint16  TempAddr=0;
	Uint16  TempData=0;
	Uint16  SetData=0;
	Uint16   i=0;
	
	AddrStart = (RdataA[2]<<8) + RdataA[3];	
	TempAddr = AddrStart;
	SetData = (RdataA[4]<<8) + RdataA[5];	

	if(AddrCheck(AddrStart,1,MaxQ))
	{//有错误
		return;
	}

/////////////////////////////
//这里不同的上位机可能不同,要测试一下该功能?
/////////////////////////////
	if(SetData == 0xFF00)
	{	//设为ON
		TempData = 1;
	} 
	else if(SetData == 0x0000)
	{	//设为OFF
		TempData = 0;
	}

	SetCoilVal(TempAddr,TempData);	
	
	for(i=0;i<RdataA_Num;i++)
	{
		SdataA[i] = RdataA[i];
	}

	SdataA_Num = RdataA_Num;
	
	SciaTx_Response();
}


//设置单个保持寄存器
void PresetSingleRegister(void)
{
	Uint16  AddrStart=0;
	Uint16  TempAddr=0;
	Uint16  SetData=0;
	Uint16   i=0;
	
	AddrStart = (RdataA[2]<<8) + RdataA[3];
	TempAddr = AddrStart;
	SetData = (RdataA[4]<<8) + RdataA[5];

	if(AddrCheck(AddrStart,1,MaxHold))
	{//有错误
		return;
	}

	SetRegisterVal(TempAddr,SetData);			

	for(i=0;i<RdataA_Num;i++)
	{
		SdataA[i] = RdataA[i];
	}

	SdataA_Num = RdataA_Num;
	
	SciaTx_Response();
}


//设置多个线圈
void ForceMultipleCoils(void)
{
	Uint16     AddrStart=0;
	Uint16     TempAddr=0;
	Uint16      ByteCount=0;
	Uint16      SetCount=0;
	Uint16     CRCCheck=0;
	unsigned   TempState=0;
	Uint16      i=0,k=0;
	
	AddrStart = (RdataA[2]<<8) + RdataA[3];
	TempAddr = AddrStart;
	SetCount = (RdataA[4]<<8) + RdataA[5];
	ByteCount = RdataA[6];	
	
	if(AddrCheck(AddrStart,SetCount,MaxQ))
	{//有错误
		return;
	}

	for(k=0;k<ByteCount;k++)
	{
		for(i=0;i<8;i++)
		{
			TempState = (RdataA[k+7]>>i) & 0x01;
		    SetCoilVal(TempAddr,TempState);

			TempAddr++;

			if(TempAddr >= AddrStart+SetCount)
			{	//写完
				goto Lable1;
			}
		}
	}

Lable1:
	SdataA[0] = Local;
	SdataA[1] = RdataA[1];
	SdataA[2] = AddrStart >> 8;
	SdataA[3] = AddrStart & 0xff;
	SdataA[4] = SetCount >> 8;
	SdataA[5] = SetCount & 0xff;
	CRCCheck  = Crc16(SdataA,6);
	SdataA[6] = CRCCheck >> 8;
	SdataA[7] = CRCCheck & 0xff;
	SdataA_Num = 8;
	
	SciaTx_Response();
}


//设置多个保持寄存器
void PresetMultipleRegisters(void)
{
	Uint16 AddrStart=0;
	Uint16 TempAddr=0;
	Uint16 ByteCount=0;
	Uint16 SetCount=0;
	Uint16 CRCCheck=0;
	Uint16 TempData=0;
	Uint16 i=0;
	
	AddrStart = (RdataA[2]<<8) + RdataA[3];
	TempAddr = AddrStart;
	SetCount = (RdataA[4]<<8) + RdataA[5];
	ByteCount = RdataA[6];	
	
	if(AddrCheck(AddrStart,SetCount,MaxHold))
	{//有错误
		return;
	}

	for(i=0;i<SetCount;i++,TempAddr++)
	{
		TempData = (RdataA[i*2+7]<<8) + RdataA[i*2+8];
	
		SetRegisterVal(TempAddr,TempData);			
	}
	
	SdataA[0] = Local;
	SdataA[1] = RdataA[1];
	SdataA[2] = AddrStart >> 8;
	SdataA[3] = AddrStart & 0xff;
	SdataA[4] = SetCount >> 8;
	SdataA[5] = SetCount & 0xff;
	CRCCheck  = Crc16(SdataA,6);
	SdataA[6] = CRCCheck >> 8;
	SdataA[7] = CRCCheck & 0xff;
	SdataA_Num = 8;
	
	SciaTx_Response();
}//void presetMultipleRegisters(void)


//掩码设置保持寄存器
void MaskWrite4XRegister(void)
{
	Uint16 AddrStart=0;
	Uint16  OrMark=0;
	Uint16  AndMark=0;
	Uint16 i=0;
	Uint16 TempData=0;

	
	AddrStart = (RdataA[2]<<8) + RdataA[3];
	AndMark = (RdataA[4]<<8) + RdataA[5];
	OrMark = (RdataA[6]<<8) + RdataA[7];
	
	if(AddrCheck(AddrStart,1,MaxHold))
	{//有错误
		return;
	}

	switch(AddrStart & 0x00ff)
	{
		case 0:
				TempData=nData4Test[0];//将寄存器的值赋给TempData
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[0]=TempData;//将新的TempData值赋给寄存器
				break;
		case 1:	
				TempData=nData4Test[1];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[1]=TempData;
				break;
		case 2:		
				TempData=nData4Test[2];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[2]=TempData;
				break;		
		case 3:
				TempData=nData4Test[3];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[3]=TempData;
				break;		
		case 4:
				TempData=nData4Test[4];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[4]=TempData;
				break;		
		case 5:
				TempData=nData4Test[5];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[5]=TempData;
				break;
		case 6:
				TempData=nData4Test[6];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[6]=TempData;
				break;			
		case 7:
				TempData=nData4Test[7];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[7]=TempData;
				break;		
		case 8:
				TempData=nData4Test[8];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[8]=TempData;
				break;		
		case 9:
				TempData=nData4Test[9];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[9]=TempData;
				break;	
		case 10:
				TempData=nData4Test[10];//将寄存器的值赋给TempData

				TempData=MarkCompute(TempData,AndMark,OrMark);

				nData4Test[10]=TempData;//将新的TempData值赋给寄存器
				break;
		case 11:	
				TempData=nData4Test[11];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[11]=TempData;
				break;
		case 12:		
				TempData=nData4Test[12];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[12]=TempData;
				break;		
		case 13:
				TempData=nData4Test[13];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[13]=TempData;
				break;		
		case 14:
				TempData=nData4Test[14];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[14]=TempData;
				break;		
		case 15:
				TempData=nData4Test[15];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[15]=TempData;
				break;
		case 16:
				TempData=nData4Test[16];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[16]=TempData;
				break;			
		case 17:
				TempData=nData4Test[17];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[17]=TempData;
				break;		
		case 18:
				TempData=nData4Test[18];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[18]=TempData;
				break;		
		case 19:
				TempData=nData4Test[19];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[19]=TempData;
				break;
		case 20:
				TempData=nData4Test[20];//将寄存器的值赋给TempData

				TempData=MarkCompute(TempData,AndMark,OrMark);

				nData4Test[20]=TempData;//将新的TempData值赋给寄存器
				break;
		case 21:	
				TempData=nData4Test[21];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[21]=TempData;
				break;
		case 22:		
				TempData=nData4Test[22];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[22]=TempData;
				break;		
		case 23:
				TempData=nData4Test[23];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[23]=TempData;
				break;		
		case 24:
				TempData=nData4Test[24];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[24]=TempData;
				break;		
		case 25:
				TempData=nData4Test[25];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[25]=TempData;
				break;
		case 26:
				TempData=nData4Test[26];
				TempData=MarkCompute(TempData,AndMark,OrMark);
				nData4Test[26]=TempData;
				break;			
		case 27:
				TempData=nData4Test[27];
				TempData=MarkCompute(TempData,AndMark,OrMark);

⌨️ 快捷键说明

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