?? modbus.txt
字號:
*(dest_p + i/2) |=ModbusModule.Buf[i+3]&0xFF; //low 8 bit renew
}
break;
case READ_HLD_REG: //3
// if ( !(SysSta&ComRecept) ){
for ( i=0; i<ModbusModule.Buf[2]; i+=2){
*(dest_p + i/2) = ( ModbusModule.Buf[i+3]<<8 ) + ModbusModule.Buf[i+4];
}
// }
break;
case SET_N_COIL: //15
case SET_N_HLD_REG: //16
// RegAddr= ((ModbusModule.Buf[2] - (uint8)Uart0.Addr) << 8) + ModbusModule.Buf[3]; // 計算 寄存器首地址
RegAddr= (ModbusModule.Buf[2]<<8) + ModbusModule.Buf[3];
RegNum = (ModbusModule.Buf[4]<<8) + ModbusModule.Buf[5];
if ( RegAddr != ModbusModule.RegAddr ){
return 4;
}
if ( RegNum != ModbusModule.RegNum ){
return 5;
}
break;
}//end switch
return 0;
}
//---------------------------------------------
// ModbusRTUMasterRun
// 主戰先發起通訊,發送16(寫),然后接收完畢,解析后發送3(讀)然后接收完畢,解析(對從站1操作)
// 對從站2進行類似操作。然后循環。
//
//---------------------------------------------
void ModbusRTUMasterRun ()
{
switch (ModbusModule.Status){
case IDLE_WAIT ://0
if (ModbusModule.TimeoutReg>=5){ //重發延時一結束符以上(3.5字符周期)
if (!(SysSta&InitSub1) ){
if(ModbusModule.FunCode ==SET_N_COIL){
ModbusModule.ID=1;
ModbusModule.FunCode =SET_N_COIL;
ModbusModule.RegAddr=400;
ModbusModule.RegNum=320;
ConstructFrame_RTUSetNCoil(ModbusModule.ID,&REBit[ModbusModule.ID-1][0],ModbusModule.RegAddr,ModbusModule.RegNum);
// }
}else if (ModbusModule.FunCode ==SET_N_HLD_REG){
ModbusModule.ID=1;
ModbusModule.FunCode =SET_N_HLD_REG;
ModbusModule.RegAddr=700;
ModbusModule.RegNum=100;
ConstructFrame_RTUSetNHldReg(ModbusModule.ID,&REDate[ModbusModule.ID-1][0],ModbusModule.RegAddr,ModbusModule.RegNum);
}
}else if( ModbusModule.FunCode == SET_N_HLD_REG ){
ConstructFrame_RTUSetNHldReg(ModbusModule.ID,&WRData[ModbusModule.ID-1][0],ModbusModule.RegAddr,ModbusModule.RegNum);
}else if ( ModbusModule.FunCode == READ_HLD_REG ){
ConstructFrame_RTUReadHldReg(ModbusModule.ID,ModbusModule.RegAddr,ModbusModule.RegNum);
}else if( ModbusModule.FunCode == SET_N_COIL ){
ConstructFrame_RTUSetNCoil(ModbusModule.ID,&WRBit[ModbusModule.ID-1][0],ModbusModule.RegAddr,ModbusModule.RegNum);
}else if ( ModbusModule.FunCode == READ_N_COIL ){
ConstructFrame_RTUReadNCoil(ModbusModule.ID,ModbusModule.RegAddr,ModbusModule.RegNum);
}
ScibRegs.SCITXBUF = ModbusModule.Buf[ModbusModule.Point++];
ModbusModule.TxLen--;
ModbusModule.Status = SEND_START;
}
break;
case SEND_START ://3
asm(" nop");
break;
case SEND_END ://4
if (ModbusModule.TimeoutReg>=10){ //超時500ms(無回應)
InitSci_B();
ModbusModule.ReTryTime++;
ModbusModule.TimeoutReg=0;
ModbusModule.Status = IDLE_WAIT;
}
break;
case RECE_START ://1
if (ModbusModule.TimeoutReg>=5){ //接收幀結束
ModbusModule.Status = RECE_END;
}
break;
case RECE_END ://2
if( (ModbusModule.FunCode== READ_N_COIL) || (ModbusModule.FunCode== SET_N_COIL)){
if ( RTUMasterFrameAnalyse(&REBit[ModbusModule.ID-1][0])==0 ){ //接收幀解碼正確,清除故障
if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==SET_N_COIL) ){
ModbusModule.Tbl_COIL_SET1=0;
}else if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==READ_N_COIL) ){
ModbusModule.Tbl_COIL_READ1=0;
}
ModbusModule.ReTryTime=0; //重試次數清0
ModbusModule.Status = SEND_EXCHANGE;
}else{ //接收幀解碼有誤,重試,重試次數加1
ModbusModule.ReTryTime++;
ModbusModule.TimeoutReg=0;
ModbusModule.Status =IDLE_WAIT;
}
}else{
if ( RTUMasterFrameAnalyse(&REDate[ModbusModule.ID-1][0])==0 ){ //接收幀解碼正確,清除故障
SysSta|=InitSub1;
if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==SET_N_HLD_REG) ){
ModbusModule.Tbl_SET1=0;
}else if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==READ_HLD_REG) ){
ModbusModule.Tbl_READ1=0;
}else if ( (ModbusModule.ID==2) && (ModbusModule.FunCode==SET_N_HLD_REG) ){
ModbusModule.Tbl_SET2=0;
}else if ( (ModbusModule.ID==2) && (ModbusModule.FunCode==READ_HLD_REG) ){
ModbusModule.Tbl_READ2=0;
}
ModbusModule.ReTryTime=0; //重試次數清0
ModbusModule.Status = SEND_EXCHANGE;
}else{ //接收幀解碼有誤,重試,重試次數加1
ModbusModule.ReTryTime++;
ModbusModule.TimeoutReg=0;
ModbusModule.Status =IDLE_WAIT;
}
}
break;
case SEND_EXCHANGE ://5
if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==SET_N_HLD_REG) ){
ModbusModule.ID = 1;
ModbusModule.FunCode= READ_HLD_REG;
ModbusModule.RegAddr= 700;
ModbusModule.RegNum = 100;
}else if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==READ_HLD_REG) ){
ModbusModule.ID = 1;
ModbusModule.FunCode= SET_N_COIL;
ModbusModule.RegAddr= 00;
ModbusModule.RegNum = 320;
}else if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==SET_N_COIL) ){
if (!(SysSta&InitSub1) ){
ModbusModule.FunCode= SET_N_HLD_REG;
}else{
ModbusModule.ID = 1;
ModbusModule.FunCode= READ_N_COIL;
ModbusModule.RegAddr= 400;
ModbusModule.RegNum = 320;
}
}else if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==READ_N_COIL) ){
ModbusModule.ID = 2;
ModbusModule.FunCode= SET_N_HLD_REG;
ModbusModule.RegAddr= 600;
ModbusModule.RegNum = 100;
}else if ( (ModbusModule.ID==2) && (ModbusModule.FunCode==SET_N_HLD_REG) ){
ModbusModule.ID = 2;
ModbusModule.FunCode= READ_HLD_REG;
ModbusModule.RegAddr= 800;
ModbusModule.RegNum = 100;
}else if ( (ModbusModule.ID==2) && (ModbusModule.FunCode==READ_HLD_REG) ){
ModbusModule.ID = 1;
ModbusModule.FunCode= SET_N_HLD_REG;
ModbusModule.RegAddr= 500;
ModbusModule.RegNum = 100;
}
ModbusModule.TimeoutReg=0; //延時一結束幀判斷時間
ModbusModule.Status = IDLE_WAIT;
break;
default :
break;
}
if(ModbusModule.ReTryTime>=5){ //重試次數到達上限,報錯,切換發送
if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==SET_N_HLD_REG) ){
ModbusModule.Tbl_SET1=1;
}else if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==READ_HLD_REG) ){
ModbusModule.Tbl_READ1=1;
}else if ( (ModbusModule.ID==2) && (ModbusModule.FunCode==SET_N_HLD_REG) ){
ModbusModule.Tbl_SET2=1;
}else if ( (ModbusModule.ID==2) && (ModbusModule.FunCode==READ_HLD_REG) ){
ModbusModule.Tbl_READ2=1;
}else if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==SET_N_COIL) ){
ModbusModule.Tbl_COIL_SET1=1;
}else if ( (ModbusModule.ID==1) && (ModbusModule.FunCode==READ_N_COIL) ){
ModbusModule.Tbl_COIL_READ1=1;
}
if (SysSta&InitSub1){
ModbusModule.Status = SEND_EXCHANGE;
}
ModbusModule.ReTryTime=0;
}
}
#endif
#ifdef MODBUS_SLAVE
//---------------------------------------------
// RTU Set N Hold Register
// CMD=16 SET_N_HLD_REG
// Constructe Answer Frame
//---------------------------------------------
void ModbusSlaveSetNHldRegAnswer ( Uint16 board_adr,Uint16 start_address,Uint16 lenth)
{
Uint16 i=0,j=0;
ModbusModule.Buf[i++] = board_adr;
ModbusModule.Buf[i++] = SET_N_HLD_REG;
ModbusModule.Buf[i++] = WORD_HI(start_address);
ModbusModule.Buf[i++] = WORD_LO(start_address);
ModbusModule.Buf[i++] = WORD_HI(lenth);
ModbusModule.Buf[i++] = WORD_LO(lenth);
j=GetCRC16(ModbusModule.Buf,i);
ModbusModule.Buf[i++] = WORD_LO(j);
ModbusModule.Buf[i++] = WORD_HI(j);
ModbusModule.TxLen = i;
ModbusModule.Point = 0;
}
//---------------------------------------------
// RTU Read Hold Register
// CMD=03 READ_HLD_REG
// Constructe Answer Frame
//---------------------------------------------
void ModbusSlaveReadHldRegAnswer ( Uint16 board_adr,Uint16 *com_buf,Uint16 lenth)
{
Uint16 i=0,j=0;
ModbusModule.Buf[i++] = board_adr;
ModbusModule.Buf[i++] = READ_HLD_REG;
ModbusModule.Buf[i++] = lenth<<1;
for(j=0;j<lenth;j++){
ModbusModule.Buf[i++] = WORD_HI( * (com_buf+j) );
ModbusModule.Buf[i++] = WORD_LO( * (com_buf+j) );
}
j=GetCRC16(ModbusModule.Buf,i);
ModbusModule.Buf[i++] = WORD_LO(j);
ModbusModule.Buf[i++] = WORD_HI(j);
ModbusModule.TxLen = i;
ModbusModule.Point = 0;
}
//---------------------------------------------
// RTU 從站接收分析
// 3 READ_HLD_REG
// 16 SET_N_HLD_REG
// 返回值: 0 OK
// 1 CRC校驗錯誤
// 2 站號不匹配
// 4 16寫地址不匹配
// 5 16寫數據字數不匹配
//---------------------------------------------
Uint16 RTUSlaveFrameAnalyse (Uint16 *dest_p)
{
Uint16 i;
Uint16 crc_result, crc_tmp;
Uint16 RegAddr,RegNum;
crc_tmp = ModbusModule.Buf[ModbusModule.RxLen-1]<<8;
crc_tmp += ModbusModule.Buf[ModbusModule.RxLen-2];
crc_result=GetCRC16(ModbusModule.Buf,ModbusModule.RxLen-2);
if ( crc_tmp != crc_result ) // CRC 校驗正確
{
return 1;
}
if ( ModbusModule.ID != ModbusModule.Buf[0] ){
return 2;
}
// if ( ModbusModule.FunCode != ModbusModule.Buf[1] ){
// return 3;
// }
ModbusModule.FunCode=ModbusModule.Buf[1];
switch (ModbusModule.FunCode){
case READ_HLD_REG: //3
// for ( i=0; i<ModbusModule.Buf[2]; i+=2){
// *(dest_p + i/2) = ( ModbusModule.Buf[i+3]<<8 ) + ModbusModule.Buf[i+4];
// }
// RegAddr= (ModbusModule.Buf[2]<<8) + ModbusModule.Buf[3];
// RegNum = (ModbusModule.Buf[4]<<8) + ModbusModule.Buf[5];
ModbusSlaveReadHldRegAnswer(ModbusModule.ID,&WRData[0][0],100);
break;
case SET_N_HLD_REG: //16
// RegAddr= ((ModbusModule.Buf[2] - (uint8)Uart0.Addr) << 8) + ModbusModule.Buf[3]; // 計算 寄存器首地址
RegAddr= (ModbusModule.Buf[2]<<8) + ModbusModule.Buf[3];
RegNum = (ModbusModule.Buf[4]<<8) + ModbusModule.Buf[5];
if ( (RegNum<<1) != ModbusModule.Buf[6] ){ //字節長度是否匹配
return 4;
}
if ( RegAddr != 600 ){ //對應從站2固定的起始地址(自定義)
return 5;
}
for ( i=0; i<ModbusModule.Buf[6]; i+=2){
*(dest_p + i/2) = ( ModbusModule.Buf[i+7]<<8 ) + ModbusModule.Buf[i+8];
}
ModbusSlaveSetNHldRegAnswer(ModbusModule.ID,RegAddr,RegNum);
break;
}//end switch
return 0;
}
//---------------------------------------------
// ModbusRTUSlaveRun
// 通訊由主站發起,從站初始化為接收,并相應的做出回應。
// 站號在初始化中有設置,以后不再更改。
//---------------------------------------------
void ModbusRTUSlaveRun (void)
{
switch (ModbusModule.Status){
case IDLE_WAIT ://0
ScibRegs.SCITXBUF = ModbusModule.Buf[ModbusModule.Point++];
ModbusModule.TxLen--;
ModbusModule.Status = SEND_START;
break;
case SEND_START ://3
asm(" nop");
break;
case SEND_END ://4
if (ModbusModule.TimeoutReg>=10){ //超時10ms
ModbusModule.ReTryTime++;
ModbusModule.TimeoutReg=0;
InitSci_B();
}
break;
case RECE_START ://1
if (ModbusModule.TimeoutReg>=5){ //接收幀結束
ModbusModule.Status = RECE_END;
}
break;
case RECE_END ://2
if ( RTUSlaveFrameAnalyse(&REDate[0][0])==0 ){//幀解析正確
ModbusModule.Status =IDLE_WAIT;
}else{ //幀解析不正確
ModbusModule.Status =SEND_END;
}
break;
}
}
#endif
//---------------------------------------------------------------------------
// END
//---------------------------------------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -