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

📄 rscomm.c

📁 本代码为电子式单相多费率电能表的源程序
💻 C
📖 第 1 页 / 共 4 页
字号:
                      Write24C64(&ComBuf[RS_CmdPtr+6],0x08,0x88,3);
                      EryBln_Flag = 1; //电能结算               
        	      break;
                    }     
        case 0xC1BB://时钟偏置
                    {
                      if(RX8025_CC==0x01)  Temp[0] = 0x7F;
                      else if(RX8025_CC==0x02)  Temp[0] = 0x7E;
                      else if(RX8025_CC==0x03)  Temp[0] = 0x7D;
                      else  Temp[0] = 0x00;
                      RTC_Set(0x70,Temp,1);
                      
                      Temp[1] = ~Temp[0];
                      Write24C64(Temp,0x08,0xFE,2);
        	      break;
                    }                       
        case 0xC32F://时区起始日期及日时段表号数据块
                    {
                      ComBuf[RS_CmdPtr+6+6] = ~SumCHK(&ComBuf[RS_CmdPtr+6+0],3);
  	              ComBuf[RS_CmdPtr+6+7] = ~SumCHK(&ComBuf[RS_CmdPtr+6+3],3);
  	              Write24C64(&ComBuf[RS_CmdPtr+6],0x09,0x47,8);
                      Fee_Flag = 1;    //置位费率检查标志
	              EryBln_Flag = 1; //电能结算
	              break;
                    }
        case 0xC33F:
        case 0xC34F://时段表1、2时段起始日期及费率号数据块
                    {
                      addr1 = 0x00;
                      if(RS_CmdL==0x3F)  addr2 = 0x60;
                      else if(RS_CmdL==0x4F)  addr2 = 0x80;
                      else  break;
                      ComBuf[RS_CmdPtr+6+24] = ~SumCHK(&ComBuf[RS_CmdPtr+6+0],24); 
                      Write24C64(&ComBuf[RS_CmdPtr+6],addr1,addr2,25);
                      Fee_Flag = 1; //置位费率检查标志
	              EryBln_Flag = 1; //电能结算
	              break;
                    }                  
        /////////////////////////////////////////////////////////////////////////
        case 0xC212://修改密码
                    {   
                      if(ComBuf[12]<=ComBuf[16]) //密级判断,高级可修改低级 
                      {
                      	ComBuf[20] = ~SumCHK(&ComBuf[17],3); //新密码的校验和
                      //addr0 = 0xA0;
                        addr1 = 0x08;
                        addr2 = 0x58; //编程密码
                        if(ComBuf[16]==0x00)  addr2 = 0x54; //清零密码
                        Write24C64(&ComBuf[17],addr1,addr2,4);
                      } 
                      else //密级不对,非法数据
                      {
                      	ErrInfFlag = 0xAA; //通讯错误信息标志
                        ErrInfStat = 0x01;
                        RS_Len =0x01;
                        TimeProg= 0; //无编程事件
                      }
                      break;
                    }   
        /////////////////////////////////////////////////////////////////////////            
        /////////////////////////////////////////////////////////////////////////
        case 0xC818://清过程(清事件)
                    {
                      ClearEvenFlag = 1;                     
                      break;
                    }   
        /////////////////////////////////////////////////////////////////////////
      	case 0xD400://自动显示数据域
                    {
    	              ComBuf[RS_CmdPtr+6+3] = ~SumCHK(&ComBuf[RS_CmdPtr+6+0],3);	
                      Write24C64(&ComBuf[RS_CmdPtr+6],0x00,0x50,4);
                      DspDataReadFlag = 1; //读显示控制参数标志置位
                      break;
                    }            
        case 0xD403://电表管理状态
                    {
                      Temp[0] = ComBuf[RS_CmdPtr+6+0]&0x03;
    	              if(Temp[0]==0x00)  isNewState = 0x80; //新进,启动36小时计时
    	              else  isNewState = 0x00;
    	              
    	              ComBuf[RS_CmdPtr+6+1]=~ComBuf[RS_CmdPtr+6+0];
                      Write24C64(&ComBuf[RS_CmdPtr+6],0x00,0xEE,2);
                      break;
                    }         
        case 0xD404://检定人代码和检定时间
                    {
                      Write24C64(&ComBuf[RS_CmdPtr+6],0x00,0xF0,6);
        	      break;
                    } 
        case 0xD415://时段表切换及标志
                    {                                                                 	    
                      //读取上次切换方式标志字节
                      Read24C64(&Temp[2],0x09,0x40,1);
                      Temp[3] = ~Temp[2];
                      //写本次时段表切换及标志      
                      ComBuf[RS_CmdPtr+6+6] = ~SumCHK(&ComBuf[RS_CmdPtr+6+0],6);
                      Write24C64(&ComBuf[RS_CmdPtr+6],0x09,0x40,7);
                      //********************************************************      
                      Temp[0] = 0x00; //清按编号切换完成标志
                      Temp[1] = 0xFF; 
                      Write24C64(Temp,0x09,0x53,4);
                      //********************************************************
                      Fee_Flag = 1; //置位费率检查标志
                      EryBln_Flag = 1; //电能结算
        	      break;
                    }
        //自定义命令
        case 0x230A://产品条形码1(低30字节)
                    {			
                      Write24C64(&ComBuf[16],0x09,0xC0,30);
                      break;
                    } 
        case 0x230B://产品条形码2(高30字节)
                    {		
                      Write24C64(&ComBuf[16],0x09,0xE0,30);
                      break;
                    }
        case 0x230C://电表表号
                    {		
                      ComBuf[22] = ~SumCHK(&ComBuf[16],6); //表号检验和
                      //用户号、局编号地址(资产条形码后8位)
                      Write24C64(&ComBuf[16],0x00,0xF7,7);
                      break;
                    }  
            default://数据项标识错
                    {
                      ErrInfFlag = 0xAA; //通讯错误信息标志
                      ErrInfStat = 0x02;
                      RS_Len =1;
                      TimeProg= 0; //无编程事件
                    }
      }
    }
    else //编程开关无效
    {
      Flag &= ~0x0A;
      //TxdFlag  = 0; //不回应
      //TimeProg = 0; //无编程事件
    }  
  }
  
}

//**********************************************************
//名称: void  LCDView(void)
//功能: LCD显示屏查看
//说明:
//**********************************************************
void  LCDView(void)
{
  Flag &= 0xE0;
  DspPtr = RS_CmdF; //查询页指针
  if( (DspPtr>21)&&(DspPtr<26) || (DspPtr>46) )  
  {
    DspPtr = 0x00;  //查询页指针出错处理
    LCDShowMode = 0;//正常轮显模式
  }
  else
  {
    LCDShowMode = 1; //查询模式
    LCDViewSec = LCDViewTime; //液晶显示屏查看时间
    CommLCDSec = 1; //查询时液晶不闪
  }
}

//**********************************************************
//名称: uchar RxdCheck(void)
//功能: 通讯帧格式及通讯地址检查
//说明:
//**********************************************************
uchar RxdCheck(void)
{	
  uchar i,CodeN,ErrorMeterAddrFlag=0;
  uchar Address[7];
	
  //帧长度、帧结构检查
  if(ComPtr<RS_MinSize || RS_Head!=0x68 || RS_Head0!=0x68 || RS_End!=0x16)  return(0x00); 
  //校验错误
  if( RS_CRC!=SumCHK(ComBuf,RS_CmdPtr+RS_Len))  return(0x00);
  Read24C64(Address,0x00,0xF7,7); //用户号、局编号地址(资产条形码后8位)
  i = SumCHK(Address,6); //表号检验和
  if(Address[6]!=~i)  ErrorMeterAddrFlag = 0xFF; //读表号出错	
  
  CodeN = 0x00;

  if( RS_Addr0==0x99 && RS_Addr1==0x99 && RS_Addr2==0x99 &&
      RS_Addr3==0x99 && RS_Addr4==0x99 && RS_Addr5==0x99 )
  {
    if(RS_Ctrl==RS_CTRL_Time)  CodeN=0x10; //广播校时
    //else if( RS_Ctrl==RS_CTRL_MetID && Prog_Flag==1 ) return(0x11); //广播设置电表号
    else  CodeN=0x00; //广播命令码错误
  }
  //局号符合(包含缩位寻址)
  else if( (RS_Addr0==Address[0]||RS_Addr0==0xAA) && (RS_Addr1==Address[1]||RS_Addr1==0xAA) && 
  	   (RS_Addr2==Address[2]||RS_Addr2==0xAA) && (RS_Addr3==Address[3]||RS_Addr3==0xAA) &&
  	   (RS_Addr4==Address[4]||RS_Addr4==0xAA) && (RS_Addr5==Address[5]||RS_Addr5==0xAA) ) 
  {
    if(RS_Ctrl==RS_CTRL_Read)  CodeN=0x21; //读数据
    else
    {
      if((RS_Addr0==0xAA) && (RS_Addr1==0xAA) && (RS_Addr2==0xAA) 
    	 &&(RS_Addr3==0xAA) && (RS_Addr4==0xAA) && (RS_Addr5==0xAA)) 
    	{
    	  if(RS_Ctrl==RS_CTRL_Write) 
    	  {
            //表号初始化,通过万能表号进行写操作
    	    if( (RS_CmdL==0x3F) && (RS_CmdH==0x56) && (ComBuf[12]==0x33) && (ComBuf[13]==0x56)
    	      &&(ComBuf[14]==0x3C) && (ComBuf[15]==0xC7) )
    	    {
    	      CodeN=0x22; //写数据
    	      ErrorMeterAddrFlag = 0x00; //
    	      //表号数据去0x33处理
    	      i = 0;
              do
              {
              	Address[i] = ComBuf[16+i]+0xCD;
                i++;
              }while(i<6);
    	    }
    	    //群清
    	    if( (RS_CmdH==0x07) && (RS_CmdL==0x43) && (ComBuf[12]==0x33) && (ComBuf[13]==0x56)
    	      &&(ComBuf[14]==0x3C) && (ComBuf[15]==0xC7) )
    	    {
    	      CodeN=0x22; //写数据
    	      ErrorMeterAddrFlag = 0x00; //
    	    }
    	  } 
    	  else  CodeN=0x00; //万能表号不允许写操作
    	}	
        else if(RS_Ctrl==RS_CTRL_Write)  CodeN=0x22; //写数据   
        else if(RS_Ctrl==RS_CTRL_Pswd)  CodeN=0x20; //修改密码(高级可修改低级)
        else  CodeN=0x00;
    }  
  }  
  else CodeN=0x00; //地址身份不符合,错误不响应

  for(i=6;i>0;--i) //构建返回表号
  {
    ComBuf[i] = Address[i-1];
  } 
  
  if(ErrorMeterAddrFlag!=0)  CodeN = 0x00; //
  
  return(CodeN);
  
}

//**********************************************************
//名称:uchar PsWdCHK(uchar PsWdPtr)
//功能:
//说明:
//**********************************************************
uchar PsWdCHK(uchar PsWdPtr)
{
  uchar PassWord[4];
 
  if(ComBuf[PsWdPtr]>0x01)  return 0x00; //权限错误
  //为扩展的自定义命令(设置表号,产品条形码)提供操作权限
  //(RS_CmdL==0x0C)||(RS_CmdL==0x0B)||(RS_CmdL==0x0A)
  else if( (RS_CmdH==0x23)&&(ComBuf[PsWdPtr+0]==0x00)&&(ComBuf[PsWdPtr+1]==0x23)
         &&(ComBuf[PsWdPtr+2]==0x09)&&(ComBuf[PsWdPtr+3]==0x94) )
  {
    return 0x10; //清零密码
  }
  else if( (RS_CmdH==0xD4)&&(ComBuf[PsWdPtr+0]==0x00)&&(ComBuf[PsWdPtr+1]==0x23)
         &&(ComBuf[PsWdPtr+2]==0x09)&&(ComBuf[PsWdPtr+3]==0x94) )
  {
    return 0x10; //清零密码
  }
  else
  {	
    //0x58--->编程密码地址 / 0x54--->清零密码地
    Read24C64(PassWord,0x08,0x54+ComBuf[PsWdPtr]*4,3);
    //密码比较
    if( ComBuf[PsWdPtr+1]==PassWord[0] && ComBuf[PsWdPtr+2]==PassWord[1] && ComBuf[PsWdPtr+3]==PassWord[2] )
    {	
      if(ComBuf[PsWdPtr]==0x00)  return 0x10; //清零密码
      else  return 0x11; //编程密码
    }
    else  return 0x00; //密码错误
  } 
  
}

//**********************************************************
//名称: TimeTerm()
//功能: 时间条件检查
//说明: 当编程开关打在"编程允许时",可用掌上机向时钟写入任意
//      时间。当编程开关打在"编程禁止时",只能对于误差在5分钟
//      之内的电表,进行对时。
//**********************************************************
bit TimeTerm(void)
{
  uchar MinSum1;
  uchar MinSum2;
		
  //时间数据正确性检查
  if(TimeCHK(&ComBuf[RS_CmdPtr+6])==0)  return(0);
  //30天判断
  AdjDate = DateTerm();
  //编程条件检查
  //if(Prog_Flag==1) return(1); //编程允许
  //else
  //{    	
    if(AdjDate==1) //30天判断
    {    		
      //不允许跨日校时
      if((Hour==0x00 && ComBuf[RS_CmdPtr+6+2]==0x23)|| 
     	 (Hour==0x23 && ComBuf[RS_CmdPtr+6+2]==0x00))  return(0);        	
      //时间误差计算
      if(abs(BCD2HEX(Hour)-BCD2HEX(ComBuf[RS_CmdPtr+6+2]))>1) //小时条件检查
      {
  	//AdjTime = 1; //时钟异常
  	return(0);
      }
      else
      {	
        //相差1小时之内	
  	MinSum1 = BCD2HEX(Min); //分
  	MinSum2 = BCD2HEX(ComBuf[RS_CmdPtr+6+1]);
  			
        if(Hour>ComBuf[RS_CmdPtr+6+2]) MinSum1 += 60;
        if(Hour<ComBuf[RS_CmdPtr+6+2]) MinSum2 += 60;
        
        if(abs(MinSum1-MinSum2)>=TimeErrorTerm) //大于时间条件,5分钟
        {
          return(0);
        }
        else 
        {
          return(1);	//满足校时误差条件    			
        }
      }
    }
    else return(0); //不满足30天条件
  //}	
}

//**********************************************************
//名称: Proc33()
//功能: 加减0x33H处理
//说明: 数据去0x33处理----0xCD ; 数据加0x33处理----0x33
//**********************************************************
void Proc33(uchar procdata)
{
  uchar i;   	 
  i=0x00;
  do
  {
    ComBuf[RS_CmdPtr+i] += procdata;
    i++;
  }while(i<RS_Len); 
}

⌨️ 快捷键说明

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