组态王与单片机通讯亲测.
/*********************字节读写****************************************/
组态王向地址是1的单片机读取1byte数据组态王选择效验没变化都是一样的数据
40 30 31 41 30 30 30 30 30 30 31 37 31 0D--寄存器选择X0---BYTE---160-----14个字节07 D0 31 30 31 30 31 45 31 0D
40 30 31 41 30 30 30 30 30 30 31 37 31 0D
40 30 31 41 32 30 30 30 30 30 31 37 33 0D----162----打包与不打包除了格式和效验位的数值不一样了,好像没啥区别,呵呵!!
40 30 31 41 30 30 30 36 34 30 31 37 33 0D--寄存器选择X100---BYTE--0X64=100
40 30 31 41 30 30 30 43 38 30 31 30 41 0D--寄存器选择X200---BYTE--0XC8=200
40 30 31 41 30 30 31 32 43 30 31 30 31 0D--寄存器选择X300---BYTE--0X12C=300
40 30 31 41 30 30 37 44 30 30 31 30 32 0D--寄存器选择X2000---BYTE--0X7D0=2000
40 30 31 41 30 34 45 32 30 30 31 30 32 0D--寄存器选择X20000---BYTE--0X4E20=20000
字头-地址--模 式-数据-- 地址-字-节--异-或
组态王向地址是1的单片机写入1byte数据组--------------81--------------------16个字节
40 30 31 35 31 30 30 30 30 30 31 30 31 30 35 0D--寄存器选择X0---BYTE--数据是1 40 30 31 23 23 30 31 0D
40 30 31 35 31 30 30 30 30 30 31 30 41 37 35 0D--寄存器选择X0---BYTE--数据是10--0X41-0X37=0X0A=10 40 30 31 23 23 30 31 0D
40 30 31 35 31 30 30 30 30 30 31 36 34 30 36 0D--寄存器选择X0---BYTE--数据是100
40 30 31 35 31 30 30 30 30 30 31 43 38 37 46 0D--寄存器选择X0---BYTE--数据是200
字头-地址--模 式-数据-- 地址-字-节--数-值--异-或
0--1--2--3---4-5--6--7--8--9--10-11-12--13-14-15
/*********************字读写****************************************/
组态王向地址是1的单片机读2byte数据组------------------164------------------14个字节
40 30 31 41 34 30 30 30 30 30 32 37 36 0D--寄存器选择X0---USHORT--数据0 40 30 31 30 32 30 30 30 31 30 32 0D
40 30 31 41 34 30 30 30 41 30 32 30 37 0D--寄存器选择X10---USHORT--数据10 0X41-0X37=0X0A=10 40 30 31 30 32 30 37 44 30 37 30 0D
40 30 31 41 34 45 41 36 30 30 32 37 34 0D--寄存器选择X60000---USHORT--EA60=60000 40 30 31 30 32 46 46 46 41 30 34 0D
字头-地址模式-数据----地址--字节-异或值
组态王向地址是1的单片机写入2byte数据组----------------85------------------18个字节
40 30 31 35 35 30 30 30 41 30 32 30 37 44 30 30 31 0D--寄存器选择X10---USHORT--数据是2000 40 30 31 23 23 30 31 0D
40 30 31 35 37 30 30 30 41 30 32 30 37 44 30 30 33 0D----87-----打包 40 30 31 23 23 30 31 0D
/*********************浮点数读写****************************************/
组态王向地址是1的单片机读4byte数据组--------------168--------------------14个字节
40 30 31 41 38 30 30 30 30 30 34 37 43 0D--寄存器选择X0---FLOAT---14个字节
40 30 31 41 38 30 30 36 34 30 34 37 45 0D--寄存器选择X100---FLOAT
字头-地址模式-数据---地址--字节-异或值
组态王向地址是1的单片机写入4byte数据组---------------89-----------------22个字节
40 30 31 35 39 30 30 30 41 30 34 30 37 43 37 46 41 45 31 37 38 0D--寄存器选择X10---FLOAT--数据是99.99 40 30 31 23 23 30 31 0D
40 30 31 35 39 30 30 36 34 30 34 31 31 38 32 33 35 30 30 30 37 0D--寄存器选择X100---FLOAT--数据是66666 40 30 31 23 23 30 31 0D
40 30 31 41 34 30 30 36 34 30 32 37 34 0D---SHORT读
40 30 31 41 34 30 30 36 34 30 32 37 34 0D
40 30 31 41 34 30 30 36 34 30 32 37 34 0D---USHORT读
40 30 31 41 34 30 30 36 34 30 32 37 34 0D
40 30 31 32 30 30 30 30 30 30 31 30 32 0D
40 30 31 32 30 30 30 30 30 30 31 30 32 0D
40 30 31 30 31 36 34 30 32 0D
40 30 31 39 30 30 30 30 30 30 31 30 39 0D
40 30 31 30 31 36 34 30 32 0D
40 30 31 39 32 30 30 30 30 30 31 30 42 0D
40 30 31 39 30 30 30 30 30 30 31 30 39 0D
40 30 31 23 23 30 31 0D
单片机源程序如下:
- /***************写在前面*************************************************************************************
- 程序思路:组态王向单片机通讯总共就两条命令读命令和写命令
- 读命令共分三条,字节读和双字和浮点读三条命令
- 写命令也分三条,字节读和双字和浮点读三条命令
- 读时的三条命令的数据长度都一样都是14个ASSIC码
- 而且单片机回传的数据分别是10个ASSIC码和12个ASSIC码和16个ASSIC码
- 40 30 31 30 32 30 30 30 31 0D 数据是1个字节2个ASSIC码
- [字头-地-址-字节--数-据-异或值-字尾]
- 40 30 31 30 32 30 30 30 31 30--30 0D 数据是2个字节4个ASSIC码
- [字头-地-址-字节--数-------据-异或值-字尾]
- 40 30 31 30 32 30 30 30 30 30-30-30-30----31-30--0D 数据是4个字节8个ASSIC码
- [字头-地-址-字节--数-------------------据---异或值-字尾]
- 写时的命令组态王分别发送字节16个ASSIC到单片机,双字节是18个ASSIC和浮点22个2ASSIC码
- 单片机只需回答正确和不正确的俩条命令 40 30 31 23 23 30 31 0D
- 然后再把数据处理就可以了如果不理解请仔细阅读组态王与单片劫ASSIC通讯手册。
- 与组态王通讯时请注意选择的单片机晶震频率和波特率及效验否则无法通讯成功
- 本次测试组态王只支持19200波特率,再高的波特率没有成功,
- 不知道是何原因难道组态的原因吗?
- ** 功能描述: 接收组态王的数据
- **(组态王发送来的数据有读都是14个ASSIC,
- bite写16个ASSIC,
- word写18个ASSIC,
- FLOAT写22个ASSIC,
- **单片机回传----读单字节时正确回传10个个ASSIC,读双字节时正确回传12个个ASSIC,读浮点时正确回传16个个ASSIC,
- 读时不正确回传8个个ASSIC
- **单片机回传----写时正确回传 8个个ASSIC,
- 写时不正确回传8个个ASSIC
- //data_num=1byte;data_num=2word;data_num=4folat
-
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- ************************************************************************************************************/
- #include "kongview.h"
- //#define MODE1T //Timer clock mode, comment this line is 12T mode, uncomment is 1T mode
- #ifdef MODE1T
- #define T1MS (65536-(MAIN_Fosc/1000)) //1ms timer calculation method in 1T mode
- #else
- #define T1MS (65536-(MAIN_Fosc/12/1000)) //1ms timer calculation method in 12T mode
- #endif
- #define N 5 //ADC采样使用递推平均滤波算法,采样次数
- /*------------------选择波特率改CH1--------------------------------------------*/
- #define CH4 1200 //串口波特率
- #define CH2 2400 //串口波特率
- #define CH3 4800 //串口波特率
- #define CH5 9600 //串口波特率
- #define CH1 19200 //串口波特率
- #define CH0 115200 //串口波特率
- #if (CH1== 1200)
- #define BAUD CH1
- #elif (CH1== 2400)
- #define BAUD CH1
- #elif (CH1== 4800)
- #define BAUD CH1
- #elif (CH1== 9600)
- #define BAUD CH1
- #elif (CH1== 19200)
- #define BAUD CH1
- #elif (CH1== 115200)
- #define BAUD CH1
- #endif
- /*------------------选择校验改PARITYBIT---------------------------------------------*/
- #define NONE_PARITY 0 //无校验
- #define ODD_PARITY 1 //奇校验
- #define EVEN_PARITY 2 //偶校验
- #define MARK_PARITY 3 //标记校验
- #define SPACE_PARITY 4 //空白校验
- #define PARITYBIT EVEN_PARITY //定义校验位
- #define ReadMode 14 //根据组态王发送来的数据14个字节都是读
- #define WritMode1byte 16 //16个字节是写1bite
- #define WritMode2byte 18 //18个字节是写整数
- #define WritMode4byte 22 //22个字节是写浮点数
- /**********组态王读写标记固定在recbuf[3],recbuf[4]******************************************/
- #define TYPEReadB 160 //字节读
- #define TYPEReadB2 162 //打包字节读
- #define TYPEWrirB 81 //字节写
- #define TYPEWrirB2 83 //打包字节写
- #define TYPEReadW 164 //字读
- #define TYPEReadW2 166 //打包字读
- #define TYPEWritw 85 //字节写
- #define TYPEWritw2 87 //打包字写
- #define TYPEReadF 168 //双字读
- #define TYPEReadF2 170 //打包双字读
- #define TYPEWritF 89 //双字读
- #define TYPEWritF2 71 //打包双字读
- #define Control_MCUIO P1 //组态王要控制的IO
- unsigned char DateRitLen; //计算组态王传到单片机的数据格式是否匹配
- unsigned char ReceiveLen; //计算组态王传到单片机的字节长度
- /*************单片机向组态王回传的信息有***********************/
- #define TYPEReadOK 10 //读正确回传10字节
- #define TYPEReadER 8 //读错误回传8字节
- #define TYPEWritOK 8 //写正确回传8字节
- #define TYPEWritER 8 //写错误回传8字节
- #define Div(X) (X/10)
- #define ANL(X) (X%10)
- #define ASSICDEC(X) (((X<<4)&0XF0) + (X&0x0F)) //宏
- unsigned char xdata datBYTE[3]={ 0,
- 0,
- 0,
- };
- //unsigned int xdata datWORD[10];
- //unsigned long xdata datFOALT[10];
- unsigned char recbuf[22]={ 0x40, //字头---------组态王向单片机回读写的数据
- 0x30, //设备地址2
- 0x31, //设备地址1
- 0x30, //标志11111111 B(000001100)
- 0x31, //标志bit0= 0:读,bit0= 1:写 bit1= 0:不打包。
- 0, //数据地址
- 0, //数据地址
- 0, //数据地址
- 0, //数据地址
- 0, //数据字节数
- 0, //数据字节数
- 0, //数据
- 0, //数据
- 0, //数据 CR结束符号读写数据类型为字节为14个数据
- 0, //数据
- 0, //异或
- 0, //异或
- 0x0d, //CR结束符号读写数据类型为字为18个数据
- 0,
- 0x0d, //CR结束符号读写数据类型为浮点型为20个数据
- 0,
- 0X0D, //CR结束符号读写数据类型为浮点型为22个数据
- };
- unsigned char xdata sendbuf[16]={0x40, //字头---------单片机向组态王回复读一个BYTE数据
- 0x30, //设备地址
- 0x31, //设备地址
- 0x30, //标志bit0~bit7-bit0= 0:读,bit0= 1:写。bit1= 0:不打包。bit3bit2 = 00,数据类型为字节。
- 0x31, //标志bit3bit2 = 01,数据类型为字。1bit3bit2 = 1x,数据类型为浮点数
- 0X36, //数据字节数2
- 0X34, //数据字节数。
- 0X30, //异或
- 0X32, //异或
- 0x0D, //CR结束符号
- }; //sendbuf[1-2]本机地址位,多机修改此处
- unsigned char xdata Answer[8]={0x40, //字头---------单片机向组态王回复读一个BYTE数据 40 30 31 23 23 30 31 0d
- 0x30, //设备地址
- 0x31, //设备地址
- 0, //数据高位若正确回复23不正确回复2a
- 0, //数据低位若正确回复23不正确回复2a
- 0X30, //异或
- 0X31, //异或
- 0x0D, //CR结束符号
- };
- unsigned char count=0; //接收组态王的数据字节计数
- BIT flag=0; //单片机接收计算机字头正确标记
- BIT recok=0; //接收组态王的数据成功
- unsigned char Li=0; //动态显示用
- unsigned char SendNum; //组态王读单片机回传的字节数
- unsigned char Pv1; //数码管显示
- //定义一个指针
- /*------------------数码管脚定义------------------------------------------*/
- sbit Led_Bit_A = P3^7; //段码A段
- sbit Led_Bit_B = P2^1; //段码B段
- sbit Led_Bit_C = P2^2; //段码C段
- sbit Led_Bit_D = P2^3; //段码D段
- sbit Led_Bit_E = P2^4; //段码E段
- sbit Led_Bit_F = P2^5; //段码F段
- sbit Led_Bit_G = P2^6; //段码G段
- sbit Led_Bit_dip = P2^7; //小数点
- sbit COM1 = P3^6;//数码管个位位选为P3.7
- sbit COM2 = P3^5;//数码管十位位选为P3.6
- sbit COM3 = P3^4;//数码管百位位选为P3.5
- /*******************************************************************************************
- 三位数码管 LEDTYPE =1,共阳数码管 ;LEDTYPE =0,共阴数码管试 LED显示相关定义
- a
- |---|
- f |__g| b
- | |
- e |___| c
- d
- ** 作 者: 李文杰
- ** 日 期: 2017年11月28日
- ** 说 明:
- ______ ______ ______
- | | | | | |
- | | | | | |
- | 1 | | 2 | | 3 |
- | | | | | |
- |______| 3 |______| 2 |______| 1
- | | | | | |
- | dot | dot | dot
- | | |
- ShowCase[0] ShowCase[1] ShowCase[2]
- ********************************************************************************************************/
- #define LEDTYPE 0 //如果用共阴还是共阳数码管只要改变这里就行了
- #if LEDTYPE
- #define LED_TYPE 0xFF //定义LED类型, 0x00--共阴, 0xff--共阳
- #define LED_TYP2 0x00
- #else
- #define LED_TYPE 0x00 //定义LED类型, 0x00--共阴, 0xff--共阳
- #define LED_TYP2 0xFF
- #endif
- /*************************************************************************************************************/
- #define b_0000_0001 1
- #define b_0000_0010 2
- #define b_0000_0100 4
- #define b_0000_1000 8
- #define b_0001_0000 16
- #define b_0010_0000 32
- #define b_0100_0000 64
- #define b_1000_0000 128
- /*------------------------------------------------------------------------------------------------------------*/
- #define _a b_0000_0001
- #define _b b_0000_0010
- #define _c b_0000_0100
- #define _d b_0000_1000
- #define _e b_0001_0000
- #define _f b_0010_0000
- #define _g b_0100_0000
- #define _p b_1000_0000
- /**************************************************************************************************************/
- #define LED_0 LED_TYPE^(_a|_b|_c|_d| _e|_f)
- #define LED_1 LED_TYPE^(_b|_c)
- #define LED_2 LED_TYPE^(_a|_b|_g|_e|_d)
- #define LED_3 LED_TYPE^(_a|_b|_g|_c|_d)
- #define LED_4 LED_TYPE^(_f|_g|_b|_c)
- #define LED_5 LED_TYPE^(_a|_f|_g|_c|_d)
- #define LED_6 LED_TYPE^(_a|_f|_g|_c|_d|_e)
- #define LED_7 LED_TYPE^(_a|_b|_c)
- #define LED_8 LED_TYPE^(_a|_b|_c|_d|_e|_f|_g)
- #define LED_9 LED_TYPE^(_a|_b|_c|_d|_f|_g)
- #define LED_a LED_TYPE^(_a|_b|_c|_e|_f|_g)
- #define LED_H LED_TYPE^(_b|_c|_e|_f|_g)
- #define LED_V LED_TYPE^(_b|_c|_d|_e|_f)
- #define LED_e LED_TYPE^(_a|_d|_d|_e|_f|_g)
- #define LED_OF LED_TYP2^(_a|_b|_c|_d|_e|_f|_g|_p)
- #define LED_Y LED_TYPE^(_b|_c|_d|_f|_g)
- #define LED_U LED_TYPE^(_c|_d|_e)
- #define LED_L LED_TYPE^(_f|_e|_d)
- #define LED_P LED_TYPE^(_a|_b|_e|_f|_g)
- #define LED_I LED_TYPE^(_e|_f )
- #define LED_d LED_TYPE^(_b|_c |_d|_e|_g)
- #define LED_r LED_TYPE^(_e|_g)
- #define LED_T LED_TYPE^(_a|_e|_f)
- #define LED_b LED_TYPE^(_c|_d|_e|_f|_g)
- #define LED_c LED_TYPE^(_a|_d|_e|_f)
- #define LED_K LED_TYPE^(_b|_d|_e|_f|_g)
- #define LED_S LED_TYPE^(_a|_c|_d|_f|_g)
- #define LED_O_1 LED_TYPE^(_a|_b|_f|_g) //上层'o'
- #define LED_O_2 LED_TYPE^(_c|_d|_e|_g) //下层'o'
- #define LED_Z LED_TYPE^(_a|_b|_e|_d)
- #define LED_f LED_TYPE^(_a|_e|_f|_g)
- #define LED_n LED_TYPE^(_c|_e|_g)
- #define LED_fu LED_TYPE^(_g)
- #define LED_DROP LED_TYPE^(_p)
- /*------------------数码管段码表----------------------------------------*/
- unsigned char code table[18]= { //需要显示的段选码
- LED_0, //0
- LED_1, //1
- LED_2, //2
- LED_3, //3
- LED_4, //4
- LED_5, //5
- LED_6, //6
- LED_7, //7
- LED_8, //8
- LED_9, //9
- LED_a,
- LED_b,
- LED_c,
- LED_d,
- LED_e,
- LED_f,
- LED_fu,
- LED_P,
- };
- /********************************************************************************************************
- ** 函数名称: void digital_CODE()
- ** 功能描述: 驱动数码管位码
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- *********************************************************************************************************/
- void digital_CODE(unsigned char ch) //led段码发送函数开始
- { ACC=ch;
- COM1=COM2=COM3=1;
- Led_Bit_A = ACC0;
- Led_Bit_B = ACC1;
- Led_Bit_C = ACC2;
- Led_Bit_D = ACC3;
- Led_Bit_E = ACC4;
- Led_Bit_F = ACC5;
- Led_Bit_G = ACC6;
- Led_Bit_dip= ACC7;
- }
- /********************************************************************************************************
- ** 函数名称: void uartsends()
- ** 功能描述: 串口发送数据串
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- *********************************************************************************************************/
- void uartsends(unsigned char buff[],uchar len)
- { unsigned char i;
- for(i=0;i<len;i++)
- { SBUF=buff[i];
- while(!TI);
- TI=0;
- }
- }
- /*************把组态王中的ASSIC码转换成16进制两个ASSIC组成1BYTE16进制码与常规的ASSIC转法不一样*********/
- unsigned char CharToHex(unsigned char bHex)
- { unsigned char temp;
- if( bHex>0x40)
- temp=(bHex-0x37)&0x0f; //只取低四位00001111----bit0-bit1--bit2--bit3
- else
- temp=(bHex-0x30)&0x0f; //只取低四位00001111----bit0-bit1--bit2--bit3
- return temp;
- }
- unsigned int CharToHexn(unsigned char bHex)
- { unsigned char temp;
- if( bHex>0x40)
- temp=(bHex-0x37)&0x0f; //只取低四位00001111----bit0-bit1--bit2--bit3
- else
- temp=(bHex-0x30)&0x0f; //只取低四位00001111----bit0-bit1--bit2--bit3
- return temp;
- }
- unsigned int CharToHexnall(unsigned char *redata,unsigned char number)
- { unsigned int temp,i;
- if(number==1) {
- for(i=0;i<2;i++) {
- temp=CharToHexn(*redata);
- temp=temp<<4|temp;
- redata++;
- }
- // temp=(temp<<4+temp1);
-
- }
- if(number==2) {
- if( temp>0x40)
- temp=(temp-0x37)&0x0f; //只取低四位00001111----bit0-bit1--bit2--bit3
- else
- temp=(temp-0x30)&0x0f;} //只取低四位00001111----bit0-bit1--bit2--bit3
- if(number==4) {
- if( temp>0x40)
- temp=(temp-0x37)&0x0f; //只取低四位00001111----bit0-bit1--bit2--bit3
- else
- temp=(temp-0x30)&0x0f;} //只取低四位00001111----bit0-bit1--bit2--bit3
- return temp;
- }
- /********************************************************************************************************
- ** 函数名称: data_num(void)
- ** 功能描述: 判断发送和写的字节数
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- *********************************************************************************************************/
- unsigned char data_num(void) //data_num=1byte;data_num=2word;data_num=4folat
- {
- unsigned char temp;
- temp=CharToHex(recbuf[9]);
- temp=(temp<<4)&0XF0;
- temp+=CharToHex(recbuf[10]);
- return temp;
- }
- /****************根据接收到的信息处理回传的信息**************************/
- void Information_processing(void)
- {
- unsigned char ctmp1=0,ctmp2=0,xordat=0,i;
- unsigned int send_temp=0;
- sendbuf[1]=recbuf[1]; //地址同步
- sendbuf[2]=recbuf[2];
- sendbuf[3]=recbuf[9]; //字节数同步
- sendbuf[4]=recbuf[10];
- /********读1字节数************************************/
- if(data_num()==1) {
- datBYTE[0]=Control_MCUIO; //组态王读单片机时只要把P0,P1,P2的数据放到datBYTE[0]中就可以读出MCUIO的状态
- ctmp1=(datBYTE[0]>>4)&0x0f;
- if(ctmp1>9) //把十六进制码转化成ASSIC码放入sendbuf[5]sendbuf[6]中以便发送
- sendbuf[5]=ctmp1%9+0x40;
- else
- sendbuf[5]=ctmp1+0x30;
- ctmp2=datBYTE[0]&0x0f; //把十六进制码转化成ASSIC码放入sendbuf[5]sendbuf[6]中以便发送
- if(ctmp2>9)
- sendbuf[6]=ctmp2%9+0x40;
- else
- sendbuf[6]=ctmp2+0x30;
- xordat=0;
- for(i=1;i<7;i++)
- xordat^=sendbuf[i]; //异或之和
- send_temp=xordat;
- ctmp1=(send_temp>>4)&0x0f;
- if(ctmp1>9) //异或高位
- sendbuf[7]=ctmp1%9+0x40;
- else
- sendbuf[7]=ctmp1+0x30;
- ctmp2=send_temp&0x0f;
- if(ctmp2>9) //异或低位
- sendbuf[8]=ctmp2%9+0x40;
- else
- sendbuf[8]=ctmp2+0x30;
- sendbuf[9]=0X0D;
- SendNum=10; //字节读回传10个数据
- uartsends(sendbuf,SendNum);
- }
- /********读2字节数************************************/
- //40 30 31 41 34 30 30 30 30 30 32 37 36 0D
- //40 30 31 30 32 30 30 36 34 30 33 0D
- if(data_num()==2) {
- sendbuf[5]=0X30; //00
- sendbuf[6]=0X30;
- sendbuf[7]=0X36; //120
- sendbuf[8]=0X34;
- xordat=0;
- for(i=1;i<9;i++) //异或之和8个数据
- xordat^=sendbuf[i];
- send_temp=xordat;
- ctmp1=(send_temp>>4)&0x0f;
- if(ctmp1>9) //异或高位
- sendbuf[9]=ctmp1%9+0x40;
- else sendbuf[9]=ctmp1+0x30;
- ctmp2=send_temp&0x0f;
- if(ctmp2>9) //异或低位
- sendbuf[10]=ctmp2%9+0x40;
- else sendbuf[10]=ctmp2+0x30;
- sendbuf[11]=0x0D;
- uartsends(sendbuf,12); //字节读回传12个数据
- }
- /********读4字节数************************************/
- if(data_num()==4) {
- sendbuf[5] =0X30; //字节数同步
- sendbuf[6] =0X30;
- sendbuf[7] =0X46; //字节数同步
- sendbuf[8] =0X46;
- sendbuf[9] =0X46; //字节数同步
- sendbuf[10]=0X46;
- sendbuf[11]=0X30; //字节数同步
- sendbuf[12]=0X30;
- xordat=0;
- for(i=1;i<13;i++) //异或之和12个数据
- xordat^=sendbuf[i];
- send_temp=xordat;
- ctmp1=(send_temp>>4)&0x0f;
- if(ctmp1>9)
- sendbuf[13]=ctmp1%9+0x40;
- else
- sendbuf[13]=ctmp1+0x30; //异或高位
- ctmp2=send_temp&0x0f;
- if(ctmp2>9)
- sendbuf[14]=ctmp2%9+0x40; //异或低位
- else
- sendbuf[14]=ctmp2+0x30; //异或低位
- sendbuf[15]=0X0D;
- SendNum=16; //字节读回传16个数据
- uartsends(sendbuf,SendNum);
- }
- }
- /****************组态王写字节数据处理**************************/
- // 40 30 31 35 31 30 30 30 30 30 31 30 31 30 35 0D
- // 40 30 31 35 31 30 30 30 30 30 31 43 38 37 46 0D--寄存器选择X0---BYTE--数据是200
- //字头-地址--模 式-数据-- 地址-字-节--数-值--异-或
- //--0 1 2 3 4 5--6--7--8 9 10 11 12 13 14 15
- void writeMCU()
- { unsigned char temp; //组态王写入MCU的数据值
- unsigned int tempAddr; //组态王写入MCU的地址值X0,X1--X200
- temp=CharToHex(recbuf[11]);
- temp=(temp<<4)&0XF0;
- temp+=CharToHex(recbuf[12]);
- datBYTE[0]=temp; //写入单片机的内存
- Control_MCUIO=datBYTE[0]; //单片机的IO等于组态王写过来的数据组态王写入MCU的数据值
- tempAddr=CharToHex(recbuf[5]);
- tempAddr=(tempAddr<<4)&0XF0;
- tempAddr+=CharToHex(recbuf[6]);
- tempAddr=(tempAddr<<4)&0XF0;
- tempAddr+=CharToHex(recbuf[7]);
- tempAddr=(tempAddr<<4)&0XF0;
- tempAddr+=CharToHex(recbuf[8]);
- // Pv1=tempAddr; //写入单片机的地址变量
- }
- /********************************************************************************************************
- ** 函数名称: write_inform(unsigned char dat)
- ** 功能描述: 单片机向计算机组态王发送8字节数据
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- *********************************************************************************************************/
- void write_inform(unsigned char dat)
- {
- unsigned char xordat,i,ctmp1,ctmp2,send_temp;
- Answer[1]=recbuf[1];
- Answer[2]=recbuf[2];
- Answer[3]=dat; //数据高位若正确回复23不正确回复2a
- Answer[4]=dat; //数据低位若正确回复23不正确回复2a
- xordat=0;
- for(i=1;i<5;i++)
- xordat^=Answer[i];
- send_temp=xordat;
- ctmp1=(send_temp>>4)&0x0f;
- if(ctmp1>9)
- Answer[5]=ctmp1%9+0x40;
- else
- Answer[5]=ctmp1+0x30; //异或高位
- ctmp2=send_temp&0x0f;
- if(ctmp2>9)
- Answer[6]=ctmp2%9+0x40; //异或低位
- else
- Answer[6]=ctmp2+0x30; //异或低位
- uartsends(Answer,8);
- }
- /********************************************************************************************************
- ** 函数名称: AddrInit()
- ** 功能描述: 地址数据初始化
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- *********************************************************************************************************/
- /*void AddrInit(void)
- {
- unsigned char ctmp;
- ctmp=(MyAddr>>4);
- if(ctmp>9)
- {
- sendbuf [1]=0x40+ctmp%9;
- sendbuf1[1]=0x40+ctmp%9;
- }
- else
- {
- sendbuf [1]=ctmp+0x30;
- sendbuf1[1]=ctmp+0x30;
- }
- ctmp=MyAddr&0x0f;
- if(ctmp>9)
- {
- sendbuf [2]=0x40+ctmp%9;
- sendbuf1[2]=0x40+ctmp%9;
- }
- else
- {
- sendbuf [2]=ctmp+0x30;
- sendbuf1[2]=ctmp+0x30;
- }
- }
- /********************************************************************************************************
- ** 函数名称: void Write_byte()
- ** 功能描述: 转换组态王发送的字节到dat区
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- *********************************************************************************************************/
- void Sendkingviow()
- { switch(ReceiveLen)
- {
- /*组态王读数据单片机回传*/
- case 14:
- Information_processing();
- ;break;
- /*组态王写字节数据单片机回传40 30 31 23 23 30 31 0d不正确回传40 30 31 2A 2A 30 31 0d*/
- case 16:
- write_inform('#');
- writeMCU();
- ;break;
- /*组态王写双字节数据单片机回传*/
- case 18:
- write_inform('#');
- ;break;
- /*组态王写四字节数据单片机回传*/
- case 22:
- write_inform('#');
- ;break;
- default://write_inform('*');
- write_inform('*');
- break;
- }
- }
- /*float C4toD(char * c)
- {
- BYTE Hd[30], Jiema[30];
- float DTc[30];
- float Decimal = 0;
- float returnflo = 0;
- BOOL ShuFU = FALSE, JieFU = FALSE;
- memset(Hd, 0, sizeof(Hd));
- memset(Jiema, 0, sizeof(Jiema));
- memset(DTc, 0, sizeof(DTc));
- if((c[7] > 0x40) && (c[7] < 0x47))
- Hd[7] = ((c[7] - 0x37) & 0x0f);
- else if((c[7] > 0x60) && (c[7] < 0x67))
- Hd[7] = ((c[7] - 0x57) & 0x0f);
- else
- Hd[7] = ((c[7] - 0x30) & 0x0f);
- if((c[6] > 0x40) && (c[6] < 0x47))
- Hd[6] = ((c[6] - 0x37) & 0x0f);
- else if((c[6] > 0x60) && (c[6] < 0x67))
- Hd[6] = ((c[6] - 0x57) & 0x0f);
- else
- Hd[6] = ((c[6] - 0x30) & 0x0f);
- DTc[2] = (float)(((float)(Hd[6] * 16.0) + (float)(Hd[7])) / 256.0);
- if((c[5] > 0x40) && (c[5] < 0x47))
- Hd[5] = ((c[5] - 0x37) & 0x0f);
- else if((c[5] > 0x60) && (c[5] < 0x67))
- Hd[5] = ((c[5] - 0x57) & 0x0f);
- else
- Hd[5] = ((c[5] - 0x30) & 0x0f);
- if((c[4] > 0x40) && (c[4] < 0x47))
- Hd[4] = ((c[4] - 0x37) & 0x0f);
- else if((c[4] > 0x60) && (c[4] < 0x67))
- Hd[4] = ((c[4] - 0x57) & 0x0f);
- else
- Hd[4] = ((c[4] - 0x30) & 0x0f);
- DTc[1] = (float)((((float)(Hd[4] * 16.0) + (float)Hd[5]) + DTc[2]) / 256.0);
- if((c[3] > 0x40) && (c[3] < 0x47))
- Hd[3] = ((c[3] - 0x37) & 0x0f);
- else if((c[3] > 0x60) && (c[3] < 0x67))
- Hd[3] = ((c[3] - 0x57) & 0x0f);
- else
- Hd[3] = ((c[3] - 0x30) & 0x0f);
- if((c[2] > 0x40) && (c[2] < 0x47))
- Hd[2] = ((c[2] - 0x37) & 0x0f);
- else if((c[2] > 0x60) && (c[2] < 0x67))
- Hd[2] = ((c[2] - 0x57) & 0x0f);
- else
- Hd[2] = ((c[2] - 0x30) & 0x0f);
- Decimal = (float)(((float)(Hd[2] * 16) + (float)(Hd[3]) + DTc[1])/ 256.0);
- if((c[1] > 0x40) && (c[1] < 0x47))
- Jiema[1] = ((c[1] - 0x37) & 0x0f);
- else if((c[1] > 0x60) && (c[1] < 0x67))
- Jiema[1] = ((c[1] - 0x57) & 0x0f);
- else
- Jiema[1] = ((c[1] - 0x30) & 0x0f);
- if((c[0] > 0x40) && (c[0] < 0x47))
- Jiema[0] = ((c[0] - 0x37) & 0x0f);
- else if((c[0] > 0x60) && (c[0] < 0x67))
- Jiema[0] = ((c[0] - 0x57) & 0x0f);
- else
- Jiema[0] = ((c[0] - 0x30) & 0x0f);
- ShuFU = ((Jiema[0] & 0x08) >> 3) > 0;
- JieFU = ((Jiema[0] & 0x04) >> 2) > 0;
- Jiema[2] = (Jiema[0] & 0x03) * 16 + Jiema[1];
-
- if(JieFU)
- returnflo = (float)pow(2, (-1) * Jiema[2]) * Decimal;
- else
- returnflo = (float)pow(2, Jiema[2]) * Decimal;
- if(ShuFU)
- returnflo = (-1) * returnflo;
- return returnflo;
- } *******************************************/
- /********************************************************************************************************
- ** 函数名称: serial_init()
- ** 功能描述: 串口1初始化函数
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- *********************************************************************************************************/
- void serial_init()
- {
- /*****************AT89C52单片机定时器1做波特率发生器***************************/
- /*
- SCON=0x50;
- TMOD=0X20;
- TH1=0xfd;
- TL1=0xfd;
- TR1=1; */
- /*****************STC15F2K60S2定时器1做波特率发生器***************************/
- /* PCON &= 0x7F; //波特率不倍速
- SCON = 0x50; //8位数据,可变波特率
- AUXR |= 0x40; //定时器1时钟为Fosc,即1T
- AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
- TMOD &= 0x0F; //清除定时器1模式位
- TMOD |= 0x21; //设定定时器1为8位自动重装方式
- #if (CH1== 9600)
- TL1 = 0xdc; //设定定时初值
- TH1 = 0xdc; //设定定时器重装值 0xdc
- #elif (CH1== 19200)
- TL1 = 0xEE; //设定定时初值
- TH1 = 0xEE; //设定定时器重装值
- #endif
- ET1 = 0; //禁止定时器1中断
- TR1 = 1; //启动定时器1
- /*****************STC15F2K60S2定时器2做波特率发生器**************************/
- T2L = (65536 - (MAIN_Fosc/4/BAUD)); //设置波特率重装值
- T2H = (65536 - (MAIN_Fosc/4/BAUD))>>8;
- AUXR = 0x14; //T2为1T模式, 并启动定时器2
- AUXR |= 0x01; //选择定时器2为串口1的波特率发生器
- #if (PARITYBIT == NONE_PARITY)
- SCON = 0X50; //8位可变波特率
- #elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
- SCON = 0XDA; //9位可变波特率,校验位初始为1
- #elif (PARITYBIT == SPACE_PARITY)
- SCON = 0XD2; //9位可变波特率,校验位初始为0
- #endif
- ES = 1; //使能串口1中断
- EA = 1; //使能总中断
- }
- /********************************************************************************************************
- ** 函数名称: void main()
- ** 功能描述: 主函数
- ** 创 建 者: 李文杰
- ** 创建时间: 2017-11-28 3:48
- ** 版 本: v1.0.0
- *********************************************************************************************************/
- void main (void)//主函数
- { TH0=T1MS>>8; //1MS
- TL0=T1MS;
- ET0=1;
- TR0=1;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
组态王单片机通讯1.0.rar
(2.47 MB, 下载次数: 156)
|