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

📄 modbus.c

📁 本程序是一个人机接口程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		case 16:*tempData =0;
				break;														
		default:*tempData =0;
				break;		
	}
	return result;
}

//设置寄存器值 返回0表示成功
unsigned int setRegisterVal(unsigned int addr,unsigned int tempData)
{
	unsigned int result = 0;
	unsigned int tempAddr;
	
	tempAddr = addr & 0xfff;
	
	switch(tempAddr & 0xff)
	{
		case 0:	Current_Set_value=tempData;
				Show_Preset();
				Preset(0);  //软给定
				break;
		case 1:	Voltage_Set_value=tempData;
				Show_Preset();
				Preset(0);  //软给定
				break;
		case 2:		
				break;		
		case 3:
				break;		
		case 4:
				break;		
		case 5:
				break;
		case 6:
				break;			
		case 7:
				break;		
		case 8:
				break;		
		case 9:
				break;		
		case 10:
				break;
		case 11:
				break;
		case 12:
				break;
		case 13:
				break;
		case 14:
				break;
		case 15:
				break;
		case 16:
				break;														
		default:
				break;		
	}
	return result;
}

//设置单个寄存器
void presetSingleRegister(void)
{
	unsigned char addr;
	unsigned char tempAddr;
	unsigned int tempData;
    unsigned char i;
	
	//addr = (receBuf[2]<<8) + receBuf[3];
	//tempAddr = addr & 0xfff;
	addr = receBuf[3];
	tempAddr = addr & 0xff;

	tempData = (receBuf[4]<<8) + receBuf[5];
	setRegisterVal(tempAddr,tempData);			
	
	for(i=0;i<receCount;i++)
	{
		sendBuf[i] = receBuf[i];
	}
	sendCount = receCount;
	beginSend();
}

//设置多个寄存器
void presetMultipleRegisters(void)
{
	unsigned char addr;
	unsigned char tempAddr;
	unsigned char byteCount;
	unsigned char setCount;
	unsigned int crcData;
	unsigned int tempData;
//	unsigned char  finsh;	//为1时完成 为0时出错
	unsigned char i;
	
	//addr = (receBuf[2]<<8) + receBuf[3];
	//tempAddr = addr & 0xfff;
	addr = receBuf[3];
	tempAddr = addr & 0xff;

	//setCount = (receBuf[4]<<8) + receBuf[5];
	setCount = receBuf[5];
	byteCount = receBuf[6];	
	
	for(i=0;i<setCount;i++,tempAddr++)
	{
		tempData = (receBuf[i*2+7]<<8) + receBuf[i*2+8];
	
		setRegisterVal(tempAddr,tempData);			
	}
	
	sendBuf[0] = Local_Address;
	sendBuf[1] = 16;
	sendBuf[2] = addr >> 8;
	sendBuf[3] = addr & 0xff;
	sendBuf[4] = setCount >> 8;
	sendBuf[5] = setCount & 0xff;
	crcData = crc16(sendBuf,6);
	sendBuf[6] = crcData >> 8;
	sendBuf[7] = crcData & 0xff;
	sendCount = 8;
	beginSend();	
}

//读寄存器
void readRegisters(void)
{
	unsigned char addr;
	unsigned char tempAddr;
//	unsigned int result;
	unsigned int crcData;
	unsigned char readCount;
	unsigned char byteCount;
//	unsigned char  finsh;	//1完成  0出错
	unsigned int i;
	unsigned int tempData = 0;	
	
	//addr = (receBuf[2]<<8) + receBuf[3];
	//tempAddr = addr & 0xfff;	
	addr = receBuf[3];
	tempAddr = addr;

	//readCount = (receBuf[4]<<8) + receBuf[5];	//要读的个数
	readCount = receBuf[5];

	byteCount = readCount * 2;
	
	for(i=0;i<byteCount;i+=2,tempAddr++)
	{
		getRegisterVal(tempAddr,&tempData);				
		sendBuf[i+3] = tempData >> 8;				   		
		sendBuf[i+4] = tempData & 0xff;			
	}
	
	sendBuf[0] = Local_Address;
	sendBuf[1] = 3;
	sendBuf[2] = byteCount;
	byteCount += 3;
	crcData = crc16(sendBuf,byteCount);
	sendBuf[byteCount] = crcData >> 8;
	byteCount++;
	sendBuf[byteCount] = crcData & 0xff;
	
	sendCount = byteCount + 1;
	beginSend();
}


//强制单个线圈
void forceSingleCoil(void)
{
	unsigned char addr;
	unsigned char tempAddr;
	unsigned int tempData;
	unsigned char  onOff;
	unsigned char i;
	
	//addr = (receBuf[2]<<8) + receBuf[3];	
	//tempAddr = addr & 0xfff;
	addr = receBuf[3];
	tempAddr = addr;

	//onOff = (receBuf[4]<<8) + receBuf[5];	
	onOff = receBuf[5];
	
	//if(onOff == 0x0000)
	if(onOff == 0x00)	//设为OFF
	{	
		tempData = 0;
	} 
	//else if(onOff == 0xff00)
	else //if(onOff == 0xff) //设为ON
	{	
		tempData = 1;
	}

	setCoilVal(tempAddr,tempData);	
	
	for(i=0;i<receCount;i++)
	{
		sendBuf[i] = receBuf[i];
	}
	sendCount = receCount;
	beginSend();	
}

//读线圈状态
void readCoil(void)
{
	unsigned char addr;
	unsigned char tempAddr;
	unsigned char byteCount;
	unsigned char bitCount;
	unsigned int  crcData;
	unsigned char position;
	unsigned char i,k;
//	unsigned char  result;
	unsigned int  tempData;
	unsigned char  exit = 0;
	
	//addr = (receBuf[2]<<8) + receBuf[3];	
	//tempAddr = addr & 0xfff;
	addr = receBuf[3];
	tempAddr = addr;

	//bitCount = (receBuf[4]<<8) + receBuf[5];	//读取的位个数
	bitCount = receBuf[5];

	byteCount = bitCount / 8;					//字节个数
	if(bitCount%8 != 0)
		byteCount++;
									
	for(k=0;k<byteCount;k++)
	{//字节位置
		position = k + 3;
		sendBuf[position] = 0;
		for(i=0;i<8;i++)
		{
			getCoilVal(tempAddr,&tempData);
			
			sendBuf[position] |= tempData << i;
			tempAddr++;
			if(tempAddr >= addr+bitCount)
			{	//读完
				exit = 1;
				break;
			}	
		}
		if(exit == 1)
			break;
	}
	
	sendBuf[0] = Local_Address;
	sendBuf[1] = 0x01;	
	sendBuf[2] = byteCount;
	byteCount += 3;
	crcData = crc16(sendBuf,byteCount);	
	sendBuf[byteCount] = crcData >> 8;
	byteCount++;
	sendBuf[byteCount] = crcData & 0xff;
	sendCount = byteCount + 1;
	
	beginSend();	
}

//检查uart0数据
void checkComm0Modbus(void)
{
	unsigned int crcData;
	unsigned int tempData;

	if(receCount > 4)
	{
		switch(receBuf[1])
		{
			case 1://读取线圈状态(读取点 16位以内)
			case 3://读取保持寄存器(一个或多个)
			case 5://强制单个线圈
			case 6://设置单个寄存器
					if(receCount >= 8)
					{//接收完成一组数据
						//应该关闭接收中断
						
						if(receBuf[0]==Local_Address && checkoutError==0)
						{
							crcData = crc16(receBuf,6);
							if(crcData == receBuf[7]+(receBuf[6]<<8))
							{//校验正确
								if(receBuf[1] == 1)	  //读取线圈状态(读取点 16位以内)
								{
									readCoil();								
								}
								else if(receBuf[1] == 3)  //读取保持寄存器(一个或多个)
								{
									readRegisters();
								}
								else if(receBuf[1] == 5)   //强制单个线圈
								{
									forceSingleCoil();								
								}
								else if(receBuf[1] == 6)
								{
									presetSingleRegister();								
								}
							}
						}						
						receCount = 0;	
						checkoutError = 0;
					}
					break;
			
			case 15://设置多个线圈
					tempData = receBuf[6]; 
					tempData += 9;	//数据个数
					if(receCount >= tempData)
					{
						if(receBuf[0]==Local_Address && checkoutError==0)
						{
							crcData = crc16(receBuf,tempData-2);
							if(crcData == (receBuf[tempData-2]<<8)+ receBuf[tempData-1])
							{
								//forceMultipleCoils();			
							}
						}	
						receCount = 0;
						checkoutError = 0;
					}
					break;
			
			case 16://设置多个寄存器
					tempData = (receBuf[4]<<8) + receBuf[5];
					tempData = tempData * 2;	//数据个数
					tempData += 9;
					if(receCount >= tempData)
					{
						if(receBuf[0]==Local_Address && checkoutError==0)
						{
							crcData = crc16(receBuf,tempData-2);
							if(crcData == (receBuf[tempData-2]<<8)+ receBuf[tempData-1])
							{
								presetMultipleRegisters();			
							}
						}	
						receCount = 0;
						checkoutError = 0;
					}
					break;
								
			default:
					break;			
		}
	}
}

⌨️ 快捷键说明

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