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

📄 ddsy922.c

📁 为88SC102IC卡与AT89C52做表的可以供大家参考
💻 C
📖 第 1 页 / 共 5 页
字号:
}

 /********************************************************************
比较函数
原型:unsigned char  Tow_Compare(unsigned long Compare ,unsigned long Compare );
功能:两个数做比较
入口参数: Compare0 与 Compare为二个比较的指针
出口参数:Flag_Relay 为1是表示前数比后数大,为0表示前数比后数小,为2表示二数相等
********************************************************************/
unsigned char  Tow_Compare(unsigned char *Compare0 ,unsigned char *Compare )
 {
  unsigned char cplen ;
  //if(*Compare0>0)
  //  return 1;
  for(cplen=0;cplen<3;cplen++) 
    {
    if((*(Compare0+cplen))>(*(Compare+cplen)))
      return 1;   
  	else if((*(Compare0+cplen))<(*(Compare+cplen)))
	    return 2;
    }
  	return 0;
  }
 /* 
unsigned char *TWO_BCD_Add(unsigned char*Addition1,unsigned char *Addition)
{
  unsigned char l1,Additions[4],a,b; 
  for(l1=0;l1<4;l1++)
	 {
	  AC=0;
      CY =0;
	   *(Additions+l1)=*(Addition1+l1)+*(Addition+l1);//+*(Additions+l1);
        a=AC;b=CY;
		if(AC||((*(Additions+l1)&0x0F)>=0x09))
		 {
		 *(Additions+l1)=*(Additions+l1)+0X06;
		 }
	  AC=0;
      CY =0;
		 if(CY||((*(Additions+l1)&0xf0)>=0x90))
		 {
		  *(Additions+l1)=*(Additions+l1)+0x60;
		  *(Additions+l1+1)=*(Additions+l1+1)+0X01;
		 }
	  }
   return Additions;
 }	  */
/*unsigned char TWO_BCD_Dec(unsigned char *Subtration1,unsigned char *Subtration)
{
  unsigned char l2, *Subtrations;
  for(l2=0;l2<4;l2++)
     {
	  if(Subtration1[l2]&0xf0==0xf0)
		 {
		 Subtration1[l2]= Subtration1[l2]+0x99;
		 Subtration1[l2+1]=Subtration1[l2+1]-0x01;
		 }
	  else if(Subtration1[l2]&0x0f==0x0f)
	     Subtration1[l2]= Subtration1[l2]-0x06;
	  if (Subtration1[l2]>=Subtration[l2])	    
	    {
	    if((Subtration1[l2]&0x0f)>=(Subtration[l2]&0x0f))
		  {
		  Subtrations[l2]=Subtration1[l2]-Subtration[l2];
		  }
	    else 
			Subtrations[l2]=Subtration1[l2]-Subtration[l2]-6;
	    }  
	  if(Subtration1[l2]<Subtration[l2])
	    {
		Subtrations[l2]=0x99+Subtration1[l2]-Subtration[l2]; 
	    Subtration1[l2+1]=Subtration1[l2+1]-1;
	    }   	    
	  
     }
  return *Subtrations;
}  */

unsigned char xaoyanghe_cs(unsigned char *p,unsigned char length)
{
 unsigned char result;
 result=0;
 while(length)
 {
 result+=*p++;
 length--;
 }
 return result;
}
  


///********************************************************************
//接收一个字节通讯函数
//原型:unsigned char  Receive_Data();
//功能:接收一个字节通讯
//入口参数:无
//出口参数:返回接收值
//********************************************************************/
 
unsigned char  Receive_Data()
{    
    RI=0;
    ACC=SBUF;
    if(P!=RB8) /*偶校验正确吗?*/
        {
        SP--;SP--;CY=0;return CY; /*错误返回*/
        }
    return (ACC); /*接收一个字节,并进行偶校验*/
}
//********************************************************************
//接收一帧通讯函数
//原型:void Receive_One(unsigned char  *);
//功能:接收一帧通讯
//入口参数:接收存取地址指针
//出口参数:接收正确标志,1 为接收正确
//********************************************************************/
bit Receive_One(unsigned char  *r)
{
unsigned char  l,ChkSum,RecCounter; 
     if(RecCounter>=30){RecCounter=0;}     
     if(RecCounter==0 && Receive_Data()==0X68)
        {
          Flag_Rece=HIGH;
        //  ec.ReceBuf[0]=0x68;
          RecCounter=0x00;
        }
     if(Flag_Rece)
        {
        ChkSum += Receive_Data();
        switch(RecCounter)
          {
            case 0:
        	  if(Receive_Data()==0x68)
                { 
                 ChkSum = 0x68;
                 RecCounter++;
                 }
				break;
	       case 1:
           case 2:
           case 3:
           case 4:
           case 5:
           case 6: //接收表号 
				r[RecCounter-1] = Receive_Data();               
				RecCounter++; 
				break;
			case 7://0x68 again
				if(Receive_Data()==0x68) RecCounter++; 
				else RecCounter = 0; 
				break;
			case 8://cmd 
                 r[RecCounter-2] = Receive_Data(); RecCounter++;			
			  	 break; 
      case 9:
                if(Receive_Data()>=2)
                 {
                 l=Receive_Data(); 
                 RecCounter++; 
                 }
				else RecCounter = 0;
                 break;
	    	default:
				if(RecCounter==(l+10)) 
                {		//check sum
					if(Receive_Data()==(ChkSum-Receive_Data())) 
				 	 RecCounter++;
					else RecCounter = 0;
				}
				else if(RecCounter==(l+11))
                   {
					if(Receive_Data()==0x16) 
                        {//接收完成
                        flag_send=1;
                        CTRL485=0;
						return 1;//返回收到的数据字节数		
					    }
					else RecCounter = 0;
                       return 0;
				   }
				else
                   {
                   	r[RecCounter-3] = Receive_Data()-0x33;
                    RecCounter++;
                   }
				break;
            }   							
	  }
        Rece500ms=0;
      if(RecCounter>=30)
       {
        Flag_ReceFinish=HIGH;
        Rece500ms=0;
        RecCounter=0;
        Flag_Rece=1;
        }
 } 
 
 /********************************************************************
检查电能量是否存在乱码
原型:void Delay_T(unsigned char );
功能:延时1ms*i
入口参数: i 是设定延时时间
出口参数:无
********************************************************************/
/*unsigned char   power_check(unsigned char  *r)
{  
  unsigned char  i,i2,i3;     
   for(i=0;i<4;i++)
    {
        i2=*(r+i);
        i3=i2 & 0x0f;
        i2=(i2>>4) & 0x0f;
        if(i3>0x09 || i2>0x09)//乱码出现电能量清零校验码清零
        {
            *(r+i)=0; 
        }                
    }
                
  return 1;          
 } */
//********************************************************************
//串口接收中断服务程序
//功能:接收数据
//********************************************************************/
void RXD_Int(void) interrupt 4
 {
    CY=Receive_One(ec.ReceBuf);
    if(CY)
    Command_status1|=0x04; /*一帧接收成功,通知主程序进行通讯处理*/
  }

//串口接收中断函数 

 //********************************************************************
//串口发送一个字节
//功能:发送一个字节数据
//入口参数:发送数据
//出口参数:无
//********************************************************************/
void Send_Data(unsigned char  Serial_data)
{
    ACC=Serial_data;
    TB8=P;TI=0;
    SBUF=Serial_data;
    while(!TI);
    TI=0; /*发送一个字节,并进行偶校验*/
}
//********************************************************************
//发送一帧数据函数
//原型:void TXD_Int(unsigned char  *);
//功能:发送一帧数据
//入口参数:发送数据帧地址指针
//出口参数:无
//********************************************************************/
void TXD_Int(unsigned char  *s)
{    
    unsigned char i,j,CS=0x68;
   // CTRL485=0;//RS485 通讯,切换为发送状态
    //Delay_T(1);
    TI = 0;
    Send_Data(0xfe); /*发送2 个前到字节*/
    Send_Data(0xfe);
    Send_Data(0xfe); /*发送2 个前到字节*/
    Send_Data(0xfe);
    Send_Data(0x68); /*发送帧头*/
    for(i=0;i<=5;i++) /*发送电表通讯地址*/
      {
      *(s+i)=meter_para.factory_No[5-i]; 
        CS+=*(s+i);Send_Data(*(s+i));
      }
    CS+=0x68;Send_Data(0x68); /*发送数据帧头*/
    CS+=*(s+6);Send_Data(*(s+6)); /*发送帧命令*/
    DelayNus1(20);
    CS+=*(s+7);j=*(s+7);Send_Data(j); /*发送数据长度*/
    for(i=0;i<=j-1;i++) /*发送数据*/
      {
        (*(s+i+8))+=0x33;
       CS+=(*(s+i+8)); Send_Data(*(s+i+8));
      }
    Send_Data(CS); /*发送校验字节*/
    Send_Data(0x16); /*发送帧尾*/
    RI=0;TI=0;
     DelayNus1(1);
    //Delay_T(1);
    CTRL485=1; /*一帧发送完毕,恢复信道切换功能*/
   //; TR0=HIGH;
}
//********************************************************************
//通讯地址判断函数
//原型:unsigned char  Serial_Address(unsigned char  *);
//功能:通讯地址判断,通讯地址存储E2PROM 0 区0x00~0x05 中
//全局变量:
//入口参数:s1 指向从通讯地址
//出口参数:0x00 错误,0x01 正确,0x02 广播地址
//********************************************************************/
unsigned char  Serial_Address(unsigned char  *s1)
{
    unsigned char  i;
    page_read(0x20,ec.ReceBuf+12,6); /*读取电表通讯地址*/
    for(i=0;i<=5;i++)
        {
        if((*(s1+i))!=0x99)
        break; /*不是广播地址*/
        if(i==5)
        return(0x02); /*是广播地址*/
        }
    for(i=0;i<=5;i++)
        {
        if((*(s1+i))!=ec.ReceBuf[17-i])
        return(0x00); /*地址不相同*/
        }
    return(0x01); /*地址相同*/
}
//********************************************************************
//通讯密码判断函数
//原型:bit Serial_Password(unsigned char  *);
//功能:通讯密码判断,密码存储E2PROM 0 区0x06~0x09 中
//全局变量:
//入口参数:s1 指向从通讯密码地址
//出口参数:0 错误,1 正确
//********************************************************************/
bit Serial_Password(unsigned char  *s1)
{
    unsigned char  i;
   // IRcvStr(FM24W08,0x06,a,4);
    for(i=0;i<=3;i++)
        {
        if((*(s1+i))!=meter_para.prg_password[i])
        return 0;/*密码不对*/
        }
    return 1;/*密码正确*/
}
//********************************************************************
//通讯执行函数
//原型:bit Serial_Command_Run(unsigned char  *);
//功能:执行通讯命令
//入口参数:帧地址
//出口参数:是否正确及是否完毕,0 为错误和通讯没有完成,1 为正确和通讯完成
//********************************************************************/
bit Serial_Command_Run(unsigned char  *s)
{   
	 unsigned char i,aa;
    switch(Serial_Address(s)) /*判断地址是否正确*/
      {
        case 0x02: /*广播地址999999999999H*/
       // break;
        case 0x01: /*正常地址*/
         switch(*(s+6))
            {
            case 0x0f: /*进行密码修改*/
               if(~Serial_Password(s+8))/*密码是否正确*/
               return 0; /*错误,返回*/
               for(i=0;i<4;i++)
               meter_para.prg_password[i]=*(s+12+i); 
               page_read(OFFSET_OF(EEPROM_DATA,eprom_program_password),&meter_para.prg_password,SIZE_OF(EEPROM_DATA,eprom_program_password));
              // DelayNus1(1);
               /*构造返回数据帧*/
               for(i=0;i<4;i++)
               *(s+8+i)=meter_para.prg_password[i];              
               (*(s+6))|=0x80;(*(s+7))=0x04; /*存入命令码及长度字节*/
               TXD_Int(s); /*发送一帧数据*/
               break;
            case 0x01: /*读数据*/
               {
                switch(*(s+8))
                {
                case 0x90:
                 {
                 	switch(*(s+7))
                  {
                    case 0x10:
                     {  
                    (*(s+6))|=0x80;(*(s+7))=0x06; /*存入命令码及长度字节*/
                    (*(s+8))=0x10;(*(s+9))=0x90;
                    for(i=0;i<4;i++)
                    *(s+10+i)=real_energy.money0.money_overplus[3-i];
                    //page_read(0x02,s+10,4); //电表的剩余电量
                     TXD_Int(s); /*发送一帧数据*/
                     }
                    break;
                    case 0x11:
                     {
                      (*(s+6))|=0x80;(*(s+7))=0x06; /*存入命令码及长度字节*/
                      (*(s+8))=0x11;(*(s+9))=0x90;
                    for(i=0;i<4;i++)
                    *(s+10+i)=real_energy.money.money_sum[3-i];                      
                      //page_read(0x06,s+10,4);//电表的累计购电量 
                      TXD_Int(s); /*发送一帧数据*/
                     }
                    break;
                    case 0x12:
                     {
                      (*(s+6))|=0x80;(*(s+7))=0x06; /*存入命令码及长度字节*/
                      (*(s+8))=0x12;(*(s+9))=0x90;
                    for(i=0;i<4;i++)
                    *(s+10+i)=real_energy.electric.energy[3-i];  
                      //page_read(0x0a,s+10,4);//电表的累计用电量
                      TXD_Int(s); /*发送一帧数据*/
                     }
                    break;
                    case 0x13:
                     {
                       // page_read(0x20,s,6); /*读取电表通讯地址*/
                      (*(s+6))|=0x80;(*(s+7))=0x06; /*存入命令码及长度字节*/
                      (*(s+8))=0x13;(*(s+9))=0x90;
				             page_read(OFFSET_OF(EEPROM_DATA,eprom_money_notice0),s+10,SIZE_OF(EEPROM_DATA,eprom_money_notice0));
                      
                       /*构造返回数据帧*/
                        for(i=0;i<4;i++)
                        {aa=*(s+10+i);
                      *(s+10+i)=*(s+13-i);
                      *(s+13-i)=aa;} 
                      TXD_Int(s); /*发送一帧数据*/             
                     }
                    break;
                    case 0x14:
                     {
                      (*(s+6))|=0x80;(*(s+7))=0x05; /*存入命令码及长度字节*/
                      (*(s+8))=0x14;(*(s+9))=0x90;
                       for(i=0;i<3;i++)
                      *(s+10+i)=meter_para.pulse_constant[2-i];   
                    //  IRcvStr(FM24W08,0x00,s+8,3);//电表的有功脉冲常数 
                       TXD_Int(s); /*发送一帧数据*/
                     }
                    break;                    

⌨️ 快捷键说明

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