看看基本完全用C语言构建的信捷程序,modbus测试 点击:2429 | 回复:14



linac

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:18帖 | 48回
  • 年度积分:0
  • 历史总积分:312
  • 注册:2002年7月21日
发表于:2012-05-24 09:35:56
楼主
#include <funcb.h>

#define XC3_24_V32

#include "\Documents and Settings\Administrator\My Documents\XC projects\lib\address.h"

// default variable on D element
#pragma SECTION bss Dunit
#pragma SECTION data Dunit

// set bit variabledeclareon M element
#define BIT_ALLOCATE_ADDR (__M_ADDRESS*8)

// only one freeport, and freeport at port2
#define FREEPORTSUM 1
#define FREEPORTFROM 1
#include "\Documents and Settings\Administrator\My Documents\XC projects\lib\modbus.h"

void init(void)
{
    crc16InitTable();
    freePortInit();
}

SETBITADDRESS(done, 0,  __S_ADDRESS)
_Bool done; // s0

SETBITADDRESS(sent, 1,  __S_ADDRESS)
_Bool sent; // s1

SETBITADDRESS(error, 0,  __Y_ADDRESS)
_Bool error; // y0

void doModbusTest(void)
{
    if (freePortTestIdle(0, 20)){
        //read first freeport,slave 1,50 input registers from address 0
        modbusRead(0, 1, 0, 1, 0, 50);
        sent = 1;
        return;
    }
   
    if (sent && freePortWaitFree(0)){
        done = 1;
        sent = 0;
        if (modbusCheckRead(0)){
            error = 1;
        }else {
            error = 0;
            //copy read in data to D7000...
            memcpy((void*)(__D_ADDRESS+7000*2),
                freePortInfos【0】.rcvBuf+MODBUSREADBUFOFFSET, 100);   
        }
    }
}

void ENTRY(WORD W, BIT B)
{
    if (FirstOn){
        init();
        done = 0;
        sent = 0;
    }
    freePortCalIdle();

    if (!done)
        doModbusTest();
}


楼主最近还看过



linac

  • 精华:0帖
  • 求助:0帖
  • 帖子:19帖 | 48回
  • 年度积分:0
  • 历史总积分:312
  • 注册:2002年7月21日
发表于:2012-05-24 09:56:45
1楼

 

 

 

 

linac

  • 精华:0帖
  • 求助:0帖
  • 帖子:19帖 | 48回
  • 年度积分:0
  • 历史总积分:312
  • 注册:2002年7月21日
发表于:2012-05-24 09:58:42
2楼
梯形图还是离不了,因为串口操作没有C语言接口

dusenmoon

  • 精华:0帖
  • 求助:4帖
  • 帖子:102帖 | 806回
  • 年度积分:11
  • 历史总积分:9309
  • 注册:2010年5月11日
发表于:2012-05-24 10:02:50
3楼

厉害!不是很明白,呵呵,我使用PLC的A  B 两个端子连接的两台PLC程序也写好了,好像通讯不上诶,我看的例子就是编程手册上的,能不能指点一下或者给我个例子程序啊,谢谢

miy_gongkong

  • 精华:0帖
  • 求助:2帖
  • 帖子:27帖 | 3065回
  • 年度积分:0
  • 历史总积分:12427
  • 注册:2008年9月18日
发表于:2012-05-24 12:38:51
4楼

没看太明白,发送,接收 缓冲区在哪里?

 

楼主能不能带注释 解释一下;

linac

  • 精华:0帖
  • 求助:0帖
  • 帖子:19帖 | 48回
  • 年度积分:0
  • 历史总积分:312
  • 注册:2002年7月21日
发表于:2012-05-24 12:51:44
5楼

modbus.h

#ifndef MODBUS_H
#define MODBUS_H

#include <funcb.h>
#include "freeport.h"
#include "crc16.h"

inline unsigned swap(unsigned in)
{
    return (in << 8) + (in>>8);
}

void memswap(unsigned *buf, unsigned size)
{
    for (; size != 0; --size)
        *(buf++) = swap(*buf);
}

void modbusStartSend(unsignedcharport)
{
    *(unsigned *)(freePortInfos【port】.sndBuf + freePortInfos【port】.sndLen)
        = crc16(freePortInfos【port】.sndBuf,
                freePortInfos【port】.sndLen, 0xffff);
    freePortInfos【port】.sndLen += 2;
    MBSClearBit(port + freePortFree);
    MBSSetBit(port + freePortSndOrd);
}

// return 0x100 for data integrity error
// return 0x101 for protocol level error
// return 0 = ok, 1~255 modbus error
unsigned modbusPublicCheckResult(unsignedcharport)
{
    unsigned _len;
    _len = PORTINBYTES(port + FREEPORTFROM);
    freePortInfos【port】.rcvLen = _len;
    if(!GETPORTNOTCOMPLETEFLAG(port + FREEPORTFROM)  // overrun
            || GETPORTERRORFLAG(port + FREEPORTFROM) // error indicated
            || _len < 2 // not a packet
            || crc16(freePortInfos【port】.rcvBuf, _len-2, 0xffff)
                != *(unsigned*)(freePortInfos【port】.rcvBuf + _len - 2)){ // crc error
        return 0x100; // data integrity error
    }else if (_len < 5 // too short packet
            || freePortInfos【port】.sndBuf【0】 != freePortInfos【port】.rcvBuf【0】 //address error
            || freePortInfos【port】.sndBuf【1】 != (freePortInfos【port】.rcvBuf【1】 & 0x7f)) { //function code not match
        return 0x101; // protocol level error
    }else if ((freePortInfos【port】.sndBuf【1】 | 0x80) == freePortInfos【port】.rcvBuf【1】) { // modbus error
        if (freePortInfos【port】.rcvBuf【2】)
            return freePortInfos【port】.rcvBuf【2】;
        else
            return 0x101;
    }
    return 0;
}

#define MODBUSREADBUFOFFSET 3

// fire modbus read action
// coil/holding: writable = 1,  read input discrete/register: writable = 0;
// read register: isreg = 1, read bit: isreg = 0;
// check freePortFree true if complete
void modbusRead(unsignedcharport, unsignedcharslave,
        unsignedcharwritable, unsignedcharisreg,
        unsigned address, unsigned count)
{
    freePortInfos【port】.sndLen = 6;
    freePortInfos【port】.sndBuf【0】 = slave;
    freePortInfos【port】.sndBuf【1】 = (char)(writable ? 0x01 : 0x02);
    if (isreg)
        freePortInfos【port】.sndBuf【1】 += 2;
    *(unsigned*)(freePortInfos【port】.sndBuf + 2) = swap(address);
    *(unsigned*)(freePortInfos【port】.sndBuf + 4) = swap(count);
    MBSSetBit(freePortTurnRcv + port);
    freePortInfos【port】.rcvLen = FREEPORTBUFSIZE;
    modbusStartSend(port);
}

unsigned modbusCheckRead(unsignedcharport)
{
    unsigned _count, _len;
    _Bool _isreg;
    unsigned _res = modbusPublicCheckResult(port);
    if (_res)
        return _res;

    _len = freePortInfos【port】.rcvLen;
    _count = swap(*(unsigned*)(freePortInfos【port】.sndBuf + 4));
    _isreg = (_Bool)(freePortInfos【port】.sndBuf【1】 > 2);
    if (freePortInfos【port】.rcvBuf【2】
            != _len - 5
        || (_isreg && _count << 1 != _len - 5)
            || (!_isreg && (_count + 7) >> 3 != _len - 5)){
        return 0x101;
    }else
        return 0;
}

#define MODBUSWRITEBUFOFFSET 7

// fire modbus write action
// read register: isreg = 1, read bit: isreg = 0;
// read freePortFree true if complete
unsignedcharmodbusWrite(unsignedcharport, unsignedcharslave,
        _Bool isreg, unsigned address, unsigned count)
{
    freePortInfos【port】.sndBuf【0】 = slave;
    *(unsigned*)(freePortInfos【port】.sndBuf + 2) = swap(address);
    *(unsigned*)(freePortInfos【port】.sndBuf + 4) = swap(count);
    if (isreg){
        freePortInfos【port】.sndBuf【1】 = 0x10;
        freePortInfos【port】.sndBuf【6】 = (char)(count << 1);
    }else {
        freePortInfos【port】.sndBuf【1】 = 0x0f;
        freePortInfos【port】.sndBuf【6】 = (char)((count + 7) >> 3);
    }
    freePortInfos【port】.sndLen = 7 + freePortInfos【port】.sndBuf【6】;
    if (slave){
        MBSSetBit(freePortTurnRcv + port);
        freePortInfos【port】.rcvLen = FREEPORTBUFSIZE;
    }
    modbusStartSend(port);
}

unsigned modbusCheckWrite(unsignedcharport)
{
    unsigned _res;
    if (!freePortInfos【port】.sndBuf【0】) //broadcast
        return 0;
    _res = modbusPublicCheckResult(port);
    if (_res)
        return _res;

    if (freePortInfos【port】.rcvLen != 8
        || *(unsigned*)(freePortInfos【port】.sndBuf + 2)
            != *(unsigned*)(freePortInfos【port】.rcvBuf + 2)
        || *(unsigned*)(freePortInfos【port】.sndBuf + 4)
            != *(unsigned*)(freePortInfos【port】.rcvBuf + 4)) {
        return 0x101;
    }else
        return 0;
}

#endif

 

linac

  • 精华:0帖
  • 求助:0帖
  • 帖子:19帖 | 48回
  • 年度积分:0
  • 历史总积分:312
  • 注册:2002年7月21日
发表于:2012-05-24 12:55:08
6楼

发送接收缓冲区在这里,freeport.h

#ifndef FREEPORT_H
#define FREEPORT_H

#include <funcb.h>
#include "address.h"

#define FREEPORTBUFSIZE 128

#ifndef FREEPORTSUM
#define FREEPORTSUM 1
#endif

#ifndef FREEPORTFROM
#define FREEPORTFROM 1
#endif

struct FreePortInfo{
    unsigned sndLen;
    unsignedcharsndBuf【FREEPORTBUFSIZE】;
    unsigned rcvLen;
    unsignedcharrcvBuf【FREEPORTBUFSIZE】;
    unsigned idleTime;
};

struct FreePortInfo freePortInfos【FREEPORTSUM】;

enum {
    freePortRstOrd = BIT_ALLOCATE_ADDR,
    freePortSndOrd = freePortRstOrd + FREEPORTSUM,
    freePortRcvOrd = freePortSndOrd + FREEPORTSUM,
    freePortFree = freePortRcvOrd + FREEPORTSUM,
    freePortTurnRcv = freePortFree + FREEPORTSUM,
};

#undef BIT_ALLOCATE_ADDR
#define BIT_ALLOCATE_ADDR (freePortTurnRcv + FREEPORTSUM)

unsignedcharfreePortTestIdle(unsignedcharport, unsigned freetime)
{
    return (unsigned char)(MBSReadBit(port + freePortFree)
        && freePortInfos【port】.idleTime >= freetime);
}

void freePortStartSend(unsignedcharport)
{
    MBSClearBit(port + freePortFree);
    MBSSetBit(port + freePortSndOrd);
}

// return true if complete
unsignedcharfreePortWaitFree(unsignedcharport)
{
    if (GETPORTSNDINGFLAG(port + FREEPORTFROM) || GETPORTRCVINGFLAG(port + FREEPORTFROM)){
        return false;
    }else if (MBSReadBit(port + freePortTurnRcv)){
        // turn from sending to receiving
        MBSSetBit(port + freePortRcvOrd);
        MBSClearBit(port + freePortTurnRcv);
        return false;
    }else {
        MBSSetBit(port + freePortFree);
        freePortInfos【port】.idleTime = 0;
        return true;
    }
}

void freePortRst(unsignedcharport)
{
    MBSClearBit(port + freePortSndOrd);
    MBSClearBit(port + freePortRcvOrd);
    MBSClearBit(port + freePortTurnRcv);
    MBSSetBit(port + freePortRstOrd);
    MBSSetBit(port + freePortFree);
}

void freePortInit(void)
{
    unsigned i;
    for (i=0; i<FREEPORTSUM; ++i){
        MBSClearBit(i + freePortSndOrd);
        MBSClearBit(i + freePortRcvOrd);
        MBSClearBit(i + freePortRstOrd);
        MBSClearBit(i + freePortTurnRcv);
        MBSSetBit(i + freePortFree);
        freePortInfos【i】.idleTime = 0;
    }
}

// call in each scan
void freePortCalIdle(void)
{
    unsigned i;
    for (i=0; i<FREEPORTSUM; ++i){
        if (MBSReadBit(i + freePortFree)){
            if (NowCycleMS >= (unsigned)(0xffff-freePortInfos【i】.idleTime))
                freePortInfos【i】.idleTime = 0xffff;
            else
                freePortInfos【i】.idleTime += NowCycleMS;
        }
    }
}

#endif

joy10000

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2010年11月05日
发表于:2013-10-15 12:33:50
7楼

厉害,看不懂!在找这方面的例子

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 455回
  • 年度积分:0
  • 历史总积分:1000
  • 注册:2008年1月09日
发表于:2013-10-18 00:49:41
8楼

没见到取数据地址的运算符&

华达科工

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 65回
  • 年度积分:0
  • 历史总积分:296
  • 注册:2015年11月11日
发表于:2016-04-30 18:56:35
9楼

不明觉厉,楼主是个高手。可惜没有注释。

wsjysjs

  • 精华:0帖
  • 求助:2帖
  • 帖子:4帖 | 18回
  • 年度积分:0
  • 历史总积分:9
  • 注册:2013年1月30日
发表于:2016-05-09 13:27:40
10楼

没有学过,所以感觉C语言有点难

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 28回
  • 年度积分:0
  • 历史总积分:131
  • 注册:2006年10月16日
发表于:2016-05-14 20:03:05
11楼

学习学习,辛苦楼主了。

xueweizhan

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 29回
  • 年度积分:0
  • 历史总积分:135
  • 注册:2005年6月08日
发表于:2016-06-03 12:40:37
12楼

怎么感觉没有比梯形图简单多少,是通信速度更快吗?

jeoge

  • 精华:0帖
  • 求助:0帖
  • 帖子:6帖 | 117回
  • 年度积分:1
  • 历史总积分:520
  • 注册:2009年12月22日
发表于:2019-01-28 16:18:27
13楼

谢谢分享!学习一下!

zhou101821

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 149回
  • 年度积分:0
  • 历史总积分:122
  • 注册:2013年8月23日
发表于:2019-03-28 18:38:34
14楼

多谢楼主分享!看看有没有用。


热门招聘
相关主题

官方公众号

智造工程师