?? modbus.c
字號(hào):
/*=====================================================================================
File name: Modbus.C (28x version)
Originator: R&D Group
NIE
Dsscription: communication base on Modbus
=====================================================================================
History:
-------------------------------------------------------------------------------------
03-17-2005 Release Rev 1.0
08-13-2005 Release Rev 1.02
: 修改了漢字傳輸?shù)捻樞?參數(shù)表可以直接輸入漢字
-------------------------------------------------------------------------------------*/
#include "DSP281x_Device.h"
#include "DSP281x_Sci.h"
#include "Modbus.h" // Include header for Mudbus library
#include "fault_log.h"
extern FAULTLOG faultlog;
//#define FAULT_LOG_MAX 1
#define WAIT_DATA_HEAD 0 //等待報(bào)頭
#define READ_DATA 1 //接受數(shù)據(jù)
#define PROCESSING_DATA 2 //處理數(shù)據(jù)
#define SEND_DATA 3 //發(fā)送響應(yīng)報(bào)文
#define PARA_MAX_NUM 50
#define PARA_MAX_TBL_A 180
extern int Parameter0;
////////////rs485端口///////////////////////
void CommA(MODBUS *v)
{
int TempA,TempB,TempC;
long * TablePoint;
int * DataPoint;
//通訊幀故障清除
if(SciaRegs.SCIRXST.bit.RXERROR)
{
SciaRegs.SCICTL1.bit.SWRESET=0;
SciaRegs.SCICTL1.bit.SWRESET=1;
}
switch(v->CommFlag)
{
//接受報(bào)頭
case WAIT_DATA_HEAD:
{
while((SciaRegs.SCIFFRX.bit.RXFIFST!=0)&&(v->CommFlag==0))
{
TempA=(SciaRegs.SCIRXBUF.all&0x00ff);
if((TempA==0x00ff)||(TempA==v->Slave_Address))
{
v->CommData[0]=TempA;
{ v->Index=1;
v->CommFlag=READ_DATA; //跳出本循環(huán)
v->CommCount=0;
}
}
}
break;
//接受數(shù)據(jù)
case READ_DATA:
v->CommCount++;
while(SciaRegs.SCIFFRX.bit.RXFIFST!=0)
{
v->CommData[v->Index]=(SciaRegs.SCIRXBUF.all&0x00ff); //
//if((v->CommData[v->Index]&0x0ff00)==0)
{ //數(shù)據(jù)必須正確
v->Index++;
if(v->Index>=PARANUMMAX)
{
v->Index=0;
v->CommFlag = WAIT_DATA_HEAD;
}
v->CommCount=0;
}
}
if(v->CommCount>=DELAYCOUNT)
{
v->CommFlag = PROCESSING_DATA;
}
}
break;
//處理報(bào)文,產(chǎn)生響應(yīng)報(bào)文
case PROCESSING_DATA:
{
if(CRC_cal(v->CommData,v->Index)==0) //if1
{
switch(v->CommData[1])
{ //switch2
//MODBUS功能3
case 3:
{
TempA=(v->CommData[2]<<8)|(v->CommData[3]); //參數(shù)起始地址
switch(TempA)
{ //switch3
//菜單頁參數(shù)讀命令
case 919:
{
//固定長度響應(yīng)報(bào)文
v->CommData[2]=32;
DataPoint=&ParaTblA[v->ParaNum][0] ;
//讀取PARA_TAB中的數(shù)據(jù)
TempA=3;
while(TempA<(16*2+3))
{
v->CommData[TempA++]= ((*DataPoint)>>8)&0x00ff;
v->CommData[TempA++]= (*DataPoint)&0x00ff;
DataPoint++;
}
//寫入實(shí)際數(shù)據(jù)
TablePoint=MenuInfo;
DataPoint=(int *)TablePoint[v->ParaNum];
v->CommData[29]=(*DataPoint>>8)&0xff; //寫入報(bào)文地址
v->CommData[30]=(*DataPoint)&0x0ff; //寫入報(bào)文地址
TempA=CRC_cal(v->CommData,35); //固定長度
v->CommData[35]=(TempA>>8)&0x00ff; //寫入CRC校驗(yàn)位
v->CommData[36]=TempA&0x00ff;
v->Index = 36; //共計(jì)發(fā)送36個(gè)數(shù)據(jù)
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
break;
//故障頁讀取
case 900:
{
v->CommData[2]=9*2; //固定報(bào)文格式
TempA=faultlog.log[v->FaultNum][0];
DataPoint=&FaultTabA[TempA][0];
//讀取PARA_TAB中的數(shù)據(jù)
v->CommData[3]=(faultlog.log[v->FaultNum][1])>>8; //hour hi8
v->CommData[4]=faultlog.log[v->FaultNum][1]; //hour low8
v->CommData[5]=(faultlog.log[v->FaultNum][2])>>8; //minute
v->CommData[6]=faultlog.log[v->FaultNum][2]; //secend
v->CommData[7]=(faultlog.log[v->FaultNum][3])>>8; //ms hi8
v->CommData[8]=(faultlog.log[v->FaultNum][3]); //ms low8
TempA=9;
while(TempA<(9*2+9))
{
v->CommData[TempA++]= ((*DataPoint)>>8)&0x00ff;
v->CommData[TempA++]= (*DataPoint)&0x00ff;
DataPoint++;
}
//寫入實(shí)際數(shù)據(jù)
TempA=CRC_cal(v->CommData,27); //固定長度
v->CommData[27]=(TempA>>8)&0x00ff; //寫入CRC校驗(yàn)位
v->CommData[28]=TempA&0x00ff;
v->Index = 28; //共計(jì)發(fā)送29個(gè)數(shù)據(jù)
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
break;
//其他,狀態(tài)頁讀取
default:
{
if(TempA<100)// 操作盤數(shù)據(jù)讀取
{
v->CommFlag = WAIT_DATA_HEAD;
}
else if(TempA<899) //參數(shù)讀取
{
TablePoint=MenuInfo1;
TempA=TempA-100; //相對(duì)參數(shù)頁首的偏移
if(TempA<PARA_MAX_TBL_A)
{
TempB=(v->CommData[4]<<8)|(v->CommData[5])-1; //數(shù)據(jù)個(gè)數(shù)
TempC=TempB+TempA; //
v->CommData[2]=TempB*2+2;
v->Index=TempB*2+4+1;
for(;TempB>=0;TempB--,TempC--)
{
DataPoint=(int *)TablePoint[TempC];
TempA = TempB*2+4;
v->CommData[TempA]=(*DataPoint)&0x0ff;
TempA--;
v->CommData[TempA]=(*DataPoint>>8)&0x0ff;
}
TempB=CRC_cal(v->CommData,v->Index); //個(gè)數(shù)=標(biāo)號(hào)+1;
v->CommData[v->Index]=(TempB>>8)&0xff;
v->Index++;
v->CommData[v->Index]=TempB&0xff;
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
else
{
v->CommFlag = WAIT_DATA_HEAD;
}
}
else if(TempA<2000) //事件讀取
{
v->CommFlag = WAIT_DATA_HEAD;
}
else if(TempA<8031) //波形記錄讀取
{
DataPoint=(int*)(0x10bbcc);
//DataPoint[21]=1;
//DataPoint[22]=0;
TempA-=2001;
TempB=(v->CommData[4]<<8)|(v->CommData[5])-1; //數(shù)據(jù)個(gè)數(shù)
TempC=TempB+TempA; //
v->CommData[2]=TempB*2+2;
v->Index=TempB*2+4+1;
for(;TempB>=0;TempB--,TempC--)
{
TempA = TempB*2+4;
v->CommData[TempA]=DataPoint[TempC]&0x0ff;
TempA--;
v->CommData[TempA]=(DataPoint[TempC]>>8)&0x0ff;
}
TempB=CRC_cal(v->CommData,v->Index); //個(gè)數(shù)=標(biāo)號(hào)+1;
v->CommData[v->Index]=(TempB>>8)&0xff;
v->Index++;
v->CommData[v->Index]=TempB&0xff;
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
else //異常數(shù)據(jù)處理
{
v->CommFlag = WAIT_DATA_HEAD;
}
}
} //end switch3
} //end switch2 case3
break;
//MODBUS功能16 寫數(shù)據(jù)
case 16:
{
TempA=(v->CommData[2]<<8)|(v->CommData[3]); //參數(shù)起始地址
switch(TempA)
{ //switch16
case 932:
{
TablePoint=MenuInfo;
DataPoint=(int *)TablePoint[v->ParaNum]; //數(shù)據(jù)地址
*DataPoint=(v->CommData[7]<<8)+(v->CommData[8]);
TempB=CRC_cal(v->CommData,6); //個(gè)數(shù)=標(biāo)號(hào)+1;
v->CommData[6]=(TempB>>8)&0xff;
v->CommData[7]=TempB&0xff;
v->Index = 7;
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
break;
case 918: //參數(shù)翻頁信息處理
{
TempB=(v->CommData[7]<<8)+(v->CommData[8]);
if(TempB==2)
{
v->ParaNum--;
if(v->ParaNum < 0 )
v->ParaNum = MENU_MAX_NUMBER_TBLA -1;
}
else if(TempB==1)
{
v->ParaNum++;
if(v->ParaNum >= MENU_MAX_NUMBER_TBLA)
v->ParaNum = 0;
}
TempB=CRC_cal(v->CommData,6); //個(gè)數(shù)=標(biāo)號(hào)+1;
v->CommData[6]=(TempB>>8)&0xff;
v->CommData[7]=TempB&0xff;
v->Index = 7;
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
break;
case 912: //故障翻頁信息
{
TempB=(v->CommData[7]<<8)+(v->CommData[8]);
if(TempB==2)
{
v->FaultNum--;
if(v->FaultNum < 0 )
v->FaultNum = FAULT_LOG_MAX -1;
}
else if(TempB==1)
{
v->FaultNum++;
if(v->FaultNum >= FAULT_LOG_MAX)
v->FaultNum = 0;
}
TempB=CRC_cal(v->CommData,6); //個(gè)數(shù)=標(biāo)號(hào)+1;
v->CommData[6]=(TempB>>8)&0xff;
v->CommData[7]=TempB&0xff;
v->Index = 7;
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
break;
default:
{
if(TempA < 100) //操作盤參數(shù)更新
{
v->Index = 0;
}
else if(TempA<900) //參數(shù)列表內(nèi)參數(shù)數(shù)據(jù)更新
{
TablePoint=MenuInfo1;
// TablePoint=MenuInfo91;
TempA=TempA-100; //相對(duì)參數(shù)頁首的偏移
TempB=(v->CommData[4]<<8)|(v->CommData[5])-1; //數(shù)據(jù)個(gè)數(shù)
TempC=TempB+TempA; //數(shù)據(jù)地址
v->Index=TempB*2+4+1;
for(;TempB>=0;TempB--,TempC--)
{
DataPoint=(int *)TablePoint[TempC];
TempA = TempB*2+7;
//增加權(quán)限控制
*DataPoint=(v->CommData[TempA]<<8)+v->CommData[TempA+1] ;
}
TempB=CRC_cal(v->CommData,6); //個(gè)數(shù)=標(biāo)號(hào)+1;
v->CommData[6]=(TempB>>8)&0xff;
v->CommData[7]=TempB&0xff;
v->Index = 7;
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
else if(TempA<=2000)
{
v->Index = 0; //對(duì)事件記錄部分修改無效
}
else if(TempA<=2021) //
{
TempA=TempA-2001; //相對(duì)頁首的偏移
TempB=(v->CommData[4]<<8)|(v->CommData[5])-1; //數(shù)據(jù)個(gè)數(shù)
DataPoint=(int *)(0x10bbcc+TempA);
TempC=TempB+TempA; //數(shù)據(jù)地址
DataPoint=(int *)(0x10bbcc+TempC);
v->Index=TempB*2+4+1;
for(;TempB>=0;TempB--)
{
TempA = TempB*2+7;
//增加權(quán)限控制
*(DataPoint--)=(v->CommData[TempA]<<8)+v->CommData[TempA+1] ;
}
TempB=CRC_cal(v->CommData,6); //個(gè)數(shù)=標(biāo)號(hào)+1;
v->CommData[6]=(TempB>>8)&0xff;
v->CommData[7]=TempB&0xff;
v->Index = 7;
v->CommCount = 0;
v->CommFlag = SEND_DATA; //轉(zhuǎn)入發(fā)送
}
else
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -