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

📄 ircomm.c

📁 一个电表的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    	 {                           //写数据,RAM
            RMtCt_Dtr[i] = Temp_WrtDt_Comm[4+i];
           }
        if(F_BlckWrt_Eeprm(EMtCt_Dtr,&Temp_WrtDt_Comm[4],3))//写数据,E2
         {
		    RMtWd_Dtr[0] &= 0xfd;	//存储芯片无错
		   }
		else
		 {
		    RMtWd_Dtr[0] |= 0x02;	//存储芯片出错
		   }               
        Nor_Write_Answer();                         //正常应答处理子程序         
    	break;
    	 
    	case 0xC113:		//循显时间
    	if(Temp_WrtDt_Comm[4] == 0)
    	 {   
            ErrByte_Comm.BYTE |= 0x01;         //非法数据,置错误信息字
            Abn_Answer();                      //异常应答处理子程序
            return;
           }    				
    	RShftDspTm_Dtr[0] = Temp_WrtDt_Comm[4];
        if(F_BlckWrt_Eeprm(EShftDspTm_Dtr,&Temp_WrtDt_Comm[4],1))//写数据,E2
         {
		    RMtWd_Dtr[0] &= 0xfd;	//存储芯片无错
		   }
		else
		 {
			RMtWd_Dtr[0] |= 0x02;	//存储芯片出错
		   }               
        Nor_Write_Answer();  
    	break;
    			
    	case 0xC114:				//停显时间    			
    	RStpDspTm_Dtr[0] = Temp_WrtDt_Comm[4];
        if(F_BlckWrt_Eeprm(EStpDspTm_Dtr,&Temp_WrtDt_Comm[4],1))//写数据,E2
         {
			RMtWd_Dtr[0] &= 0xfd;	//存储芯片无错
		   }
		else
		 {
			RMtWd_Dtr[0] |= 0x02;	//存储芯片出错
		   }               
        Nor_Write_Answer();  
    	break;  

   	    case 0xC117:        //4、自动抄表日时;
        if((Temp_WrtDt_Comm[4]>0x23)||(Temp_WrtDt_Comm[5]>0x28))//dd>31,hh>23
         {
    	     ErrByte_Comm.BYTE |= 0x01;              //非法数据,置错误信息字
    	     Abn_Answer();                           //异常应答处理子程序
    	     return;
    	    }     
         for (i=0;i<2;i++)                           //写数据,RAM
          {
             RAUtRdTm_Dtr[i] = Temp_WrtDt_Comm[4+i];
           }
            if(F_BlckWrt_Eeprm(EAUtRdTm_Dtr,&Temp_WrtDt_Comm[4],2))//写数据,E2
            {
				RMtWd_Dtr[0] &= 0xfd;	//存储芯片无错
			}
			else
			{
				RMtWd_Dtr[0] |= 0x02;	//存储芯片出错
			}               
            Nor_Write_Answer();                         //正常应答处理子程序     
    	    break;
	    case 0xC119:				//有功电能起始读数
	    ClrPw_Accdnt[0] = 0xe8;						//清零标志置位
		Databuf[0] = 0x00;		//非编程状态清零次数重新初始为零
		F_BlckWrt_Eeprm(ClrPw_Cnt,Databuf,0x01);		//读取清零允许次数

        Nor_Write_Answer();                         //正常应答处理子程序         
    	break;	

    	case 0xCD01:		//16个正常显示序号
    		for (i=0;i<16;i++)                           //写数据,RAM
            {
            	if(		(Temp_WrtDt_Comm[4+i] > 0x17)
            		&&	(Temp_WrtDt_Comm[4+i] != 0xff)
            	  )
            	{
    	        	ErrByte_Comm.BYTE |= 0x01;              //非法数据,置错误信息字
    	        	Abn_Answer();                           //异常应答处理子程序
    	        	return;
    	    	}  
            }
    		for (i=0;i<16;i++)                           //写数据,RAM
            {
                RRttDspNo_Dtr[i] = Temp_WrtDt_Comm[4+i];
            }
            if(F_BlckWrt_Eeprm(ERttDspNo_Dtr,&Temp_WrtDt_Comm[4],16))//写数据,E2
            {
				RMtWd_Dtr[0] &= 0xfd;	//存储芯片无错
			}
			else
			{
				RMtWd_Dtr[0] |= 0x02;	//存储芯片出错
			}
			DispTbl_Disp = 1;			//显示表有改变信号      
            Nor_Write_Answer();
    		break;
			  		 
    	case 0xCD03:		//16个按键显示序号
    		for (i=0;i<16;i++)                           //写数据,RAM
            {
            	if(		(Temp_WrtDt_Comm[4+i] > 0x17)
            		&&	(Temp_WrtDt_Comm[4+i] != 0xff)
            	  )
            	{
    	        	ErrByte_Comm.BYTE |= 0x01;              //非法数据,置错误信息字
    	        	Abn_Answer();                           //异常应答处理子程序
    	        	return;
    	    	}  
            }
    		for (i=0;i<16;i++)                           //写数据,RAM
            {
                RKeyDspNo_Dtr[i] = Temp_WrtDt_Comm[4+i];
            }
            if(F_BlckWrt_Eeprm(EKeyDspNo_Dtr,&Temp_WrtDt_Comm[4],16))//写数据,E2
            {
				RMtWd_Dtr[0] &= 0xfd;	//存储芯片无错
			}
			else
			{
				RMtWd_Dtr[0] |= 0x02;	//存储芯片出错
			}
			DispTbl_Disp = 1;			//显示表有改变信号      
            Nor_Write_Answer();
    		break;  
    	        	        
     default:            		//标识错,异常应答
    	    ErrByte_Comm.BYTE |= 0x02;  //标识错,置错误信息字
    	    Abn_Answer();               //异常应答处理子程序
    	    break;
   }//switch end        
}


//待写入数据BCD码判断
unsigned char Judge_BCD(void)
{
    unsigned char i,temp_num;
    
    if (CommandByte_Comm == 0x04)       //为了广播校时等其它命令通用
    {
        temp_num = CommandDataLength_Comm-6;
        for(i=0;i<temp_num;i++)
    	{
        	if(!((Temp_WrtDt_Comm[i+4]&0x0f)<=0x09) && ((Temp_WrtDt_Comm[i+4]&0xf0)<=0x90))
        	{    
            	ErrByte_Comm.BYTE |= 0x01;  //非法数据,置错误信息字
            	return 1;
        	}          
    	}
    }
        
    else
    {
        temp_num = CommandDataLength_Comm;    
    	for(i=0;i<temp_num;i++)
    	{
        	if(!((Temp_WrtDt_Comm[i]&0x0f)<=0x09) && ((Temp_WrtDt_Comm[i]&0xf0)<=0x90))
        	{    
            	ErrByte_Comm.BYTE |= 0x01;  //非法数据,置错误信息字
            	return 1;
        	}          
    	}
    }
    return 0;    
}




//编程密码比较
unsigned char Compare_sub_code(void)
{
	unsigned char i;
	for(i=0;i<4;i++)
	{
		if(RPassWd_Dtr[i] != Temp_WrtDt_Comm[i])
		{
			return 1;
		}
	}   
    
    return 0;
}                
//写命令正常应答
void Nor_Write_Answer(void)
{ 	
	 SignPrgrm = DI1DI0_Comm;
	 Prgrm_Accdnt = 1;       
	 RxTxState_Comm = AtTxState_Comm;             //置待发送状态
     Txd_Fe_Cnt = 1;
     TempCs_Comm = SioHead_Sub_Comm();            //向通讯缓冲区内写入DLT/645 协议头,返回协议头的校验和
     Put_To_SIOBuffer(0x84);                      //写入从站正常应答控制码
     TempCs_Comm+=(0x84);
     Put_To_SIOBuffer(0x00);                      //写入数据域长度
     Put_To_SIOBuffer(TempCs_Comm);               //写入校验和CS                
	 Put_To_SIOBuffer(0x16);                      //写入结束符0x16							
     End_Flg = 0x38;							  //发送完 触发end 显示
}

//计算周次
unsigned char GetDayofWeek(unsigned char *CurrentYear,unsigned char *Month,
							unsigned char *Day)
{
	unsigned char Table[13] = {0,0,3,3,6,1,4,6,2,5,0,3,5}; 
	unsigned char AccValue;
	unsigned int  TempYear;
	unsigned int  Year;
	
	Year = 2000 + Bcd_hex(*CurrentYear);
	AccValue = 5;  //2000.1.1是周6,这里的基准为了和日期对应取周5。
	TempYear = 2000;
	while(TempYear != Year)
	{
		if (((TempYear%4)==0) && ((TempYear%100)!=0) || ((TempYear%400)==0)) 
		{
			AccValue += 2;	
		}
		else
		{
			AccValue += 1;
		}
		TempYear += 1;
	}
	if (Bcd_hex(*Month) > 2)
	{
		if (((TempYear%4)==0) && ((TempYear%100)!=0) || ((TempYear%400)==0)) 
		{
			AccValue += 1;	
		}
	}
	AccValue = AccValue + Table[Bcd_hex(*Month)];
	AccValue = AccValue + Bcd_hex(*Day);
	AccValue = AccValue % 7;
	return AccValue;	
}
/**********************************************************
			广播冻结电量
***********************************************************/
void   BroChkEng_frost(void)
{
   F_BlckWrt_Eeprm(ELBrock_PPwrTtl_Dtr,RPPwrTtl_Dtr,0x04);		//广播冻结电量
   F_BlckWrt_Eeprm(ELBrock_Tm,&RTm_Dtr[1],0x02);
   F_BlckWrt_Eeprm(ELBrock_Tm+2,&RDtWk_Dtr[1],0x03);
 }
/**********************************************************
	        三、强制从站与主站时间同步,即广播校时处理
***********************************************************/
void CheckTime_Set(void)
{
   unsigned char i;
   for(i=0;i<3;i++)                        //为周次腾地方
    {
       Temp_WrtDt_Comm[6-i] = Temp_WrtDt_Comm[5-i];
      }
   Temp_WrtDt_Comm[3] = GetDayofWeek(&Temp_WrtDt_Comm[6],&Temp_WrtDt_Comm[5],
                                     &Temp_WrtDt_Comm[4]);		//计算周次
   for(i=0;i<7;i++)                        
    {
  	   E2Buffer[i] = Temp_WrtDt_Comm[i];
      }
   ClbrtTm_Trig = 1;							//显示时间
   SetTm_Accdnt = 1;
   SetDate_Accdnt = 1;
}

void CheckTime_Comm(void)
{
    unsigned char i;
    for(i=0;i<CommandDataLength_Comm;i++)   //取出数据域数据
     { 
	    Temp_WrtDt_Comm[i] = *CommandDataPointer_Comm-0x33; 
	    CommandDataPointer_Comm++;
	    CommandDataPointer_Comm = Bufferl_Tail_OP(CommandDataPointer_Comm);        
       } 
    if(Judge_BCD() == 1)                    //非法数据
     {   
	    return;
       }
    if((Temp_WrtDt_Comm[0]>0x60) || (Temp_WrtDt_Comm[1]>0x60)||(Temp_WrtDt_Comm[2]>0x23)) 
	 {
        return;
       }
    if((Temp_WrtDt_Comm[3]>0x31) || (Temp_WrtDt_Comm[4]>0x12))
	 { 
        return;
	  }  
    if(Progrm_Disp)       //**编程开关打在编程禁止
	 {
        CheckTime_Set();		//广播校时条件成立
     }
    else											//编程开关未闭合
	 {
	   if(BrochkSec_Cnt < 0x13c680)					//广播校时后秒计数器值大于60天     
        {
		   return;
         }
       if((Temp_WrtDt_Comm[5] != RDtWk_Dtr[3]) || (Temp_WrtDt_Comm[4] != RDtWk_Dtr[2]))	//主站校时年、月与电表年、月不等
	    {
		   return;
         }
       if((RDtWk_Dtr[1] >  Temp_WrtDt_Comm[3]) || ((RDtWk_Dtr[1] ==  Temp_WrtDt_Comm[3]) && (RTm_Dtr[2] >  Temp_WrtDt_Comm[2])) 
	     ||((RDtWk_Dtr[1] ==  Temp_WrtDt_Comm[3]) && (RTm_Dtr[2] ==  Temp_WrtDt_Comm[2]) && (RTm_Dtr[1] >  Temp_WrtDt_Comm[1]))
		 ||((RDtWk_Dtr[1] ==  Temp_WrtDt_Comm[3]) && (RTm_Dtr[2] ==  Temp_WrtDt_Comm[2]) && (RTm_Dtr[1] ==  Temp_WrtDt_Comm[1]) &&(RTm_Dtr[0] > Temp_WrtDt_Comm[0])))
		 {
		    if((RDtWk_Dtr[1] * 86400 + RTm_Dtr[2] * 3600 + RTm_Dtr[1] * 60 +  RTm_Dtr[0])
			  - (Temp_WrtDt_Comm[3] * 86400 + Temp_WrtDt_Comm[2] * 3600 + Temp_WrtDt_Comm[1] * 60 +  Temp_WrtDt_Comm[0]) < 1500)
			  {
			      CheckTime_Set();		//广播校时条件成立
               }
            else
			  {
			     return;
               }
          }
       else
	    {
		   if((Temp_WrtDt_Comm[3] * 86400 + Temp_WrtDt_Comm[2] * 3600 + Temp_WrtDt_Comm[1] * 60 +  Temp_WrtDt_Comm[0]) 
		       -(RDtWk_Dtr[1] * 86400 + RTm_Dtr[2] * 3600 + RTm_Dtr[1] * 60 +  RTm_Dtr[0]) < 1500)
			 {
			     CheckTime_Set();		//广播校时条件成立
              }
           else
		    {
			    return;
             }
         }
     }
   
}
  
      	
/**********************************************************
	        四、写设备地址,即设置某从站的地址码处理
***********************************************************/
void WirteDevcNo_Comm(void)
{
    unsigned char i;	
    Hello_Flg = 0x38;							//通信协议解析成功;触发 Hello 显示
    if ( ! Progrm_Disp)      					//**编程开关打在编程禁止
     {
	    return;
	 }
    for(i=0;i<CommandDataLength_Comm;i++)   	//取出数据域数据
     { 
	    Temp_WrtDt_Comm[i] = *CommandDataPointer_Comm-0x33; 
	    CommandDataPointer_Comm++;
	    CommandDataPointer_Comm = Bufferl_Tail_OP(CommandDataPointer_Comm);        
     } 
    if(Judge_BCD() == 1)                    //非法数据
	 {
        return;
      }
    for (i=0;i<6;i++) 
     {                         
        RMtNo_Dtr[i] = Temp_WrtDt_Comm[i];
      } 
    if(F_BlckWrt_Eeprm(EMtNo_Dtr,&Temp_WrtDt_Comm[0],6))
     {
	 	RMtWd_Dtr[0] &= 0xfd;	//存储芯片无错
	  }
	else
	 {
		RMtWd_Dtr[0] |= 0x02;	//存储芯片出错
	  }      
    Prgrm_Accdnt = 1;		//记录编程事件
    SignPrgrm = 0xc033;
    RxTxState_Comm = AtTxState_Comm;             //置待发送状态
	Txd_Fe_Cnt =1;
    TempCs_Comm = SioHead_Sub_Comm();            //向通讯缓冲区内写入DLT/645 协议头,返回协议头的校验和
    Put_To_SIOBuffer(0x8A);                      //写入从站正常应答控制码
    TempCs_Comm += (0x8A);
    Put_To_SIOBuffer(0x00);                      //写入数据域长度
    Put_To_SIOBuffer(TempCs_Comm);               //写入校验和CS                
	Put_To_SIOBuffer(0x16);                      //写入结束符0x16    						
    End_Flg = 0x38;							 	 //发送完 触发end 显示
}
/**********************************************************
	        五、写密码处理
	        	            
***********************************************************/
void AmendCode_Comm(void)
{
    unsigned char i;	
    Hello_Flg = 0x38;							//通信协议解析成功;触发 Hello 显示
    for(i=0;i<CommandDataLength_Comm;i++)   //取出数据域数据
     { 
	    Temp_WrtDt_Comm[i] = *CommandDataPointer_Comm-0x33; 
	    CommandDataPointer_Comm++;
	    CommandDataPointer_Comm = Bufferl_Tail_OP(CommandDataPointer_Comm);        
     } 
    if(Judge_BCD() == 1)                    //非法数据
     {
        return;
     }
    for(i=0;i<4;i++)                    //与原密码比较
     {
    	if(Temp_WrtDt_Comm[i] != RPassWd_Dtr[i])
    	{
        	return;
        }
     }
    if(Temp_WrtDt_Comm[4] != 0)                    //新密码权限必须为0
     {
        return;
     }

    for (i=0;i<4;i++)              //写数据,RAM   
     {          
    	RPassWd_Dtr[i] = Temp_WrtDt_Comm[4+i];
     }
    if(F_BlckWrt_Eeprm(EPassWd_Dtr,RPassWd_Dtr,4))//写数据,E2
     {
		RMtWd_Dtr[0] &= 0xfd;	//存储芯片无错
	 }
	else
	 {
		RMtWd_Dtr[0] |= 0x02;	//存储芯片出错
	 }     
   
    RxTxState_Comm = AtTxState_Comm;             //置待发送状态
	Txd_Fe_Cnt = 1;
    TempCs_Comm = SioHead_Sub_Comm();            //向通讯缓冲区内写入DLT/645 协议头,返回协议头的校验和
    Put_To_SIOBuffer(0x8F);                      //写入从站正常应答控制码
    TempCs_Comm += 0x8F;
    Put_To_SIOBuffer(0x04);                      //写入数据域长度
    TempCs_Comm += 0x04;
    for(i=0;i<4;i++)                             //写入数据
     {
        Put_To_SIOBuffer(Temp_WrtDt_Comm[4+i]+0x33);                      
        TempCs_Comm += (Temp_WrtDt_Comm[4+i]+0x33);     
     }
    Put_To_SIOBuffer(TempCs_Comm);               //写入校验和CS                
	Put_To_SIOBuffer(0x16);                      //写入结束符0x16  
	End_Flg = 0x38;									//写正确,显示end
	Prgrm_Accdnt = 1;		//记录编程事件
    SignPrgrm = 0xcd12;
}

⌨️ 快捷键说明

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