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

📄 spabus.cpp

📁 一个完整的RTU程序源码,用DOS平台,支持16串口,在天津港用的很多,8个规约103,modbus,cdt,1801,u4f
💻 CPP
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                 File name: spabus.cpp
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// & 0x26    > 0x3e    < 0x3c    / 0x2f    : 0x3a    LF 0x0a    CR 0x0d
// point 0x2e    space 0x20    A 0x41    a 0x61
//#include "extern.h"
#include "spabus.h"
INT8U static inline acc(INT8U);
void CSPABUS::initial(INT8U portno)
{

	myportno = portno;



	

	start_yx= ProtocolSet[myportno][0];
	end_yx =ProtocolSet[myportno][1];
	start_yc=++ProtocolSet[myportno][2];
		end_yc=ProtocolSet[myportno][3];

	rec_yx=start_yx;
	rec_yc=end_yc+1;

	slave_no=yx_define[start_yx].devno;  // portno devno type info reset channel
	channel_no=yx_define[start_yx].channel;
	data_no=yx_define[start_yx].info;
	if(yx_define[start_yx].type/10==1)// info H
		message_type='W';
	else
		message_type='R';
	switch(yx_define[start_yx].type%10){  // info L 
	case 0: data_type='S';
		break;
	case 1: data_type='O';
		break;
	case 2: data_type='I';
		break;
		}
}



INT8U CSPABUS::checksum(INT8U *buf, INT8U len)
{
	INT16U i ;
	INT8U sum;
	i = 1;
	sum = 0;
	while (i++<=len-5)
		sum = sum^buf[1];
	return (sum);
}


void CSPABUS::deal()
{
	if (!port_free(myportno)) return;

	if (port_timeout[myportno] >= 10){
		port_timeout[myportno] = 0;
		master_send();
		master_receive();
		
	}
}

void CSPABUS::master_send()
{
	if (++send_cycle >= 5){
		send_time();
		send_cycle = 0;
	}

	else
		send_query();
}


void CSPABUS::send_time()
{
	INT16U ptr = 0;
		
	sclock sclk;
	
	askbuf[ptr++]='>';
	askbuf[ptr++]='9';
	askbuf[ptr++]='0';
	askbuf[ptr++]='0';
	askbuf[ptr++]='W';
	askbuf[ptr++]='D';
	askbuf[ptr++]=':';
		
	GetClock(&sclk);
		
	askbuf[ptr++]=acc((sclk.year%100)/10);      //year   INT16U year month day weekday hour minute second msecond;
	askbuf[ptr++]=acc(sclk.year%10);
	askbuf[ptr++]='-';
	askbuf[ptr++]=acc(INT8U(sclk.month/10));   //month
	askbuf[ptr++]=acc(sclk.month%10);
	askbuf[ptr++]='-';
	askbuf[ptr++]=acc(INT8U(sclk.day/10));    //day
	askbuf[ptr++]=acc(sclk.day%10+0x30);
	askbuf[ptr++]=' ';
	askbuf[ptr++]=acc(INT8U(sclk.hour/10));    //hour
	askbuf[ptr++]=acc(sclk.hour%10);
	askbuf[ptr++]='.';
	askbuf[ptr++]=acc(INT8U(sclk.minute/10));     //minute
	askbuf[ptr++]=acc(sclk.minute%10);
	askbuf[ptr++]=';';
	askbuf[ptr++]=acc(INT8U(sclk.second/10));     //second
	askbuf[ptr++]=acc(sclk.second%10);
	askbuf[ptr++]='.';
	askbuf[ptr++]=acc(INT8U(sclk.msecond/100));      //     msecond
	askbuf[ptr++]=acc((sclk.msecond%100)/10);
	askbuf[ptr++]=acc(sclk.msecond%10);
		
	askbuf[ptr++]=':';
	askbuf[ptr++]='X';
	askbuf[ptr++]='X';
	askbuf[ptr++]=0x0d;

	com_transfer(myportno, ptr, askbuf);
	draw_send_message(myportno, askbuf, ptr, POLL_SEND_COLOR);

}//  yy-mo-dd hh.mm;ss.sss


void CSPABUS::send_query()
{
//	send_size = 0;

	INT8U ptr = 0;
	
	askbuf[ptr++] = '>';

	if((slave_no/100)>0){
		askbuf[ptr++]=acc(slave_no/100);
		askbuf[ptr++]=acc((slave_no-slave_no/100*100)/10);
		askbuf[ptr++]=acc(slave_no-(slave_no-slave_no/100*100)/10*10);
	}
	else if((slave_no/10)>0){
		askbuf[ptr++]=acc(slave_no/10);
		askbuf[ptr++]=acc(slave_no-slave_no/10*10);
	}
	else
		askbuf[ptr++]=acc(slave_no);

	askbuf[ptr++]=message_type;

	if((channel_no/10)>0){
		askbuf[ptr++]=acc(channel_no/10);
		askbuf[ptr++]=acc(channel_no-channel_no/10*10);
	}
	else
		askbuf[ptr++]=acc(channel_no);
	askbuf[ptr++]=data_type;
	if( (data_no/10)>0 ){
		askbuf[ptr++]=acc(data_no/10);
		askbuf[ptr++]=(data_no%10);
	}
	else
		askbuf[ptr++]=acc(data_no);
	
	askbuf[ptr++]=':';
	askbuf[ptr++]='X';
	askbuf[ptr++]='X';
	askbuf[ptr++]=0x0d;
	
//	send_size = ptr;

	com_transfer(myportno, ptr, askbuf);
	draw_send_message(myportno, askbuf, ptr, POLL_SEND_COLOR);
	
	change_address();
}


INT8U static inline acc(INT8U no)
{
	return no+0x30;
}



void CSPABUS::master_receive()
{
	INT16U rec_len;
	INT8U ptr=0;
	INT8U check1,check2;
	INT8U check;

	rec_len=get_com_rece_num(myportno);
	if(rec_len<9)
		return;//too little
	
	read_com_rece_nbytes(recbuf, 256, myportno);


	if( (recbuf[0] != 0x0a) || (recbuf[1] != 0x3c)){  //head  error
		clear_com_rece_buf(myportno);
		return;
	}
	
	for(ptr=8 ; (ptr < 255) && (recbuf[ptr] != 0x0a) ;ptr++)
		;
	
	if( (ptr >=255) || (recbuf[ptr] != 0x0a) || (recbuf[ptr-1] != 0x0d) ){  //end error
		clear_com_rece_buf(myportno);
		return;
	}

	check1 = asc_to_byte(recbuf[ptr-4]);
	check2 = asc_to_byte(recbuf[ptr-3]);

	if ( (check1 ==check/16) && ( check2==(check&0x0f))  ){
		process(recbuf,ptr);
		change_rec_address();
		draw_rece_message(myportno, recbuf, 11, POLL_RECE_COLOR);
	}

	else{
		clear_com_rece_buf(myportno);
		change_rec_address();
		return;
	}

}



void CSPABUS::process(INT8U *buf ,INT8U len)
{
	float digit,temp;
	INT8U ptr;
	INT16U digitFlag;
	digitFlag=10;
	

    if(rec_yc>end_yc){
		yx_update_db(rec_yx, buf[5]-0x30);
	}

	else{
		for(ptr=4;(ptr!='D')&&(ptr<=len);ptr++)
			;
		if(ptr>len)
			return;
		ptr++;
		for(temp=0 ;(ptr>=0x30)&&(ptr<=0x39)&&(ptr<=len);ptr++){
			temp=digitFlag*temp+buf[ptr];
			}

		digit=temp;

		if(buf[ptr]='.'){
			ptr++;
			for(temp=0;(ptr>=0x30)&&(ptr<=0x39)&&(ptr<=len);ptr++){
			temp=temp+buf[ptr]/digitFlag;
			digitFlag=digitFlag*10;
			}
		}

		digit=digit+temp;

		yc_update_db(rec_yc, digit);
	}
	
}







void CSPABUS::change_address()
{
	if(start_yc>end_yc){
		do{
			start_yx++;
		}
		while((start_yx<=end_yx)&&(yx_define[start_yx].portno!=myportno));

		if(ProtocolSet[myportno][2]=ProtocolSet[myportno][3])
			start_yx=ProtocolSet[myportno][0];
		else
			if(start_yx>end_yx)
				start_yc= ++ProtocolSet[myportno][2];
	
		slave_no=yx_define[start_yx].devno;  // portno devno type info reset channel
		channel_no=yx_define[start_yx].channel;
		data_no=yx_define[start_yx].info;
		if(yx_define[start_yx].type/10==1)// info H
			message_type='W';
		else
			message_type='R';
		switch(yx_define[start_yx].type%10){  // info L 
		case 0: data_type='S';
			break;
		case 1: data_type='O';
			break;
		case 2: data_type='I';
			break;
		}
	}
	else{
		do{
			start_yc++;
		}
		while    //portno; devno; type; info; order;
		 ((start_yc<=end_yc)&&(yc_define[start_yc].portno!=myportno));
		if(start_yc>end_yc)
			start_yx= ProtocolSet[myportno][0];
	
		slave_no=yc_define[start_yc].devno;  
		channel_no=yc_define[start_yc].order;
		data_no=yc_define[start_yc].info;
		if(yc_define[start_yc].type/10==1)// info H
			message_type='W';
		else
			message_type='R';
		switch(yc_define[start_yc].type%10){  // info L 
		case 0: data_type='S';
			break;
		case 1: data_type='O';
			break;
		case 2: data_type='I';
			break;
		}
	}

}

void  CSPABUS::change_rec_address()
{
	if(rec_yc>end_yc){
		do{
			start_yx++;
		}
		while
			((rec_yx<=end_yx)&&(yx_define[rec_yx].portno!=myportno));
		if(rec_yx>end_yx)
			rec_yc= ProtocolSet[myportno][2];
	}

	else{
		do{
			start_yc++;
		}
		while
		 ((rec_yc<=end_yc)&&(yc_define[rec_yc].portno!=myportno));
		if(rec_yc>end_yc)
			rec_yx= ProtocolSet[myportno][0];
	}
}

INT8U CSPABUS::asc_to_byte(INT8U value)
{
	INT8U byte;
	if( (value>=0x30)&&(value<=0x39) )
		byte=value-0x30;
	if( (value>=0x41)&&(value<=0x5a) )
		byte=value-(0x41-0x0a);
	else
		byte=value-(0x61-0x0a);
		return(byte);
}












⌨️ 快捷键说明

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