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

📄 modbus.c

📁 modbus 通信协议在dsp2407中的应用代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    tmp[2] = start_address>>8;						//起始地址 高字节
    tmp[3] = start_address & 0xFF;					//起始地址 低字节
    tmp[4] = lenth>>8;								//读取数据量 高字节
    tmp[5] = lenth & 0xFF;							//读取数据量 低字节
           
    tmp_lenth = 6; 									//二进制包长度
  	
	ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);  	
	GwSciTxBytes = tmp_lenth+2;
	
	if(lenth % 8==0)
	{
		GwSciRxBytes=(lenth/8)+3+2; // lenth/8线圈状态的字节数,3为地址码,功能码,字节数,2为两个CRC字节
	}
	else
	{
		GwSciRxBytes=(lenth/8+1)+3+2;
	}
  	
  	SciSend();										//发送请求
  	
  	SciReceive();									//接收设备响应

  	//获取应答;对应答数据分析;对接收到的应答数据分析
     		             
    if(GwSciRxBuffer[1] == 0x02) //通信正常,数据处理
    {
        ProcessMasterRTU(pwInState,GwSciRxBuffer,0,GwSciRxBytes);
   	                   	
    }
    else //查询异常码,可重新发送请求或作其他处理
    {
	    return(CMD_ERR);
    }       
   
     
}




// 功能  :读取保持寄存器:CMD == 3 
// 返回  :成功返回1,否则返回0

// 请求命令:[设备地址] [命令号03] [起始寄存器地址高8位] [低8位] [读取的寄存器个数,高8位] [低8位] [CRC校验的高8位] [CRC校验的低8位] 
// 设备响应:[设备地址] [命令号03] [返回的字节个数][数据1][数据2]...[数据n][CRC校验的低高8位] [CRC校验的低8位]

char ReadHldreg(unsigned int *pwHldregState, unsigned char DeviceID, unsigned int start_address, unsigned int lenth) 
{
    unsigned char tmp[64], tmp_lenth,flag;    

    tmp[0] = DeviceID;							//从设备地址
    tmp[1] = 0x03;								//命令
    tmp[2]=start_address>>8;					//起始地址 高字节
    tmp[3]=start_address & 0xFF;				//起始地址 低字节
    tmp[4]=lenth>>8;							//读取寄存器个数 高字节
    tmp[5]=lenth & 0xFF;						//读取寄存器个数 低字节
    
    tmp_lenth = 6;
    
	ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);  	
	GwSciTxBytes = tmp_lenth+2;
	GwSciRxBytes=lenth*2+3+2;	//地址码,功能码,字节数共占3字节,CRC占2字节
  
  	SciSend();									//发送请求

	SciReceive();								//接收设备响应
	

	if(GwSciRxBuffer[1]==0x03)
   	  	ProcessMasterRTU(pwHldregState,GwSciRxBuffer,0,GwSciRxBytes);     	 
        
    else //通信异常0x83,查询异常码,可重新发送请求或作其他处理
    {
		return(CMD_ERR);
    }  

}

// 功能  :读取模拟量输入:CMD == 4 
// 返回  :成功返回1,否则返回0

// 请求命令:[设备地址] [命令号04] [起始寄存器地址高8位] [低8位] [读取的寄存器数高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]
// 设备响应:[设备地址] [命令号04] [返回的字节个数][数据1][数据2]...[数据n][CRC校验的低8位] [CRC校验的高8位]

char ReadAnlogIn(unsigned int *pwAnologInState, unsigned char DeviceID, unsigned int start_address, unsigned int lenth) 
{
    unsigned char tmp[64], tmp_lenth;

    tmp[0] = DeviceID;								//从设备地址
    tmp[1] = 0x04;  								//命令
    tmp[2] = start_address>>8;						//起始地址 高字节
    tmp[3] = start_address & 0xFF;					//起始地址 低字节
    tmp[4] = lenth>>8;								//读取数据量 高字节
    tmp[5] = lenth & 0xFF ;							//读取数据量 低字节 
    tmp_lenth = 6;
    
	ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);  	
	GwSciTxBytes = tmp_lenth+2;

	GwSciRxBytes = lenth*2+3+2;		//地址码,功能码,字节数占3字节,CRC占2字节
  	
  	SciSend();										//发送请求
  	
  	SciReceive();									//接收设备响应
  	//获取应答;对应答数据分析;对接收到的应答数据分析
        		             
    if(GwSciRxBuffer[1] == 0x04) 	//通信正常,数据处理
    {
    	 ProcessMasterRTU(pwAnologInState,GwSciRxBuffer,0,GwSciRxBytes);       	  	
    	                	
    }
    else //通信异常0x83,查询异常码,可重新发送请求或作其他处理
    {
	
		 return(CMD_ERR);
    }       
    
}

// 功能  :设置继电器:CMD == 5 
// 返回  :成功返回1,否则返回0

// 请求命令:[设备地址] [命令号05] [需下置的寄存器地址高8位] [低8位] [下置的数据高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]
// 设备响应:如果成功把计算机发送的命令原样返回,否则不响应
char SetCoil(unsigned char DeviceID, unsigned int start_address, unsigned int value)
{
    unsigned char tmp[64], tmp_lenth;
    
    tmp[0] = DeviceID;					//从设备地址
    tmp[1] = 0x05 ;						//命令  
    tmp[2] = start_address>>8;			//起始地址 高字节
    tmp[3] = start_address & 0xFF;		//起始地址 低字节
    tmp[4] = value>>8;					//待写数据 高字节
    tmp[5] = value & 0xFF;				//待写数据 低字节
    tmp_lenth = 6;
    
   
	ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);  	
	GwSciTxBytes = tmp_lenth+2;
	GwSciRxBytes = 6+2;
  	
  		
  	SciSend();							//发送请求
  	
  	SciReceive();						//接收设备响应
  	
  	if(GwSciRxBuffer[1] == 0x05) 		//通信正常,数据处理
    {
    	  if(CheckCRC(GwSciRxBuffer,GwSciRxBytes))
    	  {
  	  			if(GwSciRxBuffer[2]!=GwSciTxBuffer[2]) return(0);
  	  			if(GwSciRxBuffer[3]!=GwSciTxBuffer[3]) return(0);
  	  			if(GwSciRxBuffer[4]!=GwSciTxBuffer[4]) return(0);
  	  			if(GwSciRxBuffer[5]!=GwSciTxBuffer[5]) return(0);	
  	  			return(1);
    	  } 
    	  else  	//CRC校验不一致;可重新发送请求或作其他处理
    	  {
    	  		
    	  		return(CRC_ERR);
    	  }                    	
    }
    
    else 			//通信异常0x83,查询异常码,可重新发送请求或作其他处理
    {
				
		return(CMD_ERR);
    }       
    
}

// 功能  :设置单保持寄存器 CMD == 6 
// 返回  :成功返回1,否则返回0

// 请求命令:[设备地址] [命令号06] [需下置的寄存器地址高8位] [低8位] [下置的数据高8位] [低8位] [CRC校验的低8位] [CRC校验的高8位]
// 设备响应:如果成功把计算机发送的命令原样返回,否则不响应

char SetHldreg(unsigned char DeviceID, unsigned int start_address, unsigned int value)
{
    unsigned char tmp[64], tmp_lenth;
    
    tmp[0] = DeviceID; 							//地址
    tmp[1] = 0x06;								//命令
    tmp[2] = start_address>>8;					//写数据的起始地址 高字节
    tmp[3] = start_address & 0xFF;				//写数据的起始地址 低字节
    tmp[4] = value>>8;							//待写数据 高字节
    tmp[5] = value & 0xFF;						//待写数据 低字节
    tmp_lenth = 6;								//有效数据长度
    
	ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);  	
	GwSciTxBytes = tmp_lenth+2;

	GwSciRxBytes = 6+2;
  	
  		
	SciSend();									//发送请求
  	
  	SciReceive();								//接收设备响应

  	//获取应答;对应答数据分析;对接收到的应答数据分析
        		             
    if(GwSciRxBuffer[1] == 0x06) 				//通信正常,数据处理
    {
    	  if(CheckCRC(GwSciRxBuffer,GwSciRxBytes))
    	  {
  	  			if(GwSciRxBuffer[2]!=GwSciTxBuffer[2]) return(0);
  	  			if(GwSciRxBuffer[3]!=GwSciTxBuffer[3]) return(0);
  	  			if(GwSciRxBuffer[4]!=GwSciTxBuffer[4]) return(0);
  	  			if(GwSciRxBuffer[5]!=GwSciTxBuffer[5]) return(0);	
  	  			return(1);
    	  } 
    	  else  	//CRC校验不一致;可重新发送请求或作其他处理
    	  {
    	  		
    	  		return(CRC_ERR);
    	  }                    	
    }
    else 			//通信异常0x83,查询异常码,可重新发送请求或作其他处理
    {
					
		 return(CMD_ERR);
    }       
     
}

// 功能  :对多个线圈进行强制:CMD == 15 
// 返回  :成功返回1,否则返回0

// 请求格式:从站地址 0x0F 第一个位首地址 所写位数 值占用的字节数 值
//         (例如,置从站5的位12至17为1,则:05 0F 000C 0006 01 3F CRC)

char SetCoils(unsigned char DeviceID, unsigned int Startbit_Add, unsigned int Bit2Write, unsigned char ByteValue, unsigned char *Values)
{
    unsigned char tmp[64], tmp_lenth,i;
    
    tmp[0] = DeviceID;
    tmp[1] = 0x0f ;  
    tmp[2] = Startbit_Add>>8;
    tmp[3] = Startbit_Add & 0xFF;
    tmp[4] = Bit2Write>>8;
    tmp[5] = Bit2Write & 0xFF;
    tmp[6] = ByteValue;
    for(i=0;i<ByteValue;i++)
   		 tmp[7+i] = Values[i];

    tmp_lenth = 7+ByteValue;
    
    
	ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);  	
	GwSciTxBytes = tmp_lenth+2;

	GwSciRxBytes = 6+2;
  		
  	SciSend();							//发送CMD请求
  	
  	SciReceive();						//接收设备响应	
  	//获取应答;对应答数据分析;对接收到的应答数据分析
       		             
    if(GwSciRxBuffer[1] == 0x0F) 		//通信正常,数据处理
    {
    	  if(CheckCRC(GwSciRxBuffer,GwSciRxBytes))
    	  {
  	  			if(GwSciRxBuffer[2]!=GwSciTxBuffer[2]) return(0);
  	  			if(GwSciRxBuffer[3]!=GwSciTxBuffer[3]) return(0);
  	  			if(GwSciRxBuffer[4]!=GwSciTxBuffer[4]) return(0);
  	  			if(GwSciRxBuffer[5]!=GwSciTxBuffer[5]) return(0);	
  	  			return(1);
    	  } 
    	  else  	//CRC校验不一致;可重新发送请求或作其他处理
    	  {
    	  		
    	  		return(CRC_ERR);
    	  }                    	
    }
    else 			//通信异常0x83,查询异常码,可重新发送请求或作其他处理
    {
					
		return(CMD_ERR);
    }       
    
}

char SetMultiHldreg(unsigned char DeviceID, unsigned int start_address, unsigned int WNum, unsigned char BNum, unsigned int *values)
{
    unsigned char tmp[256], tmp_lenth;
    unsigned char i=0;
    unsigned int j;
    
    tmp[0] = DeviceID; 					//地址
    tmp[1] = 0x10;      				//命令
    tmp[2] = start_address>>8;			//写数据的起始地址 高字节
    tmp[3] = start_address & 0xFF;		//写数据的起始地址 低字节
    tmp[4] = WNum>>8; 					//待写寄存器数量
    tmp[5] = WNum & 0xFF; 				//待写寄存器数量
    tmp[6] = BNum;        				//待写数据的字节数
    for(j=0;j<WNum;j++)      			//填充数据
    {    		
    		tmp[i+7] = values[j]>>8;	//待写数据 高字节    
    		tmp[i+8] = values[j] & 0xFF;//待写数据 低字节  
    		i=i+2;     		
    }
    
    tmp_lenth = 7+i;	//有效数据长度
    
    
	ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);  	
	GwSciTxBytes = tmp_lenth+2;

	GwSciRxBytes = 6+2;
  
  		
  	SciSend();				//发送CMD请求
  	
  	SciReceive();			//接收设备响应
  	//获取应答;对应答数据分析;对接收到的应答数据分析
      		             
    if(GwSciRxBuffer[1] == 0x0F) 	//通信正常,数据处理
    {
    	  if(CheckCRC(GwSciRxBuffer,GwSciRxBytes))
    	  {
  	  			if(GwSciRxBuffer[2]!=GwSciTxBuffer[2]) return(0);
  	  			if(GwSciRxBuffer[3]!=GwSciTxBuffer[3]) return(0);
  	  			if(GwSciRxBuffer[4]!=GwSciTxBuffer[4]) return(0);
  	  			if(GwSciRxBuffer[5]!=GwSciTxBuffer[5]) return(0);	
  	  			return(1);
    	  } 
    	  else  	//CRC校验不一致;可重新发送请求或作其他处理
    	  {
    	  		
    	  		return(CRC_ERR);
    	  }                    	
    }
    else 			//通信异常0x83,查询异常码,可重新发送请求或作其他处理
    {
					
		return(CMD_ERR);
    }       
   
}


void interrupt SCI_INT()
{

	switch(PIVR)
	{
		case 0x0006:
		{		
			//置SCI接收中断标志
			GwSciRxFlag = 1;
			
			//todo:把接收数据放在中断服务程序中
			//GwSciRxBuffer[GwRxCount] = SCIRXBUF;			
    		//todo:通过读SCIRXBUF就可以清除SCIRXST的RXRDY位,下面的判断是否可去掉
    		//while((SCIRXST & 0x40)!=0);	//查看SCIRXST的RXRDY位,判断SCIRXBUF中的数据是否读完    		
			//GwRxCount++;
			
			break;
		}
		 
		default: 
			break;		
	}
	
	//todo:当一个中断被响应时,系统会自动清除IFR中相应的标志位,下面的清除是否必要
	//IFR = 0x0001;         	//清IFR相应中断标志
	Enable();					//开总中断
	//return;					//返回
}

⌨️ 快捷键说明

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