組態王與單片機通訊親測.
/*********************字節讀寫****************************************/
組態王向地址是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, 下載次數: 159)
2018-9-14 10:00 上傳
點擊文件名下載附件
|