|
楼主 |
发表于 2013-12-8 14:18:51
|
显示全部楼层
本帖最后由 oldbeginner 于 2013-12-8 19:32 编辑
void eMBPoll( void )
{
变量定义();
桢事件判断();
最小桢判断();
CRC判断();
地址判断();
执行功能码();
回复主机();
错误码判断();
报文发送();
}
*******************************
变量定义();
static UCHAR *ucMBFrame;
static UCHAR ucFunctionCode;
static USHORT usLength;
static eMBException eException;
eMBEventType eEvent;
UCHAR i;
USHORT usCRC16;
变量名字前面加uc的意思应该是,uchar变量,MB表示modbus,所以ucMBFrame表示 uchar变量的modbus帧,前面加*,是一个指针。
ucFunctionCode应该是uchar变量的功能码,应该类似散转函数,只不过freemodbus使用了大量#ifdef .....#endif等,各种标志位来回绕几圈,现在还不清楚怎么调用。
usLength应该是ushort变量的帧长度。
static eMBException eException(ModBusRTU.h);
需要查看eMBException的定义,
typedef enum
{
MB_EX_NONE = 0x00,
MB_EX_ILLEGAL_FUNCTION = 0x01,
MB_EX_ILLEGAL_DATA_ADDRESS = 0x02,
MB_EX_ILLEGAL_DATA_VALUE = 0x03,
MB_EX_SLAVE_DEVICE_FAILURE = 0x04,
MB_EX_ACKNOWLEDGE = 0x05,
MB_EX_SLAVE_BUSY = 0x06,
MB_EX_MEMORY_PARITY_ERROR = 0x08,
MB_EX_GATEWAY_PATH_FAILED = 0x0A,
MB_EX_GATEWAY_TGT_FAILED = 0x0B
} eMBException;
e表示enum,MB同上,Exception表示异常状况,共有10种异常状况,暂不展开(原程序也没有解释,估计不太重要)。
上面四种变量都是static型,只能用在ModBusRTU.c中。
然后,
eMBEventType eEvent;
查看定义(ModBusRTU.h),
typedef enum
{
EV_READY, /*!< Startup finished. */
EV_FRAME_RECEIVED, /*!< Frame received. */
EV_EXECUTE, /*!< Execute function. */
EV_FRAME_SENT /*!< Frame sent. */
} eMBEventType;
这个变量好理解,可以用来表示状态,共有4种状态。
UCHAR i;
执行功能代码时,要用到的循环变量。
USHORT usCRC16;
ushort类型的检验码。
在avr中 USHORT (unsigned short) 是16位的。
*****************************************************
桢事件判断();
if(xMBPortEventGet( &eEvent) == TRUE ){
if(eEvent == EV_FRAME_RECEIVED){
调用了函数
xMBPortEventGet
查看一下定义(ModBusPort.c),
//出队列
BOOL xMBPortEventGet( eMBEventType * eEvent ){
BOOL xEventHappened = FALSE;
if( xEventInQueue ){
*eEvent = eQueuedEvent;
xEventInQueue = FALSE;
xEventHappened = TRUE;
}
return xEventHappened;
}
另外还要查看
static eMBEventType eQueuedEvent;
static BOOL xEventInQueue;
首先理解xEventInQueue,x表示返回类型布尔值,直译:队列中的事件。如果它为真,则函数返回值为真。
对
xEventInQueue赋值的函数有两个,
//对列初始化
BOOL xMBPortEventInit( void ) {
xEventInQueue = FALSE;
return TRUE;
}
//进入队列
BOOL xMBPortEventPost( eMBEventType eEvent ){
xEventInQueue = TRUE;
eQueuedEvent = eEvent;
return TRUE;
}
因为初始化只一次,所以表示进入队列的函数在某个地方应该被调用了,否则出队列返回值一直为false。
再看xMBPortEventGet中的
*eEvent = eQueuedEvent;
eQueuedEvent是eMBEventType类型,直译:队列中的事件。
//进入队列
BOOL xMBPortEventPost( eMBEventType eEvent ){
xEventInQueue = TRUE;
eQueuedEvent = eEvent;
return TRUE;
}
当从事件队列中提取的事件为EV_FRAME_RECEIVED时,表示接收帧状态,就会继续执行。
if(eEvent == EV_FRAME_RECEIVED),即
eQueuedEvent == EV_FRAME_RECEIVED
********************************************************************
|
|