推广 热搜: 非标自动化设备  北京*  自动化设备  机械  自动化  电子  印刷  深圳  公司  包装机 

组态王与单片机通讯

   日期:2018-09-15     浏览:94    评论:0    
核心提示:与组态王通讯时请注意选择的单片机晶震频率和波特率及效验否则无法通讯成功本次测试组态王只支持19200波特率,再高的波特率没有成功,不知道是何原因难道组态的原因吗?*******************************************
 与组态王通讯时请注意选择的单片机晶震频率和波特率及效验否则无法通讯成功
本次测试组态王只支持19200波特率,再高的波特率没有成功,不知道是何原因难道组态的原因吗?
************************************************************************************************************/
#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采样使用递推平均滤波算法,采样次数

#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

#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个字节是写浮点数

#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        //打包双字读
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 DEC2BCD(X) ((X/10)<<4 | (X%10))               //用于将十进制转成BCD码的宏
#define ASSICDEC(X) (((X<<4)&0xF0) + (X&0x0F))      //用于将BCD码转成十进制的宏
//data uchar x1 _at_ 0x40;      //在data区中定义字节变量x1,地址为0x40H,这里是uchar
//xdata uint x2 _at_ 0x2000;    //在xdata区中定义字变量x2,它的地址为0x2000H,这里是uint

//unsigned int xdata dat[10]={1,7,3,4,5,6,7,8,9,10}; 
unsigned char  xdata datBYTE[3]={ 5,
                                 6,
                                 7,

                                 };
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结束符号
                               };
                           //通讯尝试恢复命令(COMERROR),请求地址为0的一个BYTE数据


///40 30 31 32 30 30 30 30 30 30 31 30 32 0D
unsigned char count=0;
BIT flag=0; 
BIT recok=0;
//BIT startrec=0;
//BOOL Tempurekey;
unsigned char Li=0;   //动态显示用 
unsigned char SendNum;//组态王读单片机回传的字节数

//unsigned char Pv;
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

#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(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(unsigned char buff[],uchar len)
{   unsigned char i;
    for(i=0;i<len;i++)
    {   SBUF=buff;
        while(!TI);
        TI=0;
    }
}

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 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 write()

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];

if(data_num()==1) {
// sendbuf[5]=0x36;
// sendbuf[6]=0x34;
  ctmp1=(datBYTE[0]>>4)&0x0f;
  if(ctmp1>9)                //异或高位
  sendbuf[5]=ctmp1%9+0x40;
  else 
  sendbuf[5]=ctmp1+0x30;  
  ctmp2=datBYTE[0]&0x0f;
  if(ctmp2>9)                //异或低位
  sendbuf[6]=ctmp2%9+0x40;    
  else 
  sendbuf[6]=ctmp2+0x30;   
//  sendbuf[5]=datBYTE[0];
//  sendbuf[6]=datBYTE[0];


  xordat=0;
  for(i=1;i<7;i++)
  xordat^=sendbuf;
  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);
                   }

//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++)
xordat^=sendbuf;
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个数据
                   }         


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++)
xordat^=sendbuf;
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;
    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=datBYTE[0];
    Pv1=tempAddr;



}


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;
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);
}


                             case 14:    
                                          write();                                         
                                        ;break;
                          
                            case 16:   
                                        write_inform('#'); 
                                        writeMCU();
                                       ;break; 
                            
                            case 18:   
                                        write_inform('#'); 
                                       ;break;
                            
                            case 22:   
                                        write_inform('#');
                                       ;break;
                            default://write_inform('*');
                                        write_inform('*');
                                        break;    

                           } 
            

}



void serial_init()
{




    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;                        //使能总中断

}



//unsigned char  LED;

void main (void)//主函数
{ TH0=T1MS>>8;                                                  //1MS
  TL0=T1MS;
  ET0=1;
  TR0=1;
  serial_init();
  P1M0=B(00000000);//P1除P1.0,P1.1,P1.2为输入模式外均为正常模式
  P1M1=B(00000111);
  P1ASF=(00000111);//设置P1相应ADC转换的I/O口为ADC输入模式
  P2M0=B(11111111);//P2都是推挽模式
  P2M1=B(00000000);
  P3M0=B(11110000);//P3.4,P3.5,P3.6,P3.7为推挽模式,P3.2,P3.3为输入模式,其余正常模式
  P3M1=B(00000000);

  while(1){    
             if(recok) 
            {
               ET0=0;
               // Pv=ReceiveLen;
             //  Pv1=data_num();
               Sendkingviow();
               recok=0;
               ET0=1;    
             } 

  }

}

void recive(void) interrupt UART1_VECTOR
{  if(RI){
    if(SBUF==Start)         //如果接收到的是开头符号(ASCII码为0x40--"@  ")
    flag=1,ReceiveLen=0x00;
    if(flag==1)
    {   recbuf[count]=SBUF;
        count++;
        if(SBUF==ReceivEND)    //如果接收到的是结束符号(ASCII码为0x0D--"*")
        {   flag=0;
            ReceiveLen=count;
            count=0;
            recok=1;

          }
      } 
     RI=0;                 //从新开启串口中断     
  }
    if (TI)
    {
        TI = 0;                 //清除TI位
    //    busy = 0;               //清忙标志
    }
                                
}

void  timer0() interrupt TIMER0_VECTOR //显示中断;前两位调试用,
{    
TH0=T1MS>>8;                                                  //1MS
TL0=T1MS;
Li++;   
if(Li==2)///
{ digital_CODE(table[Pv1/100%10]);
COM3=0; COM1=1; 
}
if(Li==4)

  digital_CODE(table[Pv1/10%10]);
  COM3=1;  COM2=0;


if(Li==6)
{ digital_CODE(table[Pv1%10]);
  COM1=0;  COM2=1;

}
if(Li==8)
{

Li=0;


}
 
打赏
 
更多>同类工控
0相关评论

推荐图文
推荐工控
点击排行

网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报