www.pudn.com > TCPmodbushy.rar > modbus.c
/******************************************************************************
* Project : t_box
* Module Name : modbus.C
* CPU Type : C8051F340
*
* Description :
*
* History Author Version Comment
* 2002.12.22 HY V0.0 Original version
*
* Copyright (C) 2006 HY. All rights reserved.
******************************************************************************/
#include "o:\sysdef.h"
#include "modbus.h"
#define SndCommuBuf CommuBuffer
#define RcvCommuBuf CommuBuffer
uchar xdata CommuBuffer[ SndRcvBufferSize ];
uchar data RcvCommuLen = 0;
uchar data SndCommuLen;
uchar data TransmittedLen;
uchar idata Commbufflen;
bit data master_com_flag;
bit data master_sendcommdata_flag;
bit data shield_flag = NO;
/******************************************************************************
* 功能: 通信中断服务程序
* 说明:receive data
******************************************************************************/
void CommuRcv_INT( void )
{
master_sendcommdata_flag = NO;
//master_com_flag = NO;
/*only when wait receive,process receive data*/
if(FrameDataReceived == WAIT_RECEIVE)
{
uchar data tmp;
if( RxByte( &tmp ) )
{
if(RcvCommuLen == 0)
{
COM_LED = LED_ON;
if( (CurWorkState&MASTER_NOT_SLAVE) )
{
/*query station is or not in shield list*/
FLASHADDRH = 0x06;
FLASHADDRL = tmp;
if( FLASHDATA != 0 )
// if( ReadByteFromFlash( MASTER_SHIELD_ADDRESS + (uint)tmp ) != 0 )
shield_flag = YES;
else
shield_flag = NO;
}
}
RcvCommuBuf[ RcvCommuLen ] = tmp;
RcvCommuLen++;
if( RcvCommuLen >= SndRcvBufferSize )
RcvCommuLen = SndRcvBufferSize - 1;
Timer5ms = COMM_RECEIVE_OUTTIME;
}
else
{
if( !shield_flag )
FrameDataReceived = END_RECEIVE;
else
{
RcvCommuLen = 0;
Timer5ms = 0;
}
COM_LED = LED_OFF;
}
}
}
/******************************************************************************
* 功能: 通信中断服务程序
* 说明:send data
******************************************************************************/
void CommuSnd_INT( void )
{
if( TransmittedLen < SndCommuLen )
{
TxByte( SndCommuBuf[ TransmittedLen ] ); /* 将 CommuBuf[ TredLen ] 装入发送寄存器 */
TransmittedLen++;
COM_LED = LED_ON;
}
else
{
//FrameDataReceived = wait_receive;
RstRcvCommu();
COM_LED = LED_OFF; /*send end,begine receive*/
//TransmittedLen = 0;
}
}
/******************************************************************************
* 功能 :start send first data
******************************************************************************/
void StartTrans( void )
{
StartTx();
TransmittedLen = 1;
FrameDataReceived = WAIT_RECEIVE;
TxByte( SndCommuBuf[0]); /* 将 CommuBuf[ 0 ] 装入发送寄存器 */
}
/********************************************************************
********************************************************************/
void RSTsend(uchar len,uchar *pd)
{
/*send data on 485*/
uint tmp;
tmp = CRC(pd,pd+len);
pd +=len;
*pd = HIGH_BYTE( tmp );
pd ++;
*pd = LOW_BYTE( tmp );
SndCommuLen = len+2;
/* &SndCommuBuf[0] = pd;*/
StartTrans();
}
/******************************************************************************
* 功能:
******************************************************************************/
#pragma NOAREGS
void RstRcvCommu( void )
{
RcvCommuLen = 0;
Timer5ms = 0;
FrameDataReceived = WAIT_RECEIVE;
StartRx();
}
#pragma AREGS
/*****************************************************************************
check receive data(CRC)
******************************************************************************/
bit check_RCVdata()
{
if( ( RcvCommuLen > 2 )&&( RcvCommuLen <= SndRcvBufferSize ) )
{
if( ! ( ( RcvCommuBuf[ RcvCommuLen-2 ] == 0xA5 )&&( RcvCommuBuf[ RcvCommuLen-1 ] == 0x5A ) ) )
{
if( ! CRC_OK( RcvCommuBuf+RcvCommuLen-2, RcvCommuBuf, RcvCommuBuf+RcvCommuLen-2 ) )
{
#ifdef TESTDEBUG
test[11]++;
#endif
RstRcvCommu();
COM_ERROR_LED = LED_ON;
return(ERR);
}
}
COM_ERROR_LED = LED_OFF;
Commbufflen = RcvCommuLen;
return(OK);
}
else
{
#ifdef TESTDEBUG
test[0]++;
#endif
RstRcvCommu();
COM_ERROR_LED = LED_ON;
return(ERR);
}
}
/*********************************************************************************
analyse normal modbus data( master)
**********************************************************************************/
void MODBUS_analyse()
{
//uchar tmp;
//Commbufflen = RcvCommuLen;
check_station_reply();
if(RcvCommuBuf[0] == BROADCAST )
{
master_sendcommdata_flag = YES;
switch_message();
}
else
{
//tmp = RcvCommuBuf[0];
master_sendcommdata_flag = YES;
check_ip();
}
}
/********************************************************************************
check ip,if ip in list ,then send data ,if not ,then query ip
*********************************************************************************/
void check_ip(void)
{
if( station_IP(RcvCommuBuf[0]) != ERR )
{
switch_message(); /*this port's IP have get,send data use tcp*/
}
else
{
queryIP(RcvCommuBuf[0]); /*send broadcast to get the port's IP,*/
master_com_flag = YES;
}
}
/*******************************************************************************
switch normal modbus data to tcp modbus data
********************************************************************************/
void switch_message( void )
{
if( CurWorkState & MASTER_NOT_SLAVE )
{
if(comm_send_protocol == TCP_PROTOCOL)
{
if( IsHaveDataSending() != 0 ) //query data if or not finish sending
{
#ifdef TESTDEBUG
test[10]++;
#endif
return;
}
}
make_request_message((Commbufflen - 2), CommuBuffer);
master_com_flag = NO;
master_sendcommdata_flag = NO;
}
else
{
make_response_message((RcvCommuLen - 2), CommuBuffer);
}
}