我替换后的
- /******************************************************************
- ** 开关量输出
- ** 晶 振 频 率: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;
- }
- }
|