我替换后的
/******************************************************************
** 开关量输出
** 晶 振 频 率:11.0592M
** 线路->单片机实验开发板B
与组态王联机 实验板地址为:15 存储地址为15
测试代码(通过串口助手以16进制发送):40 30 46 43 35 30 30 30 46 30 31 30 41 30 36 0d
*************************************************************************************************/
#include<reg51.h>
/****************************开关端口定义*********************************************/
sbit sw_0=P3^3;
sbit sw_1=P3^4;
sbit sw_2=P3^5;
sbit sw_3=P3^6;
sbit jdq1=P2^0;//继电器1
sbit jdq2=P2^1;//继电器2
unsigned char rec[50];//用于接收组态王发送来的数据,发送过来的数据不能超过此数组长度
unsigned char code error[]={0x40,0x30,0x46,0x2a,0x2a,0x37,0x36,0x0d};//数据不正确
unsigned char code send[]={0x40,0x30,0x46,0x23,0x23,0x37,0x36,0x0d};//正确的数据
unsigned char i;
unsigned char sw;//开关值
void sw_out(unsigned char);//开关量输出
unsigned int htd(unsigned int); //进制转换函数
unsigned char ath(unsigned char,unsigned char);//ASIIC码转换为十六进制数
void uart(void);//串口中断程序
/************************************************************************************************/
void main(void)
{
unsigned char a=0;
TMOD=0x20; //定时器1--方式2
TL1=0xfd;
TH1=0xfd; //11.0592MHZ晶振,波特率为9600
SCON=0x50; //方式1
TR1=1; //启动定时
IE = 0x90; //EA=1,ES=1:打开串口中断
while(1)
{
sw_out(sw); //输出开关量
}
}
void sw_out(unsigned char a)
{
if(a==0x00)
{
jdq1=1; //接收到PC发来的数据00,关闭继电器1和2
jdq2=1;
}
else if(a==0x01)
{
jdq1=1; //接收到PC发来的数据01,继电器1关闭,继电器2打开
jdq2=0;
}
else if(a==0x10)
{
jdq1=0; //接收到PC发来的数据10,继电器1打开,继电器2关闭
jdq2=1;
}
else if(a==0x11)
{
jdq1=0; //接收到PC发来的数据11,打开继电器1和2
jdq2=0;
}
}
/**************************十六进制转十进制函数**************************/
/*函数原型:uint htd(uint a)
/*函数功能:十六进制转十进制
/*输入参数:要转换的数据
/*输出参数:转换后的数据
/*调用模块:无
/******************************************************************/
unsigned int htd(unsigned int a)
{
unsigned int b,c;
b=a%10;
c=b; //*16^0
a=a/10;
b=a%10;
c=c+(b<<4);//*16^1
a=a/10;
b=a%10;
c=c+(b<<8);//*16^2
a=a/10;
b=a%10;
c=c+(b<<12);//*16^3
return c;
}
/********************ASIIC码转换为十六进制程序*************************/
/*函数原型:unsigned char ath(unsigned char a,unsigned char b)
/*函数功能:ASIIC码转换为十六进
/*输入参数:要转换的数据
/*输出参数:转换后的数据
/*调用模块:无
/**********************************************************************/
unsigned char ath(unsigned char a,unsigned char b)
{
if(a<0x40)
a-=0x30;
else if(a<0x47)
a-=0x37;
else if(a<67)
a-=0x57;
if(b<0x40)
b-=0x30;
else if(b<0x47)
b-=0x37;
else if(a<67)
b-=0x57;
return((a<<4)+b);
}
/**************************串口中断程序******************************/
/*函数原型:void uart(void)
/*函数功能:串口中断处理
/*输入参数:无
/*输出参数:无
/*调用模块:无
/**********************************************************************/
void uart(void) interrupt 4
{
unsigned char a,b;
if(RI)
{
a=SBUF;
RI=0;
if(a==0x40)//接收到字头
i=0;
rec[i]=a;
i++;
if(a==0x0d)//接收到字尾,开始出路数据
{
if(ath(rec[1],rec[2])==15)//判断是否为本机地址
{
b=0;
for(a=1;a<i-3;a++)//产生异或值
b^=rec[a];
if(b==ath(rec[i-3],rec[i-2]))//接收到正确数据
{
if((ath(rec[3],rec[4])&0x01)==1)//写操作
{
sw=ath(rec[11],rec[12]);
sw=htd(sw);
for(a=0;a<8;a++)
{
SBUF=send[a];
while(TI!=1);
TI=0;
}
}
}
else//接收到错误数据
{
for(a=0;a<8;a++)
{
SBUF=error[a];
while(TI!=1);
TI=0;
}
}
}
}
}
else
{
TI=0;
}
}
|