原创 AVR单片机开发-单片机与PLC通信

2014-8-7 23:51 1369 14 14 分类: MCU/ 嵌入式

 

在我们的开发中,要给PLC配显示设备我们首先想到的是触摸屏。但是我们仅仅要显示某个寄存器的数值时,用触摸屏是不是有点浪费?!这时我们采用一片单片机+一只数码管是不是性价比更高些。

      单片机和PLC通信我们要遵循一定的协议,如:松下(Panasonic)PLC的MEWTOCO协议、欧姆龙(OMRON)PLC的HOSTLINK协议、三菱(MITSUBISHI)PLC的CCLINK协议、西门子(SIEMENS)PLC的UUS协议以及通用的Modbus协议。这些协议可以方便的和PLC之间通信,而且不用编写PLC程序,由PLC自行完成。

     以下是基于于行科技开发的DMS64单片机控制板编写的单片机与松下PLC的通信程序,仅供设计参考。

/*------------MEWTOCOL.h---------------*/

#ifndef MEWTOCOL_H
#define MEWTOCOL_H
 
#include"UART_Init.h"
 
#define StartChar '%'
#define EndChar   '\r'
 
void inttoasc(unsigned long _data,unsigned char *p);
unsigned char asciitohex(unsigned char _ascii);
unsigned char dectohex(unsigned char _dec);
void MTXORCheck(unsigned char *checkresult,unsigned char *checkdata,unsigned char _length); //异或求和
unsigned char MTCheck(); //接收数据有效性检查
unsigned char MTRCS(unsigned char _code ,unsigned int _address);//读取单触点状态[X,Y,R,L]
unsigned char MTWCS(unsigned char _code ,unsigned int _address,unsigned char _staus);//写入单触点状态[Y,R,L]
unsigned char MTRD(unsigned int *p,unsigned char _code ,unsigned long _address,unsigned char _length); //读取寄存器[D,L,F]
unsigned char MTWD(unsigned int *p,unsigned char _code ,unsigned long _address,unsigned char _length); //写寄存器[D,L,F]
 
#endif
/*---------------MEWTOCOL.h-----------------*/
#include"MEWTOCOL.h"
#include"AllHardFile.h"
#include"yhdelay.h"
unsigned char Maddress = 0x01;
void inttoasc(unsigned long _data,unsigned char *p)
{
    unsigned char data[5];
unsigned char i;
for(i=0;i<5;i++)
 {
    data = (unsigned char)(_data % 10) + '0';
_data = _data /10;
 }
    for(i=0;i<5;i++)
 {
    *p = data[4-i];
p++;
 }
}
unsigned char asciitohex(unsigned char _ascii)
{
    unsigned char _hex = 0;
    switch(_ascii)
 {
     case 0x30:
   _hex = 0x0;
break;
     case 0x31:
   _hex = 0x1;
break;
     case 0x32:
   _hex = 0x2;
break;
     case 0x33:
   _hex = 0x3;
break;
     case 0x34:
   _hex = 0x4;
break;
     case 0x35:
   _hex = 0x5;
break;
     case 0x36:
   _hex = 0x6;
break;
     case 0x37:
   _hex = 0x7;
break;
     case 0x38:
   _hex = 0x8;
break;
     case 0x39:
   _hex = 0x9;
break;
     case 0x41:
   _hex = 0xA;
break;
     case 0x42:
   _hex = 0xB;
break;
     case 0x43:
   _hex = 0xC;
break;
     case 0x44:
   _hex = 0xD;
break;
     case 0x45:
   _hex = 0xE;
break;
     case 0x46:
   _hex = 0xF;
break;
 
 }
    return _hex;
}
unsigned char dectohex(unsigned char _dec)
{
    unsigned char hex;
hex = _dec + '0';
if(hex>0x39)
  hex = hex + 0x7;
    return hex;
}
void MTXORCheck(unsigned char *checkresult,unsigned char *checkdata,unsigned char _length) //接收数据有效性检查
{
    unsigned char i;
unsigned char xorsum = 0;
for(i=0;i<_length;i++)
  {
     xorsum = xorsum ^(*checkdata);
 checkdata++;
  }
    *checkresult = dectohex(xorsum/16);
checkresult++;
*checkresult = dectohex(xorsum%16);
}
unsigned char MTCheck() //接收数据有效性检查
{
   unsigned char xorsum[2];
   unsigned char errcode = 0x00;
   unsigned char address = 0;
   MTXORCheck(xorsum,rxbuf,rxcount-3);
   if((xorsum[0]==rxbuf[rxcount-3])&(xorsum[1]==rxbuf[rxcount-2])) // 异或求和 校验
     {
   address = asciitohex(rxbuf[1]);
address = address<<4;
address |= asciitohex(rxbuf[2]);
   if(address==Maddress)  // 地址校验
  {
     if(rxbuf[3]=='$')  // 返回数据正确/错误代码校验
    errcode = 0xFF;
              if(rxbuf[3]=='!')
    {
    errcode = asciitohex(rxbuf[4]);
errcode = errcode<<4;
errcode |= asciitohex(rxbuf[5]);
}
  }
}
   return errcode;
}
unsigned char MTRCS(unsigned char _code ,unsigned int _address)
{
    unsigned int address;
unsigned char xorsum[2];
unsigned char rxendi;
unsigned char isnormal;
    txbuf[0] = StartChar;
txbuf[1] = '0';
txbuf[2] = '1';
txbuf[3] = '#';
txbuf[4] = 'R';
txbuf[5] = 'C';
txbuf[6] = 'S';
txbuf[7] =  _code;
address = _address>>4;
txbuf[8] = (address/100) + '0';
address = address % 100;
txbuf[9] = address/10 + '0';
txbuf[10] = address%10 + '0';
txbuf[11] = dectohex((unsigned char)(_address&0x000F));
//txbuf[12] = _staus + '0';
MTXORCheck(xorsum,txbuf,12);
txbuf[12] = xorsum[0];
txbuf[13] = xorsum[1];
txbuf[14] = EndChar;
Uart0_Send(txbuf,15);
delay_ms(50);
rxendi = 0;  
while((rxendi<100))// 接收超时处理
  {
     
     if(rxstaus==rxend)
   {
   rxendi = 101;
}
          else
   {
   delay_ms(50);
rxendi++;
}
  }
    rxstaus = rxwait;
    isnormal = MTCheck();
if(isnormal==0xFF)
  return rxbuf[6];
    else
  return isnormal;
}
unsigned char MTWCS(unsigned char _code ,unsigned int _address,unsigned char _staus)
{
    unsigned int address;
unsigned char xorsum[2];
unsigned char rxendi;
unsigned char isnormal;
    txbuf[0] = StartChar;
txbuf[1] = '0';
txbuf[2] = '1';
txbuf[3] = '#';
txbuf[4] = 'W';
txbuf[5] = 'C';
txbuf[6] = 'S';
txbuf[7] =  _code;
address = _address>>4;
txbuf[8] = (address/100) + '0';
address = address % 100;
txbuf[9] = address/10 + '0';
txbuf[10] = address%10 + '0';
txbuf[11] = dectohex((unsigned char)(_address&0x000F));
txbuf[12] = _staus + '0';
MTXORCheck(xorsum,txbuf,13);
txbuf[13] = xorsum[0];
txbuf[14] = xorsum[1];
txbuf[15] = EndChar;
Uart0_Send(txbuf,16);
delay_ms(50);
rxendi = 0;  
while((rxendi<100))// 接收超时处理
  {
     
     if(rxstaus==rxend)
   {
   rxendi = 101;
}
          else
   {
   delay_ms(50);
rxendi++;
}
  }
    rxstaus = rxwait;
    isnormal = MTCheck();
return isnormal;
}
unsigned char MTRD(unsigned int *p,unsigned char _code ,unsigned long _address,unsigned char _length)
{
    unsigned char add[5];
unsigned char xorsum[2];
unsigned int rxdata;
unsigned char i;
unsigned char isnormal;
unsigned char base=0;
txbuf[0] = StartChar;
txbuf[1] = '0';
txbuf[2] = '1';
txbuf[3] = '#';
txbuf[4] = 'R';
txbuf[5] = 'D';
txbuf[6] =  _code;
inttoasc(_address,add);
    txbuf[7] = add[0];
txbuf[8] = add[1];
txbuf[9] = add[2];
txbuf[10] = add[3];
txbuf[11] = add[4];
    inttoasc((_address+_length-1),add);
    txbuf[12] = add[0];
txbuf[13] = add[1];
txbuf[14] = add[2];
txbuf[15] = add[3];
txbuf[16] = add[4];
MTXORCheck(xorsum,txbuf,17);
txbuf[17] = xorsum[0];
txbuf[18] = xorsum[1];
txbuf[19] = EndChar;
    Uart0_Send(txbuf,20);
    delay_ms(50);
i = 0;  
while((i<100))// 接收超时处理
  {
     
     if(rxstaus==rxend)
   {
   i = 101;
}
          else
   {
   delay_ms(50);
i++;
}
  }
    rxstaus = rxwait;
    isnormal = MTCheck();
    if(isnormal==0xFF)//(isnormal)
  {
     for(i=0;i<_length;i++)
   {
  base = i*4 + 6;
  rxdata = asciitohex(rxbuf[base+2]);
  rxdata = rxdata <<4; 
  rxdata |= asciitohex(rxbuf[base+3]);
  rxdata = rxdata <<4;  
  rxdata |= asciitohex(rxbuf[base+0]);
  rxdata = rxdata <<4;
  rxdata |= asciitohex(rxbuf[base+1]);
  //p = p + i;
  *(p+i) = rxdata;
}
  }
    else
 {
     for(i=0;i<_length;i++)
   {
  *(p+i) = 0;
}
 }
    return isnormal;
 
}
unsigned char MTWD(unsigned int *p,unsigned char _code ,unsigned long _address,unsigned char _length)
{
    unsigned char add[5];
    unsigned char data[4];
unsigned char xorsum[2];
unsigned int txdata;
unsigned char i;
unsigned char isnormal;
unsigned char base=0;
unsigned char arraylength;
txbuf[0] = StartChar;
txbuf[1] = '0';
txbuf[2] = '1';
txbuf[3] = '#';
txbuf[4] = 'W';
txbuf[5] = 'D';
txbuf[6] =  _code;
inttoasc(_address,add);
    txbuf[7] = add[0];
txbuf[8] = add[1];
txbuf[9] = add[2];
txbuf[10] = add[3];
txbuf[11] = add[4];
    inttoasc((_address+_length-1),add);
    txbuf[12] = add[0];
txbuf[13] = add[1];
txbuf[14] = add[2];
txbuf[15] = add[3];
txbuf[16] = add[4];
arraylength = 17;
for(i=0;i<_length;i++)
  {
       txdata = *(p+i); // 取值
data[0] = dectohex(txdata&0x000F); // 转换为HEX ASCII
txdata = txdata >>4;
data[1] = dectohex(txdata&0x000F);
txdata = txdata >>4;
data[2] = dectohex(txdata&0x000F);
txdata = txdata >>4;
data[3] = dectohex(txdata&0x000F);
txbuf[arraylength] = data[1]; // 存放到发送数组
arraylength++;
txbuf[arraylength] = data[0];
arraylength++;
txbuf[arraylength] = data[3];
arraylength++;
txbuf[arraylength] = data[2];
arraylength++;
  }
MTXORCheck(xorsum,txbuf,arraylength); // 异或和校验
txbuf[arraylength] = xorsum[0];
arraylength++;
txbuf[arraylength] = xorsum[1];
arraylength++;
txbuf[arraylength] = EndChar; // 结束符
arraylength++;
    Uart0_Send(txbuf,arraylength);
    delay_ms(50);
i = 0;  
while((i<100))// 接收超时处理
  {
     
     if(rxstaus==rxend)
   {
   i = 101;
}
          else
   {
   delay_ms(50);
i++;
}
  }
    rxstaus = rxwait;
    isnormal = MTCheck();
return isnormal;
}
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
14
关闭 站长推荐上一条 /3 下一条