#define XC3_24_V32
#include "\Documents and Settings\Administrator\My Documents\XC projects\lib\address.h"楼主最近还看过
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
发送接收缓冲区在这里,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