?? modbus.c
字號:
tmp[2] = start_address>>8; //起始地址 高字節
tmp[3] = start_address & 0xFF; //起始地址 低字節
tmp[4] = lenth>>8; //讀取數據量 高字節
tmp[5] = lenth & 0xFF; //讀取數據量 低字節
tmp_lenth = 6; //二進制包長度
ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);
GwSciTxBytes = tmp_lenth+2;
if(lenth % 8==0)
{
GwSciRxBytes=(lenth/8)+3+2; // lenth/8線圈狀態的字節數,3為地址碼,功能碼,字節數,2為兩個CRC字節
}
else
{
GwSciRxBytes=(lenth/8+1)+3+2;
}
SciSend(); //發送請求
SciReceive(); //接收設備響應
//獲取應答;對應答數據分析;對接收到的應答數據分析
if(GwSciRxBuffer[1] == 0x02) //通信正常,數據處理
{
ProcessMasterRTU(pwInState,GwSciRxBuffer,0,GwSciRxBytes);
}
else //查詢異常碼,可重新發送請求或作其他處理
{
return(CMD_ERR);
}
}
// 功能 :讀取保持寄存器:CMD == 3
// 返回 :成功返回1,否則返回0
// 請求命令:[設備地址] [命令號03] [起始寄存器地址高8位] [低8位] [讀取的寄存器個數,高8位] [低8位] [CRC校驗的高8位] [CRC校驗的低8位]
// 設備響應:[設備地址] [命令號03] [返回的字節個數][數據1][數據2]...[數據n][CRC校驗的低高8位] [CRC校驗的低8位]
char ReadHldreg(unsigned int *pwHldregState, unsigned char DeviceID, unsigned int start_address, unsigned int lenth)
{
unsigned char tmp[64], tmp_lenth,flag;
tmp[0] = DeviceID; //從設備地址
tmp[1] = 0x03; //命令
tmp[2]=start_address>>8; //起始地址 高字節
tmp[3]=start_address & 0xFF; //起始地址 低字節
tmp[4]=lenth>>8; //讀取寄存器個數 高字節
tmp[5]=lenth & 0xFF; //讀取寄存器個數 低字節
tmp_lenth = 6;
ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);
GwSciTxBytes = tmp_lenth+2;
GwSciRxBytes=lenth*2+3+2; //地址碼,功能碼,字節數共占3字節,CRC占2字節
SciSend(); //發送請求
SciReceive(); //接收設備響應
if(GwSciRxBuffer[1]==0x03)
ProcessMasterRTU(pwHldregState,GwSciRxBuffer,0,GwSciRxBytes);
else //通信異常0x83,查詢異常碼,可重新發送請求或作其他處理
{
return(CMD_ERR);
}
}
// 功能 :讀取模擬量輸入:CMD == 4
// 返回 :成功返回1,否則返回0
// 請求命令:[設備地址] [命令號04] [起始寄存器地址高8位] [低8位] [讀取的寄存器數高8位] [低8位] [CRC校驗的低8位] [CRC校驗的高8位]
// 設備響應:[設備地址] [命令號04] [返回的字節個數][數據1][數據2]...[數據n][CRC校驗的低8位] [CRC校驗的高8位]
char ReadAnlogIn(unsigned int *pwAnologInState, unsigned char DeviceID, unsigned int start_address, unsigned int lenth)
{
unsigned char tmp[64], tmp_lenth;
tmp[0] = DeviceID; //從設備地址
tmp[1] = 0x04; //命令
tmp[2] = start_address>>8; //起始地址 高字節
tmp[3] = start_address & 0xFF; //起始地址 低字節
tmp[4] = lenth>>8; //讀取數據量 高字節
tmp[5] = lenth & 0xFF ; //讀取數據量 低字節
tmp_lenth = 6;
ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);
GwSciTxBytes = tmp_lenth+2;
GwSciRxBytes = lenth*2+3+2; //地址碼,功能碼,字節數占3字節,CRC占2字節
SciSend(); //發送請求
SciReceive(); //接收設備響應
//獲取應答;對應答數據分析;對接收到的應答數據分析
if(GwSciRxBuffer[1] == 0x04) //通信正常,數據處理
{
ProcessMasterRTU(pwAnologInState,GwSciRxBuffer,0,GwSciRxBytes);
}
else //通信異常0x83,查詢異常碼,可重新發送請求或作其他處理
{
return(CMD_ERR);
}
}
// 功能 :設置繼電器:CMD == 5
// 返回 :成功返回1,否則返回0
// 請求命令:[設備地址] [命令號05] [需下置的寄存器地址高8位] [低8位] [下置的數據高8位] [低8位] [CRC校驗的低8位] [CRC校驗的高8位]
// 設備響應:如果成功把計算機發送的命令原樣返回,否則不響應
char SetCoil(unsigned char DeviceID, unsigned int start_address, unsigned int value)
{
unsigned char tmp[64], tmp_lenth;
tmp[0] = DeviceID; //從設備地址
tmp[1] = 0x05 ; //命令
tmp[2] = start_address>>8; //起始地址 高字節
tmp[3] = start_address & 0xFF; //起始地址 低字節
tmp[4] = value>>8; //待寫數據 高字節
tmp[5] = value & 0xFF; //待寫數據 低字節
tmp_lenth = 6;
ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);
GwSciTxBytes = tmp_lenth+2;
GwSciRxBytes = 6+2;
SciSend(); //發送請求
SciReceive(); //接收設備響應
if(GwSciRxBuffer[1] == 0x05) //通信正常,數據處理
{
if(CheckCRC(GwSciRxBuffer,GwSciRxBytes))
{
if(GwSciRxBuffer[2]!=GwSciTxBuffer[2]) return(0);
if(GwSciRxBuffer[3]!=GwSciTxBuffer[3]) return(0);
if(GwSciRxBuffer[4]!=GwSciTxBuffer[4]) return(0);
if(GwSciRxBuffer[5]!=GwSciTxBuffer[5]) return(0);
return(1);
}
else //CRC校驗不一致;可重新發送請求或作其他處理
{
return(CRC_ERR);
}
}
else //通信異常0x83,查詢異常碼,可重新發送請求或作其他處理
{
return(CMD_ERR);
}
}
// 功能 :設置單保持寄存器 CMD == 6
// 返回 :成功返回1,否則返回0
// 請求命令:[設備地址] [命令號06] [需下置的寄存器地址高8位] [低8位] [下置的數據高8位] [低8位] [CRC校驗的低8位] [CRC校驗的高8位]
// 設備響應:如果成功把計算機發送的命令原樣返回,否則不響應
char SetHldreg(unsigned char DeviceID, unsigned int start_address, unsigned int value)
{
unsigned char tmp[64], tmp_lenth;
tmp[0] = DeviceID; //地址
tmp[1] = 0x06; //命令
tmp[2] = start_address>>8; //寫數據的起始地址 高字節
tmp[3] = start_address & 0xFF; //寫數據的起始地址 低字節
tmp[4] = value>>8; //待寫數據 高字節
tmp[5] = value & 0xFF; //待寫數據 低字節
tmp_lenth = 6; //有效數據長度
ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);
GwSciTxBytes = tmp_lenth+2;
GwSciRxBytes = 6+2;
SciSend(); //發送請求
SciReceive(); //接收設備響應
//獲取應答;對應答數據分析;對接收到的應答數據分析
if(GwSciRxBuffer[1] == 0x06) //通信正常,數據處理
{
if(CheckCRC(GwSciRxBuffer,GwSciRxBytes))
{
if(GwSciRxBuffer[2]!=GwSciTxBuffer[2]) return(0);
if(GwSciRxBuffer[3]!=GwSciTxBuffer[3]) return(0);
if(GwSciRxBuffer[4]!=GwSciTxBuffer[4]) return(0);
if(GwSciRxBuffer[5]!=GwSciTxBuffer[5]) return(0);
return(1);
}
else //CRC校驗不一致;可重新發送請求或作其他處理
{
return(CRC_ERR);
}
}
else //通信異常0x83,查詢異常碼,可重新發送請求或作其他處理
{
return(CMD_ERR);
}
}
// 功能 :對多個線圈進行強制:CMD == 15
// 返回 :成功返回1,否則返回0
// 請求格式:從站地址 0x0F 第一個位首地址 所寫位數 值占用的字節數 值
// (例如,置從站5的位12至17為1,則:05 0F 000C 0006 01 3F CRC)
char SetCoils(unsigned char DeviceID, unsigned int Startbit_Add, unsigned int Bit2Write, unsigned char ByteValue, unsigned char *Values)
{
unsigned char tmp[64], tmp_lenth,i;
tmp[0] = DeviceID;
tmp[1] = 0x0f ;
tmp[2] = Startbit_Add>>8;
tmp[3] = Startbit_Add & 0xFF;
tmp[4] = Bit2Write>>8;
tmp[5] = Bit2Write & 0xFF;
tmp[6] = ByteValue;
for(i=0;i<ByteValue;i++)
tmp[7+i] = Values[i];
tmp_lenth = 7+ByteValue;
ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);
GwSciTxBytes = tmp_lenth+2;
GwSciRxBytes = 6+2;
SciSend(); //發送CMD請求
SciReceive(); //接收設備響應
//獲取應答;對應答數據分析;對接收到的應答數據分析
if(GwSciRxBuffer[1] == 0x0F) //通信正常,數據處理
{
if(CheckCRC(GwSciRxBuffer,GwSciRxBytes))
{
if(GwSciRxBuffer[2]!=GwSciTxBuffer[2]) return(0);
if(GwSciRxBuffer[3]!=GwSciTxBuffer[3]) return(0);
if(GwSciRxBuffer[4]!=GwSciTxBuffer[4]) return(0);
if(GwSciRxBuffer[5]!=GwSciTxBuffer[5]) return(0);
return(1);
}
else //CRC校驗不一致;可重新發送請求或作其他處理
{
return(CRC_ERR);
}
}
else //通信異常0x83,查詢異常碼,可重新發送請求或作其他處理
{
return(CMD_ERR);
}
}
char SetMultiHldreg(unsigned char DeviceID, unsigned int start_address, unsigned int WNum, unsigned char BNum, unsigned int *values)
{
unsigned char tmp[256], tmp_lenth;
unsigned char i=0;
unsigned int j;
tmp[0] = DeviceID; //地址
tmp[1] = 0x10; //命令
tmp[2] = start_address>>8; //寫數據的起始地址 高字節
tmp[3] = start_address & 0xFF; //寫數據的起始地址 低字節
tmp[4] = WNum>>8; //待寫寄存器數量
tmp[5] = WNum & 0xFF; //待寫寄存器數量
tmp[6] = BNum; //待寫數據的字節數
for(j=0;j<WNum;j++) //填充數據
{
tmp[i+7] = values[j]>>8; //待寫數據 高字節
tmp[i+8] = values[j] & 0xFF;//待寫數據 低字節
i=i+2;
}
tmp_lenth = 7+i; //有效數據長度
ConstructRtuFrame(GwSciTxBuffer, tmp, tmp_lenth);
GwSciTxBytes = tmp_lenth+2;
GwSciRxBytes = 6+2;
SciSend(); //發送CMD請求
SciReceive(); //接收設備響應
//獲取應答;對應答數據分析;對接收到的應答數據分析
if(GwSciRxBuffer[1] == 0x0F) //通信正常,數據處理
{
if(CheckCRC(GwSciRxBuffer,GwSciRxBytes))
{
if(GwSciRxBuffer[2]!=GwSciTxBuffer[2]) return(0);
if(GwSciRxBuffer[3]!=GwSciTxBuffer[3]) return(0);
if(GwSciRxBuffer[4]!=GwSciTxBuffer[4]) return(0);
if(GwSciRxBuffer[5]!=GwSciTxBuffer[5]) return(0);
return(1);
}
else //CRC校驗不一致;可重新發送請求或作其他處理
{
return(CRC_ERR);
}
}
else //通信異常0x83,查詢異常碼,可重新發送請求或作其他處理
{
return(CMD_ERR);
}
}
void interrupt SCI_INT()
{
switch(PIVR)
{
case 0x0006:
{
//置SCI接收中斷標志
GwSciRxFlag = 1;
//todo:把接收數據放在中斷服務程序中
//GwSciRxBuffer[GwRxCount] = SCIRXBUF;
//todo:通過讀SCIRXBUF就可以清除SCIRXST的RXRDY位,下面的判斷是否可去掉
//while((SCIRXST & 0x40)!=0); //查看SCIRXST的RXRDY位,判斷SCIRXBUF中的數據是否讀完
//GwRxCount++;
break;
}
default:
break;
}
//todo:當一個中斷被響應時,系統會自動清除IFR中相應的標志位,下面的清除是否必要
//IFR = 0x0001; //清IFR相應中斷標志
Enable(); //開總中斷
//return; //返回
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -