?? modbusrxd.c
字號:
/*********************************************************************
* FileName : modbusrxd.c
* Author : Jack Zhang
* Date : 06/6/2008
*********************************************************************/
#include <psos.h>
#include <custom_defs.h>
#include <tmInterrupts.h>
#include <AppModel.h>
#include <stdio.h>
#include <string.h>
#include <tmNxTypes.h>
#include <tmDbg.h>
#include <tmosal.h>
#include <dprintf.h>
#include <tmbslCore.h>
#include <tmosal.h>
#include "modbus.h"
#include "..\..\nexper5.5\exProject\comps\Uart8004\src\uart_local.h"
#include "..\..\nexper5.5\exProject\comps\Uart8004\inc\uart.h"
#define DEBUG_MODBUS
//----------------公有變量------------------------------------
static unsigned int addr =1; //定義靜態的地址變量,用于接收數據的地址校驗,以及用戶修改地址數據
unsigned char *mod_ascii =NULL;//接收modbus傳送過來的字符,是BIT
unsigned char *mod_rtu =NULL; //接收rtu模式的數據
unsigned char **dframe =NULL;
unsigned char *chars;
extern int valid_data(unsigned char*, int,char); //提取有效數據
//-------------------------------------------------------------
//-------------公有函數-----------------------------------------
int process_rxd(Rn_Buffer_t *pRnBuf); //通信處理函數
void change_addr(int); //改變地址
//---------------------------------------------------------------
//---------------私有函數----------------------------------------
unsigned char lrc8(unsigned char *,unsigned short); //LRC校驗
int len_check(unsigned char* ); //計算每個包中數據的長度,查看是否丟失數據
extern unsigned short crc16(unsigned char *,unsigned short); //CRC校驗
int ch2ii (int dfnum); //將字符轉換成整形數
//---------------------------------------------------------------
//-------------------更改設備地址-----------------------------
void change_addr(int num)
{
if((num>247||num<0))
printf("輸入錯誤!請輸入一個1--247之間的整數:");
else
addr = num;
}
//-----------------------------------------------------------------
//-------------------CRC校驗-----------------------------
unsigned short crc16(unsigned char *puchMsg , unsigned short usDataLen)
{
unsigned char uchCRCHi = 0xFF ; /* high byte of CRC initialized */
unsigned char uchCRCLo = 0xFF ; /* low byte of CRC initialized */
unsigned short uIndex ; /* will index into CRC lookup table */
while (usDataLen--)/* pass through message buffer */
{
uIndex = uchCRCHi ^ *puchMsg++ ; /* calculate the CRC */
uchCRCHi = uchCRCLo ^ aucrchi[uIndex];
uchCRCLo = aucrclo[uIndex] ;
}
return (uchCRCHi << 8 | uchCRCLo) ;
}
//-----------------------------------------------------------------
//-------------------LRC校驗-----------------------------
unsigned char lrc8(unsigned char *auchMsg_,unsigned short usDataLen_)
{
unsigned char uchLRC = 0 ; /* LRC 字節初始化 */
while (usDataLen_--) /* 傳送消息 */
uchLRC += *auchMsg_++; /* 累加*/
return (((unsigned char)(~uchLRC+1)));
}
//-----------------------------------------------------------------
//-------------------字符轉換函數-----------------------------------
int ch2ii (int dfnum)
{
int i,k;
for(i =0; i<22; i++)
{
if(dframe[dfnum][0] ==ch2i[i].ch)
{
break;
}
}
for(k =0; k<22; k++)
{
if(dframe[dfnum][1] ==ch2i[k].ch)
{
break;
}
}
return ((((ch2i[i].num)&0x0000000f)<<4)+((ch2i[k].num)&0x0000000f));
}
//-------------------------ASCII模式數據接收----------------
int ascii_rxd(Rn_Buffer_t *pRnBuf)
{
int length=RNBUF_LEN(pRnBuf);
unsigned char *pStart = pRnBuf->buf+pRnBuf->rd;
unsigned short ascii_oper; //操作碼
int i,ascii_flag;//ascii_flag表識數據接收成功與否
int j=1;
char lrcch;
#ifdef DEBUG_MODBUS
printf("hello ascii world!\n");
printf("length =%d\n",length);
#endif
mod_ascii = (unsigned char *)malloc(length*sizeof(unsigned char));
if(mod_ascii == NULL)
{
printf("mod_ascii申請內存失敗。\n");
}
memcpy(mod_ascii,pStart,length);
#ifdef DEBUG_MODBUS
for(i =0;i<length;i++)
printf("0x%x\n",mod_ascii[i]);
printf("\n");
#endif
dframe = (unsigned char **)malloc(((length)/2)*sizeof(unsigned char));
chars =(unsigned char *)malloc(((length)/2)*sizeof(unsigned char));
if(dframe == NULL)
{
printf("dframe申請內存失敗。\n");
}
for(i =0;i<length/2;i++)
{
dframe[i] =(unsigned char*)malloc(2*sizeof(unsigned char));
dframe[i][0] =mod_ascii[j++];
dframe[i][1] =mod_ascii[j++];
}
for(i =0;i<length/2;i++)
{
chars[i] =ch2ii(i);
#ifdef DEBUG_MODBUS
printf("char[i] =0x%x\n",chars[i]);
#endif
}
if( FRAME_START == mod_ascii[0]) // 幀頭檢查,幀頭一個字節
{
#ifdef DEBUG_MODBUS
printf("ascii rxd start ok\n");
#endif
if(addr ==(int)chars[0]) //地址檢查,地址兩個字節
{
#ifdef DEBUG_MODBUS
printf("ascii addr ok!\n");
#endif
lrcch =lrc8(chars,(length/2)-1);
#ifdef DEBUG_MODBUS
printf("lrc =0x%x\n",(lrcch&0x000000ff));
printf("chars[length/2-1] =0x%x\n",chars[length/2-1]);
printf("chars[length/2-1] =0x%x\n",chars[length/2-2]);
#endif
if( chars[length/2-1]== (lrcch&0x000000ff))//LRC檢查,兩個字節
{
#ifdef DEBUG_MODBUS
printf("ascii lrc ok!\n");
#endif
ascii_oper =chars[1]; //取操作碼兩個字節
//packs_num = PACKINTS(dframe[6],dframe[5]); //取數據包量兩個字節
// if(packs_num == packnum_check(dframe,length))
// {
ascii_flag =valid_data(chars,length,'a'); //取有效數據
//}
//else
// _send(addr , "長度校驗有誤!");
}
else
error_send(addr , mod_ascii,'a');
}
//地址不正確,不進行接收數據
}
else
error_send(addr,mod_ascii,'a');
if(ascii_flag ==0)
ok_send(addr,mod_ascii,'a');
else
error_send(addr , mod_ascii,'a');
for(i =0; i<length/2; i++)
{
free(*dframe[i]);
*dframe[i] =NULL;
}
free(mod_ascii);
mod_ascii =NULL;
return (pRnBuf->rd+length);
}
//-------------------------------------------------------------
//-------------------------RTU模式數據接收----------------
int rtu_rxd(Rn_Buffer_t *pRnBuf)
{
int length=RNBUF_LEN(pRnBuf);
unsigned char *pStart = pRnBuf->buf+pRnBuf->rd;
unsigned char rtu_oper; //操作碼
int i,rtu_flag; //rtu_flag表識接收數據成功與否
int crcci;
#ifdef DEBUG_MODBUS
printf("rtu_rxd ok!\n");
printf("length =%d\n",length);
#endif
mod_rtu = (unsigned char *)malloc(length*sizeof(unsigned char));
if(mod_rtu == NULL)
{
printf("mod_rtu申請內存失敗。\n");
}
memcpy(mod_rtu,pStart,length);
for(i =0;i<length;i++)
#ifdef DEBUG_MODBUS
printf("0x%x\n",mod_rtu[i]);
printf("\n");
#endif
if(addr ==mod_rtu[0]) //地址檢查
{
#ifdef DEBUG_MODBUS
printf("addr ok!\n");
#endif
crcci =crc16(mod_rtu,length-2);
#ifdef DEBUG_MODBUS
printf("crc =0x%x\n",(crcci&0x0000ffff));
printf("crc2 =0x%x\n",mod_rtu[length-1]<<8|mod_rtu[length-2]);
#endif
if(mod_rtu[length-1]<<8|mod_rtu[length-2]== (crcci&0x0000ffff))//CRC檢查 {
#ifdef DEBUG_MODBUS
printf("crc ok!\n");
#endif
rtu_oper =mod_rtu[1]; //取操作碼兩個字節
//packs_num = PACKINTS(dframe[6],dframe[5]); //取數據包量兩個字節
// if(packs_num == packnum_check(dframe,length))
// {
rtu_flag =valid_data(mod_rtu,length-2,'r'); //取有效數據
//}
//else
// _send(addr , "長度校驗有誤!");
}
else
error_send(addr,mod_rtu,'r');
}
//地址不正確,不進行接收數據
if(rtu_flag ==0)
error_send(addr,mod_rtu,'r');
else
ok_send(addr,mod_rtu,'r');
free(mod_rtu);
mod_rtu =NULL;
return (pRnBuf->rd+length);
}
//-------------------------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -