📄 ddsy922.c
字号:
}
/********************************************************************
比较函数
原型: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 + -