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

📄 disp.c

📁 ATT7022B与C8051F的通讯licheng
💻 C
📖 第 1 页 / 共 5 页
字号:
		case 0x24: result = COMBINE_2UCHAR_TO_16UINT(Ic.high_byte8,Ic.low_byte8);
				break;
		case 0x26: result = 0;
				break;
		case 0x28: result = COMBINE_2UCHAR_TO_16UINT(Pc.high_byte8, Pc.low_byte8);
				break;
		case 0x2a: result = COMBINE_2UCHAR_TO_16UINT(Pfc.high_byte8,Pfc.low_byte8);
				break;
		case 0x2c: result = COMBINE_2UCHAR_TO_16UINT(Qc.high_byte8,Qc.low_byte8);
				break;
		case 0x2e: result = 0;
				break;
		case 0x30: result = 0;	
				break;
		case 0x32: result = 0;		
				break;		
		case 0x34: result = 0;
				break;		
		case 0x36: result = COMBINE_2UCHAR_TO_16UINT(F.high_byte8,F.low_byte8);
				break;		
		case 0x38: result = COMBINE_2UCHAR_TO_16UINT(Psum.high_byte8,Psum.low_byte8);
				break;
		case 0x3a: result = COMBINE_2UCHAR_TO_16UINT(Pfsum.high_byte8,Pfsum.low_byte8);
				break;			
		case 0x3c: result = COMBINE_2UCHAR_TO_16UINT(Qsum.high_byte8,Qsum.low_byte8);
				break;		
		case 0x3e: result = 0;
				break;
	
		case 0x42: result = 0;/*Power parameter*/
				break;		
		case 0x44: result = 0;
				break;
		case 0x46: result = 0;
				break;
		case 0x48: result = 0;
				break;
		case 0x4a: result = 0;
				break;
		case 0x4c: result = 0;
				break;
		case 0x4e: result = 0;
				break;
		case 0x50: result = 0;
				break;		
		case 0x52: result = 0;
				break;	  
		case 0x54: result = 0;//(Sec<<8|Secn);
				break;
		case 0x55: result = 0;//(Min<<8|Minn);
				break;
		case 0x56: result = 0;//(Hour<<8|Hourn);
				break;
		case 0x57: result = 0;//(Month<<8|Monthn);
				break;
		case 0x58: result = 0;//(Year<<8|Yearn);
				break;												
		default: result = 0;
				break;		
	}

	return result;
#endif
}

/*
***********************************************************************************************************
**函数原型		:  	read_holding_registers()
**参数说明		:  	
				:		
**返回值		:		
**说	明		:	本函数用于根据下行命令要求取得遥测数据,并通过485上传数据
************************************************************************************************************/

void read_holding_registers()
{//Analogy data
	uint readCount;
	uint result_value = 0;
	uchar k = 0;
	uchar start_dataAddr;//Start address for data
	uchar tempAddr;
	uchar byteCount;
	uint send_crcData = 0;
		if((modbus_com.recv_dataBuf[2]) || (modbus_com.recv_dataBuf[3] % 2) || (modbus_com.recv_dataBuf[3] > REGISTER_NUM))
			{ //起始地址不符合,读到非法寄存器地址
			modbus_com.recvNumber = 0;
		}
		else if(modbus_com.recv_dataBuf[5] > (REGISTER_NUM - modbus_com.recv_dataBuf[3])){//读实时数据长度超出积存器地址,舍弃frame
			modbus_com.recvNumber = 0;
		}		
		else{
			start_dataAddr = modbus_com.recv_dataBuf[3];
			tempAddr = start_dataAddr;
			modbus_com.send_dataBuf[0] = address;//DEV_ADDR*machine_multiple;
			modbus_com.send_dataBuf[1] = modbus_com.recv_dataBuf[1];
			readCount = modbus_com.recv_dataBuf[5];//Reading Bytes number
			byteCount = readCount * 2;//Calculation the Byte number for sending
			modbus_com.send_dataBuf[2] = byteCount;
			byteCount = byteCount + 3;//There has have 3 Bytes before 
			for(k = 3;k < byteCount;k += 2,tempAddr += 2){//Sending the Bytes
				result_value = getRegisterVal(tempAddr);
				modbus_com.send_dataBuf[k] = result_value >> 8;				   		
				modbus_com.send_dataBuf[k + 1] = result_value & 0xff;
				result_value = 0;
			}
			send_crcData = crcData(modbus_com.send_dataBuf,byteCount);//verify the data
			modbus_com.send_dataBuf[byteCount] = send_crcData >> 8;//Send High Byte at the first time
			byteCount++;
			modbus_com.send_dataBuf[byteCount] = send_crcData & 0xff;
			modbus_com.sendNumber = byteCount + 1;
			beginSend();
		}
}


 /*
***********************************************************************************************************
**函数原型		:  	select_YX_card(uchar sel_tmp)
**参数说明		:  	sel_tmp	-->>	遥信卡地址
				:		
**返回值		:	对应地址的具体数据	
**说	明		:	本函数用于遥信,根据下行命令的地址来查询对应的数据
************************************************************************************************************/

uchar select_YX_card(uchar sel_tmp){//选择遥信卡
	uchar yx_tmp;
	uchar sel_addr;//遥信地址
	sel_addr = sel_tmp & 0xff;
	if(sel_addr > (COIL_NUM - 8 * 1 - 1)){
		YX_CARD_SIXTEEN_ACTIVE();
		spi_delay(10);//为了选择势能端提供时间
	}
	else if(sel_addr > (COIL_NUM - 8 * 2 - 1)){
		YX_CARD_FIFTEEN_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 3 - 1)){
		YX_CARD_FOURTEEN_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 4 - 1)){
		YX_CARD_THIRTEEN_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 5 - 1)){
		YX_CARD_TWELVE_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 6 - 1)){
		YX_CARD_ELEVEN_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 7 - 1)){
		YX_CARD_TEN_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 8 - 1)){
		YX_CARD_NINE_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 9 - 1)){
		YX_CARD_EIGHT_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 10 - 1)){
		YX_CARD_SEVEN_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 11 - 1)){
		YX_CARD_SIX_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 12 - 1)){
		YX_CARD_FIVE_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 13 - 1)){
		YX_CARD_FOUR_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 14 - 1)){
		YX_CARD_THREE_ACTIVE();
		spi_delay(10);
	}
	else if(sel_addr > (COIL_NUM - 8 * 15 - 1)){
		YX_CARD_TWO_ACTIVE();
		spi_delay(10);//为了选择势能端提供时间
	}
	else if(sel_addr >= (COIL_NUM - 8 * 16)){
		YX_CARD_ONE_ACTIVE();
		spi_delay(10);
	}
	else{
		return 0;
	}
	return (yx_tmp = P3 & 0xff);
}
		 
/*
***********************************************************************************************************
**函数原型		:  	read_coils()
**参数说明		:  	
				:		
**返回值		:		
**说	明		:	本函数用于根据下行命令要求取得遥信数据,并通过485上传数据
************************************************************************************************************/
	
void read_coils(){//Switch data		
	uchar i;
	uchar start_dataAddr;//数据起始地址
	uchar tempAddr;
	uchar byteCount;//发送字节数
	uchar logic_data = 0;//产生的新数
	uchar remain_tmp_data = 0;//临时数据
	uchar full_byte_count = 0;//读取整字节个数
	uchar leavings_bit_count = 0;//读取剩余位个数
	uint send_crcData = 0;
	if((modbus_com.recv_dataBuf[2]) || (modbus_com.recv_dataBuf[3] >= COIL_NUM)){	//起始地址不符合,舍弃frame(128路遥信)
		modbus_com.recvNumber = 0;
	}
	else if(modbus_com.recv_dataBuf[5] > (COIL_NUM - modbus_com.recv_dataBuf[3])){//读实时数据长度超出积存器地址,舍弃frame
		modbus_com.recvNumber = 0;										//最大长度减起始地址
	}
	else{
		start_dataAddr = modbus_com.recv_dataBuf[3];
		tempAddr = start_dataAddr;//开始地址
		full_byte_count = modbus_com.recv_dataBuf[5] / 8;
		leavings_bit_count = modbus_com.recv_dataBuf[5] % 8;
		if(leavings_bit_count != 0){
			byteCount = full_byte_count + 1;
		}
		else{
			byteCount = full_byte_count;
		}
		modbus_com.send_dataBuf[0] = address;
		modbus_com.send_dataBuf[1] = modbus_com.recv_dataBuf[1];
		modbus_com.send_dataBuf[2]	= byteCount;
		byteCount += 3;			
		for(i = 0;i < full_byte_count; i++){//读取整字节
			modbus_com.send_dataBuf[3 + i] = select_YX_card(tempAddr);
			tempAddr += 8;
		}
		if(leavings_bit_count !=  0){//还有剩余位
			remain_tmp_data = select_YX_card(tempAddr);
			for(i = 0;i < leavings_bit_count;i++){
				logic_data |= (1 << i);//新的逻辑数
			}
			modbus_com.send_dataBuf[byteCount - 1] = (remain_tmp_data & logic_data);//把没有查询到的位清0
		}
		send_crcData = crcData(modbus_com.send_dataBuf,byteCount);
		modbus_com.send_dataBuf[byteCount] = send_crcData >> 8;
		byteCount++;
		modbus_com.send_dataBuf[byteCount]= send_crcData & 0xff;
		modbus_com.sendNumber = byteCount + 1;
		beginSend();	 
	}
}	

		
/*
***********************************************************************************************************
**函数原型		:  	T0_reset()
**参数说明		:  	
				:		
**返回值		:		
**说	明		:	本函数用于把定时器T0重新启动
************************************************************************************************************/	

/*
void T0_reset(){
	TR0=0;
	c20ms=0;
	flag_recv1ms=0;
	flag_recv20ms=0;
	TH0=TIMER_HIGHT;
	TL0=TIMER_LOW;
	TR0=1;
}					 */
   
/*
***********************************************************************************************************
**函数原型		:  	checkComm0Modbus()
**参数说明		:  	
				:		
**返回值		:		
**说	明		:	本函数用于modbus通信协议中处理下行数据,并完成上行数据的发送
************************************************************************************************************/

void checkComm0Modbus()
{//Check uart0 data
	uint recv_crcData = 0;
		if(modbus_com.recv_dataBuf[0] != address){//NO according with address,discard the frame	
			modbus_com.recvNumber = 0;
		}		
		else if(modbus_com.recv_dataBuf[0] == address){//DEV_ADDR*machine_multiple){
			recv_crcData = crcData(modbus_com.recv_dataBuf,6);//Verifing the receiving Data
			if(recv_crcData == ((RECVHIGH_CRCBYTE << 8) | RECVLOW_CRCBYTE)){//Verifing OK
				switch(modbus_com.recv_dataBuf[1]){//Judge the function code
					case 0x01: read_coils();break;//Query device (switch value)
					case 0x03: read_holding_registers(); break;//Reading data(Analog variable)
					default : modbus_com.recvNumber = 0;break;//function code is error,discard the frame
				}
			}
			else{
				modbus_com.recvNumber = 0;
			}
		}		   
}


/*
***********************************************************************************************************
**函数原型		:  	read_spi_data()
**参数说明		:  	
				:		
**返回值		:		
**说	明		:	本函数用于利用SPI传输方式,340读取7022B中的数据
************************************************************************************************************/ 
void read_spi_data(){	
	uchar tmp_high,tmp_middle,tmp_low;
	spi_delay(100);
	while(!SPIF);//SPI0中断标志,一个完整字节传输完成标志,由硬件置1
	spi_delay(20);
	SPIF = 0;


	spi_delay(200);//发送完毕MOSI,等待7022传输的过来的数据
	spi_delay(200);
	spi_delay(200);

	SPI_DATA_START();

	spi_delay(60);
	SPI0DAT = 0;	
	while(!SPIF); 
	spi_delay(30);
	tmp_high = SPI0DAT;
	SPIF = 0;
	spi_delay(60); 
	
	SPI0DAT = 0;
	while(!SPIF);	
	spi_delay(30);
	tmp_middle = SPI0DAT;
	SPIF = 0;
	spi_delay(60);

	SPI0DAT = 0;
	while(!SPIF);  
	spi_delay(30);
	tmp_low = SPI0DAT;
	SPIF = 0;
	spi_delay(10);

	SPI_CS_HIGH_LEVEL();// CS=1;  p4.5
	spi_delay(100);
	original_high_byte = tmp_high;
	original_middle_byte = tmp_middle;
	original_low_byte = tmp_low;
	
}

/*
***********************************************************************************************************
**函数原型		:  	revise_data(uchar tmp_high_byte,uchar tmp_middle_byte,uchar tmp_low_byte)
**参数说明		:  	tmp_high_byte	-->>	可调系数的高位字节
				:	tmp_middle_byte	-->>	可调系数的中位字节
				:	tmp_middle_byte	-->>	可调系数的低位字节	
**返回值		:		
**说	明		:	本函数用于调整测量数据的精度
************************************************************************************************************/
void revise_data(uchar tmp_high_byte,uchar tmp_middle_byte,uchar tmp_low_byte){
	uchar revise_parameter1;//Each meansure'revise paremeter
	uchar revise_parameter2;
	uchar revise_paremeter3;
	revise_parameter1=tmp_high_byte;
	revise_parameter2=tmp_middle_byte;
	revise_paremeter3=tmp_low_byte;	
	spi_delay(200);	
	while(!SPIF);
	spi_delay(60);
	SPIF = 0;

	SPI0DAT = revise_parameter1;
	spi_delay(30);
	while(!SPIF);
	spi_delay(60);

⌨️ 快捷键说明

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