📄 dd100.c
字号:
#include"PL3105.h"
#define unchar unsigned char
#define unint unsigned int
unchar bdata pl_data; //发送字节缓冲
sbit pl_h=pl_data^7; //发送字节高位
unchar data r_data; //接收字节缓冲
unchar data len8=0; //发送位计数
unchar data r_8=0; //接收位计数
unchar data zbs_count=0;//发送字节计数
unchar data r_len; //接收字节计数
unchar data zbs_countl=23;//发送总字节
unchar data r_len1; //接收总字节
unchar xdata buf_send[23]={0x0ff,0x0ff,0x0ff,0x0ff,0x0ff,0x0ff,0x09,0x0af,0x30,0x40,0x0c8,0x00,0x00,0x00,0x00,0x00,0x0aa,0x0aa,0x42,0x64,0x9E,0x32,0x00};//发送数据
unchar xdata buf_recv[8];//接收数据
bit bdata flag=0; //发送完成标志
bit bdata r_x=0; //帧头标示符
bit bdata r_d=0; //载波数据标示符
bit bdata plmrxd=0; //正在接收载波数据标志 下行接收
unint data x_09af=0; //存放同步头
sbit RXD_TXD=P3^7; //载波数据输入输出端口
void initsys(void); //初始化设置函数
void initsys_ref(void); //初始化重置函数
void zb_pro(void); //载波通讯收发中断
void Zb_trans(void); //载波发送中断
void Zb_recv(void); //载波接收中断
void initsys(void)
{
CKCON=0X3F; // 控制看门狗喂狗时间长度
ALU_MOD=0; // 8位/16位运算模式选择位设置,设置成8位运算模式
IT2=1; // (C8H) 为边沿触发方式(IT2=1)。
EIP=0X01; // 外部中断2 为高级中断
EIE=0X01; // (A9H 使能INT2中断(EX2=1)
PLM_SSC=1; // (D8H)使能载波通讯PLM_SSC(EXT_CFG.0)=1
PLM_RS=0; // PLM_RS(EXT_CTRL.0)=1 为0时,载波处于接收状态
EA=1; // 开放中断
}
void initsys_ref(void)
{
if(IT2!=1) IT2=1; //(C8H)为边沿触发方式(IT2=1)
if(EIP!=0X01) EIP=0X01; // 外部中断2 为高级中断
if(EIE!=0X01) EIE=0X01; //(A9H)使能INT2中断(EX2=1)
if(PLM_SSC!=1) PLM_SSC=1; //(D8H)使能载波通讯PLM_SSC(EXT_CFG.0)=1
if(EA!=1) EA=1;
}
void zb_pro(void) interrupt 7 //载波通讯收发中断
{
if(PLM_RS==1)
Zb_trans(); //载波发送中断
else
Zb_recv(); //载波接收中断
}
void Zb_trans() //载波发送中断
{
if(flag==0)
{
if(len8==0)
pl_data=buf_send[zbs_count]; //取待发送字节到位发送缓冲
RXD_TXD=pl_h; //位发送,最高位在前
pl_data=pl_data<<1; //左移
len8++; //移位计数计算
if(len8>=8) //8位发送完毕
{
zbs_count++;//下一字节
len8=0; //移位计数清零
if(zbs_count>=zbs_countl)
flag=1;
}
}
else
{
flag=0;
len8=0;
zbs_count=0;
plmrxd=0; //发送完毕
PLM_RS=0;
}
}
void Zb_recv()
{
unchar data i;
PLM_RS=0; //冗余设置为接收态
RXD_TXD=1;
if(r_x==0) //帧头标志
{
if(RXD_TXD==1)
{
x_09af=x_09af|1;
}
if(x_09af==0x09af) //如果已接收到09AF
{
r_x=1; //置收到同步标志
r_8=0;
r_d=0; //开始接收载波数据体标志
x_09af=0;
r_data=0;
}
else
{
x_09af=x_09af<<1;
}
}
else
{
if(r_d==0) //
{
if(RXD_TXD==1)
{
r_data=r_data|1;
}
r_8++;
if(r_8!=8)
{
r_data=r_data<<1;
}
else //接收完成一字节数据
{
i=r_data;
i=i&0x20;
if(i==0x20)
{
r_len1=14; // 上行
}
else //下行
{
i=r_data;
i=i&0x18;
if((i==0x18)||(i==0x10)) //冻结抄表和实时抄表
{
i=r_data;
i=i&0x07;
r_len1=8+(2*i); //接收数据包的长度为8+2*N
}
else
if(i==0x08)
{ //设置表号,接收数据包的长度为8
r_len1=8;
}
else
{ //设表底接收数据包的长度为14
r_len1=14;
}
buf_recv[0]=r_data; //Func_A抄表功能比特
r_8=0;
r_d=1; //
r_len=1; //接收第二个字节
r_data=0;
}
}
}
else
{
if(RXD_TXD==1)
{
r_data=r_data|1;
}
r_8++;
if(r_8!=8)
{
r_data=r_data<<1;
}
else
{
buf_recv[r_len]=r_data;
r_8=0;
r_len++;
r_data=0;
if(r_len==r_len1)
{
r_x=0;
r_d=0; //校验正确之后,置接收完成一帧标志
plmrxd=1; //接收完毕
PLM_RS=1; //置为发送态
}
}
}
}
}
void main()
{
initsys(); //系统初始化
while(1)
{
WDT_RST=0xA1;
initsys_ref(); // 设置重置
if(plmrxd==1) //接收完一帧
{
if((buf_recv[0]==0x10)&&(buf_recv[2]==0x42)&&(buf_recv[3]==0x64)&&(buf_recv[4]==0x0aa)&&(buf_recv[5]==0x0aa)&&(buf_recv[6]==0x36)&&(buf_recv[7]==0x0a)) //判断地址是否为本表地址
{
PLM_RST=0XA2;
WDT_RST=0xA1; //清看门狗
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -