📄 modbusa.h
字号:
if(uc_is_excep) //如果有异常
{
*(puc_send_buf + --ucp_send_count) = *(puc_rec_buf + 1) + 0x80;//功能码加0x80
ucp_send_count++;
*(puc_send_buf + ucp_send_count++) = uc_excep_code;
}
if(is_modbus_asc)
{
ucp_send_count = convert_rtu_to_ascii(puc_send_buf,ucp_send_count);
}
else
{
u16 = CRC16(puc_send_buf,ucp_send_count);//CRC效验,传的是数组的个数
*(puc_send_buf + ucp_send_count++) = (LO_UINT(u16));
*(puc_send_buf + ucp_send_count) = (HI_UINT(u16));
}
return(ucp_send_count); //返回的是下标,这是发送中断所确定的
}
#ifdef OP_TB_WRITE_REG
//**************************************************************************
//**Purpose:
//** 以下是自己发出了读PLC内部变量的命令03,PLC返回了数据,填写入自己的内存
void write_word_by_plc(uint ui_word_address,uchar uc_word_len,uchar *dat)
{
uchar uc_i;
uint ui_mid;
for(uc_i = 0; uc_i<uc_word_len; uc_i++)
{
ui_mid = *dat;
dat++;
ui_mid<<=8;
ui_mid |= *dat;
dat++;
Rtu_write_singleReg(ui_word_address+uc_i,ui_mid);
}
}
#endif //**end(#ifdef OP_TB_WRITE_REG)
//*****************************************************************************************
//**Purpose:当modbus为主时,分析接收帧,并根据接收帧作相应处理.
//**Entry: puc_rec_buf:---指向接收缓冲. uc_rec_len:---接收缓冲的长.uc_op_table_pos:指向发送命令表的下标。
void rtu_reqframe_anlys_master(UCHAR* puc_rec_buf,UCHAR uc_rec_len,UCHAR uc_op_table_pos)
{
UCHAR uc_func_code,uc_bytes;
if(is_modbus_asc) //modbus为asc模式
{
uc_func_code = MAKE_HEX_TO_DEC(*(puc_rec_buf+uc_rec_len-2),*(puc_rec_buf+uc_rec_len-1));
uc_rec_len = convert_ascii_to_rtu(puc_rec_buf,uc_rec_len-2,0); //不包含crc校验
if(uc_func_code != lrc(puc_rec_buf,uc_rec_len))
{
return ;
}
}
else //modbus为rtu模式
{
if(CRC16(puc_rec_buf,uc_rec_len-2) != (puc_rec_buf[uc_rec_len-1]<<8 |puc_rec_buf[uc_rec_len-2]))//效验出错
{
return;
}
}
if(*(puc_rec_buf +1) != (uc_func_code = stMod_Master_OP[uc_op_table_pos].uc_cmd))//功能码不同
{
return;
}
uc_bytes = (uc_func_code == 0x01 || uc_func_code == 0x02)?((stMod_Master_OP[uc_op_table_pos].uc_lenth -1)/8+1):(stMod_Master_OP[uc_op_table_pos].uc_lenth*2);
if(uc_bytes != *(puc_rec_buf + 2)) //如果长度不同
{
return;
}
switch(uc_func_code) //功能码
{
#ifdef MB_MST_BIT_READ_EN
case MB_READ_COIL: //coil
case MB_READ_DISCRETE:
write_bit_by_plc(stMod_Master_OP[uc_op_table_pos].ui_mem_begin_addr,
stMod_Master_OP[uc_op_table_pos].uc_lenth,puc_rec_buf+3);
break;
#endif //**end(#ifdef MB_MST_BIT_READ_EN )
#ifdef MB_MST_REG_READ_EN
case MB_READ_HOLD_REG:
case MB_READ_INPUT_REG:
write_word_by_plc( stMod_Master_OP[uc_op_table_pos].ui_mem_begin_addr,
stMod_Master_OP[uc_op_table_pos].uc_lenth,puc_rec_buf+3);
break;
#endif //**end(#ifdef MB_MST_REG_READ_EN)
#ifdef MB_MST_REG_RW_EN
case MB_READ_WRITE_REG:
write_word_by_plc( stMod_Master_OP[uc_op_table_pos].ui_mem_begin_addr,
stMod_Master_OP[uc_op_table_pos].uc_lenth,puc_rec_buf+3);
break;
#endif //**end(#ifdef MB_MST_REG_RW_EN)
default:
break;
}
}
///////////////////////////////////////////////////////////////////////////////
//以下是自己发出了写PLC内部Word/bit的命令0x10/0x0F,组成发送数据串,返回串长度
///////////////////////////////////////////////////////////////////////////////
uchar rtu_modbus_master_send(uchar uc_op_table_xb,uchar uc_plc_address,uchar *puc_send_buf)
{
uchar uc_mid,uc_h,uc_l;
uint ui_mid,ui_mem_begin_addr;
UCHAR ucp_send_count = 0;
*(puc_send_buf + ucp_send_count++) = uc_plc_address; //address
uc_mid = stMod_Master_OP[uc_op_table_xb].uc_cmd;
*(puc_send_buf + ucp_send_count++) = uc_mid;//stMod_Master_OP[uc_op_table_xb].uc_cmd; //func code
ui_mid = stMod_Master_OP[uc_op_table_xb].ui_plc_begin_addr;
*(puc_send_buf + ucp_send_count++) = ui_mid >>8; //start address
*(puc_send_buf + ucp_send_count++) = (uchar)ui_mid;
switch(uc_mid)
{
case 0x01:
case 0x02:
case 0x03:
case 0x04:
*(puc_send_buf + ucp_send_count++) = 0;
*(puc_send_buf + ucp_send_count++) = stMod_Master_OP[uc_op_table_xb].uc_lenth;
break;
#ifdef MB_MST_BIT_WRITE_EN
case 0x05: //写单个位
*(puc_send_buf + ucp_send_count++) = rtu_read_bits(stMod_Master_OP[uc_op_table_xb].ui_mem_begin_addr,1)>0?0xff:0;
*(puc_send_buf + ucp_send_count++) = 0;
break;
case 0x0f://写多个位
uc_h = (stMod_Master_OP[uc_op_table_xb].uc_lenth-1)/8;
uc_l = (stMod_Master_OP[uc_op_table_xb].uc_lenth-1)%8;
*(puc_send_buf + ucp_send_count++) = 0;
*(puc_send_buf + ucp_send_count++) = stMod_Master_OP[uc_op_table_xb].uc_lenth;
*(puc_send_buf + ucp_send_count++) = uc_h + 1;
ui_mid = stMod_Master_OP[uc_op_table_xb].ui_mem_begin_addr;
for(uc_mid = 0;uc_mid < uc_h;uc_mid++)
{
*(puc_send_buf + ucp_send_count++) = rtu_read_bits( ui_mid+ uc_mid*8,8);
}
*(puc_send_buf +ucp_send_count++) = rtu_read_bits(ui_mid + uc_mid*8,uc_l+1);
break;
#endif //**end(#ifdef MB_MST_BIT_WRITE_EN)
#ifdef MB_MST_REG_WRITE_EN
case 0x06: //写单个寄存器
ui_mid = ui_RTU_ret_Word(stMod_Master_OP[uc_op_table_xb].ui_mem_begin_addr);
*(puc_send_buf + ucp_send_count++) = ui_mid>>8;
*(puc_send_buf + ucp_send_count++) = (uchar)ui_mid;
break;
case MB_WRITE_MULTI_REG: //写多个寄存器
*(puc_send_buf + ucp_send_count++) = 0;
*(puc_send_buf + ucp_send_count++) = stMod_Master_OP[uc_op_table_xb].uc_lenth;
*(puc_send_buf + ucp_send_count++) = stMod_Master_OP[uc_op_table_xb].uc_lenth<<1;
uc_l = stMod_Master_OP[uc_op_table_xb].uc_lenth;
ui_mem_begin_addr = stMod_Master_OP[uc_op_table_xb].ui_mem_begin_addr;
for(uc_mid=0;uc_mid<uc_l;uc_mid++)
{
ui_mid = ui_RTU_ret_Word( ui_mem_begin_addr+ uc_mid);
*(puc_send_buf + ucp_send_count++) = ui_mid>>8;
*(puc_send_buf + ucp_send_count++) = (uchar)ui_mid;
}
break;
#endif //**(#ifdef MB_MST_REG_WRITE_EN)
#ifdef MB_MST_REG_RW_EN
case 0x17: //写读多个寄存器
ui_mem_begin_addr = stMod_Master_OP[uc_op_table_xb].ui_write_plc_addr;
*(puc_send_buf + ucp_send_count++) = 0;
*(puc_send_buf + ucp_send_count++) = stMod_Master_OP[uc_op_table_xb].uc_lenth;//读的个数
*(puc_send_buf + ucp_send_count++) = ui_mem_begin_addr>>8; //写的开始地址
*(puc_send_buf + ucp_send_count++) = (uchar)ui_mem_begin_addr;
uc_l = stMod_Master_OP[uc_op_table_xb].uc_write_len;
*(puc_send_buf + ucp_send_count++) = 0; //写的数量
*(puc_send_buf + ucp_send_count++) = uc_l;
*(puc_send_buf + ucp_send_count++) = uc_l<<1; //写的字节数
ui_mem_begin_addr = stMod_Master_OP[uc_op_table_xb].ui_write_mem_addr;
for(uc_mid=0;uc_mid<uc_l;uc_mid++)
{
ui_mid = ui_RTU_ret_Word( ui_mem_begin_addr+ uc_mid);
*(puc_send_buf + ucp_send_count++) = ui_mid>>8;
*(puc_send_buf + ucp_send_count++) = (uchar)ui_mid;
}
break;
#endif //**end(#ifdef MB_MST_REG_RW_EN)
default:
break;
}
if(is_modbus_asc)
{
ucp_send_count = convert_rtu_to_ascii(puc_send_buf,ucp_send_count);
}
else
{
ui_mid = CRC16(puc_send_buf,ucp_send_count);//CRC效验,传的是数组的个数
*(puc_send_buf + ucp_send_count++) = ui_mid & 0x00ff;
*(puc_send_buf + ucp_send_count) = (uchar)(ui_mid>>8);
}
return(ucp_send_count); //返回的是下标,这是发送中断所确定的
}
//*******************************************************************
//**Purpose: 将modbus的rtu帧转化为asc码,rtu中不包含crc。
//**Entry: uc_bytes:--指定缓冲的字节数
//**Return: 返回的是下标,而不是字节数.
UCHAR convert_rtu_to_ascii(UCHAR* puc_buf,UCHAR uc_bytes)
{
UCHAR uc_pos,uc_index,uc_value,uc_lrc;
UCHAR* puc_src_buf,*puc_dst_buf;
UCHAR uc_temp_buf[comm_array_max_xb+1];
uc_pos = 0;
uc_lrc = lrc(puc_buf,uc_bytes);
puc_src_buf = puc_buf;
puc_dst_buf = uc_temp_buf;
uc_index = uc_bytes;
while(uc_index--)
{
*puc_dst_buf++ = *puc_src_buf++;
}
*(puc_buf + uc_pos++) = MB_HEAD_ASCII; //帧头
for(uc_index = 0;uc_index < uc_bytes;uc_index++)
{
uc_value = uc_temp_buf[uc_index];
*(puc_buf + uc_pos++) = HI_UCHAR_TO_HEX(uc_value);
*(puc_buf + uc_pos++) = LO_UCHAR_TO_HEX(uc_value);
}
*(puc_buf + uc_pos++) = HI_UCHAR_TO_HEX(uc_lrc);//lrc 高
*(puc_buf + uc_pos++) = LO_UCHAR_TO_HEX(uc_lrc);//lrc 低
*(puc_buf + uc_pos++) = MB_PRE_END_ASCII; //pre end
*(puc_buf + uc_pos) = MB_END_ASCII; //end
return uc_pos;
}
//***************************************************************
//**Purpose: 将modbus的ascii帧转化为rtu帧.不包含头.uc_is_crc为0无crc效验,否则有crc效验。
UCHAR convert_ascii_to_rtu(UCHAR* puc_buf,UCHAR uc_bytes,UCHAR uc_is_crc)
{
UCHAR uc_index;
UINT ui_crc;
UCHAR_PDATA uc_temp_buf[comm_array_max_xb+1];
UCHAR_PDATA * puc_src_buf,*puc_dst_buf;
puc_src_buf = puc_buf;
puc_dst_buf = uc_temp_buf;
uc_index = uc_bytes;
while(uc_index--)
{
*puc_dst_buf++ = *puc_src_buf++;
}
puc_dst_buf = puc_buf;
for(uc_index = 0;uc_index < uc_bytes;uc_index++)
{
*puc_dst_buf++ = MAKE_HEX_TO_DEC(uc_temp_buf[uc_index],uc_temp_buf[uc_index+1]);
uc_index++;
}
uc_bytes = uc_bytes / 2;
if(uc_is_crc)
{
ui_crc = CRC16(puc_buf,uc_bytes);
*puc_dst_buf++ = LO_UINT(ui_crc);
*puc_dst_buf = HI_UINT(ui_crc);
uc_bytes += 2;
}
return uc_bytes;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -