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

📄 adam.h

📁 西门子PPI协议源码
💻 H
字号:
////////////////////////////////////////////////////////////////////////////
/////////** ADAM.h                                //////////////////////
//** 这个头文件定义了ADAM通用的程序,和效验
#ifndef ADAM_H
#define ADAM_H

//c:简化了接受判断程序
//
//b:增加了目标设置指令
//   对于亚当协议,指令为@(Addr)SV(Data)<CR> 
//                 示例:@06HI+0300.0<CR> 回答为>(Addr)+1234.5+2345.6+3210.0<CR>
//   对于天宏协议  指令为02,ADDR,S,+1000,XOH,XOL,03 回答和查询相同
//   SV是整数类型,忽略小数点,既+0100.0为数set_value=1000,显示为100.0             

/*研祥通讯协议
命令	             PC发送	             PC接受	                          示例	   说明
e读配置	         $(Addr)2<CR>	 !(Addr)(InputRange)(bt)(datformat)<CR>		
e读模块名称	     $(Addr)M<CR>	 !(Addr)(ModuleName)<CR>		                       14013、14017、14018
e读版本	         $(Addr)F<CR>	 !(Addr)(FirmRev)<CR>	                $30F<CR>  !30A2.10<CR>	
u读同步数据	     $(Addr)4<CR>	 >(Addr)(Status)(Data)<CR>	            $064<CR> >060+1.6888<CR> >061+1.6888<CR>	1表示第一次被读
e读模拟数据	     #(Addr)<CR>	 >(InputData)<CR>	                    #06<CR>  >+1.6888<CR>	仅对4013有效,为0通道的数据
u量程校准	     $(Addr)0<CR>	 !(Addr)<CR>	                            $060<CR>  !06<CR>	
u零点偏移	     $(Addr)1<CR>	 !(Addr)<CR>	                            $061<CR>  !06<CR>	
e从N通道读数	 #(Addr)(Ch)<CR> >(InputData)<CR>	                #061<CR> >+1.6888<CR>	ch0-7,(4013,0-2)
e读所有通道数据	 #(Addr)A<CR>	 >(Id)(Id)(Id)<CR>	                    #06A<CR> >+100.88+020.66+006.79<CR>	仅对4013有效
u用/禁通道,计数	 $(Addr)5(chv)<CR>!(Addr)<CR>	                        $06548<CR>  !06<CR>	3、6通道启用,其他禁止
e读通道状态	     $(Addr)6<CR>	 !(Addr)(chv)<CR>	                    $066<CR>  !0648<CR>	
u读CJC状态	     $(Addr)3<CR>	 >(InputData)<CR>	                    $063<CR>  >+0037.9<CR>	仅4018,冷端补偿温度
uCJC偏移校准	 $(Addr)9(Counts)<CR>	!(Addr)<CR>	                    $089+0042<CR>  !08<CR>	H42=66,66*0.0153=1.009度
u设置报警上限	 @(Addr)HI(Data)<CR>	!(Addr)<CR>	                    @06HI+300.00<CR>  !06<CR>	
u设置报警下限	 @(Addr)LO(Data)<CR>	!(Addr)<CR>	                    @06LO+100.00<CR>  !06<CR>	
u读事件计数器	 @(Addr)RE<CR>	 !(Addr)(Data)<CR>	                    @06RE<CR>  !0612345<CR>	
u读报警上限	     @(Addr)RH<CR>	 !(Addr)(Data)<CR>	                    @06RH<CR>  !06+1.500<CR>	1.5V报警
u读报警下限	     @(Addr)RL<CR>	 !(Addr)(Data)<CR>	                    @06RL<CR>  !06-0.3840<CR>	
针对天宏组态软件的扩展
读所有通道数据,返回数据中含地址信息
1.
@(Addr)N<CR>  >(Addr)+123.45+234.56...N<CR>
如:4013:@(Addr)3<CR>      >(Addr)+123.45+234.56+321.00<CR>	
如:4014:@(Addr)4<CR>      >(Addr)+123.45+234.56+321.00+123.88<CR>	
如:4018:@(Addr)8<CR>      >(Addr)+123.45+234.56+321.00+123.88+123.45+234.56+321.00+123.88<CR>	
N='1' TO '8'(即0x31-0x38)

  2.
  @(Addr)A<CR>   >(Addr)+123.45+234.56...<CR>      8路 注意是含地址的 	
  @(Addr)SV<CR>  >(Addr)+123.45+234.56+234.56<CR>  3路 注意是含地址的
  
	3.
	#(Addr)SV<CR>  >+123.45+234.56+234.56<CR>  3路 注意不含地址的			 
	天宏组态默认含有和效验
*/
/*因为是+***.**表达法,所以不同与天宏协议,使用LONG,并且int_temp也是LONG */

uchar uc_get_char(uchar uc_input)
{
	if(uc_input>=10) {return(uc_input+55);}
	else{return(uc_input+0x30);}	
}	
////////////////////////////////////////////////////////////////
uchar uc_get_data(uchar uc_h,uchar uc_l)
{
	if(uc_h>64){uc_h-=55;}else{uc_h-=0x30;}
	if(uc_l>64){uc_l-=55;}else{uc_l-=0x30;}
	return((uc_h<<4) | uc_l);
}
////////////////////////////////////////////////////////////////
uchar calc_uc_send_yx(uchar *comx,uchar xb,unsigned long ui_mid_in_send)
{
	uchar cci,ccj;
	uchar uc_comm_mid_buf[5];
	
	uc_comm_mid_buf[0]=ui_mid_in_send/10000+0x30;
	uc_comm_mid_buf[1]=(ui_mid_in_send/1000)%10 +0x30;
	uc_comm_mid_buf[2]=(ui_mid_in_send/100)%10 +0x30;
	uc_comm_mid_buf[3]=(ui_mid_in_send/10)%10 +0x30;
	uc_comm_mid_buf[4]=(ui_mid_in_send)%10 +0x30;
	
	cci=0;
	for(ccj=0;ccj<=5;ccj++)
	{
		xb++;
		if((5-ccj)==COMM_DP){*(comx + xb) = '.';}
		else{*(comx + xb) = uc_comm_mid_buf[cci];cci++;}
	}
	
    return(xb); 	 
}
/////////////////////////////////////////////////////////////////

//****************************************************************************
//**Purpose:
//**    当ADAM分析及返回,先效验 返回为发送串长(下标),返回0为不发送
uchar adam_reqframe_anlys_slaver(UCHAR *puc_rec_buf,UCHAR uc_rec_len,UCHAR *puc_send_buf,uchar uc_head)
{
	uchar uc_is_need_check = 0;//注意不可使用is_need_check,is_need_send,因为有宏定义的原因
	uchar uc_is_need_send = 0;
	//以上为标志,51系统可用位
	UCHAR cmd_pc_need,cmd_pc_need1;
	UCHAR uc_mid,uc_check_sum,uc_addr_h,uc_addr_l,uc_p_in_send;
	UINT ui_mid;
	
	cmd_pc_need =  *(puc_rec_buf + 2);
	cmd_pc_need1 = *(puc_rec_buf + 3);
	uc_check_sum = uc_head;
	
	switch(uc_rec_len)
	{
	case 2:
		{cmd_pc_need='A';uc_is_need_send = 1;}break;
	case 3:
		{uc_is_need_send = 1;}break;		
	case 5://13,sv1
		{
			for(uc_mid = 0;uc_mid < 3;uc_mid++){uc_check_sum += *(puc_rec_buf + uc_mid);}
			if((uc_check_sum) == uc_get_data(*(puc_rec_buf + 3),*(puc_rec_buf + 4)))
			{
				uc_is_need_check = 1;
				uc_is_need_send = 1;
			}
		}break;	
	case 6://是4050类型的写数字输出
		{
			if((cmd_pc_need == '0') && (cmd_pc_need1 == '0'))
			{uc_output=uc_get_data(*(puc_rec_buf + 4),*(puc_rec_buf + 5));}
			else if(cmd_pc_need == '1')
			{
				if(uc_get_data(*(puc_rec_buf + 4),*(puc_rec_buf + 5))==0)
				{uc_output &=~ BIT(cmd_pc_need1-0x30);}
				else
				{uc_output |=  BIT(cmd_pc_need1-0x30);}
			}	
			uc_head = 'A';//为统一程序,换头为A	
			uc_is_need_send = 1;	
		}break;	
		
	case 8://是4050类型的写数字输出,有效验
		{  
			for(uc_mid=0;uc_mid<6;uc_mid++){uc_check_sum += *(puc_rec_buf + uc_mid);}
			if(uc_check_sum == uc_get_data(*(puc_rec_buf + 6),*(puc_rec_buf + 7)))
			{
				if((cmd_pc_need == '0') && (cmd_pc_need1 == '0'))
				{uc_output=uc_get_data(*(puc_rec_buf + 4),*(puc_rec_buf + 5));}
				else if(cmd_pc_need == '1')
				{
					if(uc_get_data(*(puc_rec_buf + 4),*(puc_rec_buf + 5))==0)
					{uc_output &=~ BIT(cmd_pc_need1-0x30);}
					else
					{uc_output |=  BIT(cmd_pc_need1-0x30);}
				}
				uc_head = 'A';//为统一程序,换头为A
				uc_is_need_check = 1;
				uc_is_need_send = 1;
			}	
		}break;
		
#ifdef ADAM_DA_MODEL	
		// # A A N + 1 0 0 . 0 0 XH XL 0d
		// H 0 1 2 3 4 5 6 7 8 9 10 11 12
	case 10:
		{
			if(uc_head == '#')
			{
				//+0300.0
				ui_mid=0;
				for(uc_mid=4;uc_mid<=9;uc_mid++)
				{
					if(*(puc_rec_buf + uc_mid) != '.')
					{
						ui_mid*=10;
						ui_mid+=(*(puc_rec_buf + uc_mid)-0x30);
					}
				}
				
				Rtu_write_singleReg(cmd_pc_need-0x30,ui_mid);
				uc_is_need_send = 1;
			}	
		}break;
		
	case 12:
		{
			for(uc_mid=0;uc_mid<10;uc_mid++){uc_check_sum += *(puc_rec_buf + uc_mid);}
			if( uc_check_sum == uc_get_data(*(puc_rec_buf + 10),*(puc_rec_buf + 11)))
			{
				//+0300.0
				ui_mid=0;
				for(uc_mid=4;uc_mid<=9;uc_mid++)
				{
					if(*(puc_rec_buf + uc_mid) != '.')
					{
						ui_mid*=10;
						ui_mid+=(*(puc_rec_buf + uc_mid)-0x30);
					}
				}
				
				Rtu_write_singleReg(cmd_pc_need-0x30,ui_mid);
				
				uc_is_need_check = 1;
				uc_is_need_send = 1;
			}
		}break;
#endif  //ADAM_DA_MODEL	
	default: {uc_is_need_send = 0;}break;	
	}//switch
	
	///////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////
	if (uc_is_need_send)
	{
		//亚当协议
		uc_addr_h=*(puc_rec_buf);
		uc_addr_l=*(puc_rec_buf + 1);
		
		*puc_send_buf = '?';
		*(puc_send_buf + 1) = uc_addr_h;
		*(puc_send_buf + 2) = uc_addr_l;
		uc_p_in_send        = 2;
		
		if(uc_head == '#')
		{
			//da模块只返回>,超出范围返回?,
#ifdef ADAM_DA_MODEL
			if((cmd_pc_need-0x30) < CHANNEL_NUM)//CHANNEL_NUM定义在VAR中
			{
				*puc_send_buf = '>';
			}
			uc_p_in_send        = 0;
#else 
			if((cmd_pc_need < 0x38) && (cmd_pc_need >= 0x30))
			{ 
				{
					uc_mid        = cmd_pc_need;
					uc_mid       -= 0x30;
					*puc_send_buf = '>';
					uc_p_in_send=1;
					if(int_temp[uc_mid] >= 0)
					{
						*(puc_send_buf + 1) = 43;
						uc_p_in_send=calc_uc_send_yx(puc_send_buf,uc_p_in_send,int_temp[uc_mid]);
						//返回的是结尾的下标         传递数组指针   和当前下标,该函数内部先+1再赋值
					}
					else
					{
						*(puc_send_buf + 1) = 45;
						uc_p_in_send=calc_uc_send_yx(puc_send_buf,uc_p_in_send,-int_temp[uc_mid]);
					}
				}
			}/*cmd_pc_need<3*/	
			else if((cmd_pc_need == 'A') || ((cmd_pc_need == 'S') && (cmd_pc_need1 == 'V')))
			{
				*puc_send_buf = '>';
				uc_p_in_send=0;
				for(uc_mid=0;uc_mid<CHANNEL_NUM;uc_mid++)
				{
					uc_p_in_send++;
					if(int_temp[uc_mid] >= 0)
					{
						*(puc_send_buf + uc_p_in_send) = 43;
						uc_p_in_send=calc_uc_send_yx(puc_send_buf,uc_p_in_send,int_temp[uc_mid]);
						//返回的是结尾的下标         传递数组指针   和当前下标,该函数内部先+1再赋值
					}
					else
					{
						*(puc_send_buf + uc_p_in_send) = 45;
						uc_p_in_send=calc_uc_send_yx(puc_send_buf,uc_p_in_send,-int_temp[uc_mid]);
					}
				}	
			}/*COMMAND =A*/
#endif	
		} 
		else if(uc_head == '@')
		{  
			if((cmd_pc_need == 'S') && (cmd_pc_need1 == 'V')){cmd_pc_need = CHANNEL_NUM+0x30;}//转译!!!
			else if(cmd_pc_need == 'A'){cmd_pc_need = CHANNEL_NUM+0x30;}//转译!!!}
			
			if((cmd_pc_need <= 0x38) && (cmd_pc_need >= 0x31))
			{ 
				//only 0x31-0x38 enable,if cmd_pc_need='3',then send 0,1,2
				//cmd_pc_need='8',then send int_temp[0,1,2,3,4,5,6,7]
				cmd_pc_need -= 0x30;
				*puc_send_buf = '>';
				*(puc_send_buf + 1) = uc_addr_h;
				*(puc_send_buf + 2) = uc_addr_l;
				uc_p_in_send=2;
				
				for(uc_mid=0;uc_mid<cmd_pc_need;uc_mid++)
				{
					uc_p_in_send++;
					if(int_temp[uc_mid] >= 0)
					{
						*(puc_send_buf + uc_p_in_send) = 43;
						uc_p_in_send=calc_uc_send_yx(puc_send_buf,uc_p_in_send,int_temp[uc_mid]);
						//返回的是结尾的下标         传递数组指针   和当前下标,该函数内部先+1再赋值
					}
					else
					{
						*(puc_send_buf + uc_p_in_send) = 45;
						uc_p_in_send=calc_uc_send_yx(puc_send_buf,uc_p_in_send,-int_temp[uc_mid]);
					}
				} //end for
			}
		}	
		else if(uc_head == '$')
		{
			if(cmd_pc_need == 'M') 
			{
				*(puc_send_buf + 0) = '!';
				*(puc_send_buf + 1) = uc_addr_h;
				*(puc_send_buf + 2) = uc_addr_l;
				*(puc_send_buf + 3) = ME_TYPE0; 
				*(puc_send_buf + 4) = ME_TYPE1; 
				*(puc_send_buf + 5) = ME_TYPE2; 
				*(puc_send_buf + 6) = ME_TYPE3; 
				uc_p_in_send=6;
			}
			else if(cmd_pc_need == 'F') 
			{
				*(puc_send_buf + 0) = '!';
				*(puc_send_buf + 1) = uc_addr_h;
				*(puc_send_buf + 2) = uc_addr_l;
				*(puc_send_buf + 3) = 'A'; 
				*(puc_send_buf + 4) = MODULE_VERSION/100; 
				*(puc_send_buf + 5) = '.'; 
				*(puc_send_buf + 6) = (MODULE_VERSION / 10) % 10;
				*(puc_send_buf + 7) = MODULE_VERSION %10; 
				uc_p_in_send=7;
			}
			else if(cmd_pc_need == '6')//数字输入命令
			{
				*(puc_send_buf + 0) = '!';
				*(puc_send_buf + 1) = uc_get_char(uc_output>>4);
				*(puc_send_buf + 2) = uc_get_char(uc_output & 0x0f);
				*(puc_send_buf + 3) = uc_get_char(uc_input>>4);
				*(puc_send_buf + 4) = uc_get_char(uc_input & 0x0f);
				*(puc_send_buf + 5) = '0';
				*(puc_send_buf + 6) = '0';
				uc_p_in_send=6;	
			}
		}
		else if(uc_head == 'A')
		{
			*puc_send_buf = '>';
			uc_p_in_send=0;	
		}	
		
		if(uc_is_need_check)
		{
			uc_check_sum=0;
			for(uc_mid=0;uc_mid<=uc_p_in_send;uc_mid++)
			{uc_check_sum += *(puc_send_buf + uc_mid);}
			
			uc_mid = uc_check_sum;
			uc_p_in_send++;
			*(puc_send_buf + uc_p_in_send)=uc_get_char(uc_mid >>4);
			
			uc_p_in_send++;
			*(puc_send_buf + uc_p_in_send)=uc_get_char(uc_mid & 0x0f);
		}	
		
		uc_p_in_send++; 
		*(puc_send_buf + uc_p_in_send) = 13;
		
		return(uc_p_in_send);
		//亚当协议
	}
	else
	{
		return(0);
	}
}

#endif

⌨️ 快捷键说明

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