📄 ppia.h
字号:
//#define PPI_F_MASTER_SUCCESS 5
//上电的时候, step == PPI_F_MASTER_REQUIRED, 进入发送程序,发的实际上是DC me me ,step 变成 PPI_F_MASTER_SEND_DC,10ms后发
//10ms后发送请求,将OP表++,查发送指令后发送申请,step变成PPI_F_MASTER_REQUIRED从机若无反应(超时),则实际上回到上一步
//若接受到信息,则进入ppi_reqframe_anlys_master,
//应该是E5,发确认命令,step变成PPI_F_MASTER_ENTERED,若从机没反应(超时),发DC ME ME
//若不是E5,而是直接收到数据,则转入“收到数据:”
//若不是E5,什么也不发,step变成PPI_F_MASTER_ENTERED,从机定没反应(超时),发DC ME ME
//若收到数据:
//如果还是E5,step变成PPI_F_MASTER_E5AGAIN,则重新发10命令,若干次后重新发送DC ME ME,STEP变PPI_F_MASTER_ANSW_DC,并转换5C,7C
//若是数据,分析数据,step变成PPI_F_MASTER_SUCCESS,1MS后发DC ME ME
//*****************************************************************************************
//*****************************************************************************************
//**Purpose:当PPI为主时,分析接收帧,并根据接收帧作相应处理.
//**Entry: puc_rec_buf:---指向接收缓冲. uc_rec_len:---接收缓冲的长.uc_op_table_pos:指向发送命令表的下标。
//**当PPI为主时,接收帧有如下可能:
//** 1。返回E5,表示准备好命令,本机应该发送确认命令 10 ,PLC,ME,5C
//** 但返回2个E5,则忽略,发下个命令
//** 2。返回的是回复指令,如从PLC读数返回68,2x,2x,68,ME,PLC..... 向PLC写数返回68 12 12 68....
//** 3。异常:有两种,一个是E5反复发,一个是发 10,ME,PLC,02
//*****************************************************************************************
UCHAR ppi_reqframe_anlys_master(UCHAR uc_ch,UCHAR *puc_rec_buf,UCHAR *puc_send_buf,UCHAR uc_rec_len,UCHAR *uc_op_table_pos,
uchar me_address,uchar uc_plc_address,uchar *next_send_ms_count)
{
UCHAR uc_mid,uc_loop;
UCHAR ucp_send_count = 0;
UINT u16;
if(uc_ppi_master_step[uc_ch] == PPI_F_MASTER_REQUIRED)//刚才自己发的是请求命令,应该收到的是E5
{
//先写确认命令,只有PPI为MASTER时才调用,4.12后,收到连续两个E5,不再调用确认命令了
if((*puc_rec_buf == 0xe5))// && (uc_rec_len == 1))
{
uc_ppi_is_connect[uc_ch] = 1;
if(uc_ppi_acq_cmd_5c[uc_ch])//现在是确认指令,请求是5C,则确认是7C
{
uc_mid = 0x7c;
}
else
{
uc_mid = 0x5c;
}
uc_ppi_master_step[uc_ch] = PPI_F_MASTER_ENTERED;
*next_send_ms_count = 250; //本命令只发了5个字节,然后该收了,只要收到,则该变量会变255ms,如果没有反应了,则50ms后主发DC
return(ppi_send_command_10(puc_send_buf,me_address,uc_plc_address,uc_mid));
}
else if(*puc_rec_buf == 0x68)//发现是68,转到下面处理了
{
uc_ppi_master_step[uc_ch] = PPI_F_MASTER_ENTERED;
}
else//可能是10 me plc 02 不管他,直接发DC
{
//*puc_send_buf++ = 0xDC;
//*puc_send_buf++ = me_address;
//*puc_send_buf = me_address;
uc_ppi_master_step[uc_ch] = PPI_F_MASTER_REQUIRED;
*next_send_ms_count = 100; //本命令只发了5个字节,应该什么也收不到,50ms后主发DC
return(0xfe);
}
}
//不用else if 的原因是上面的程序要不就退出了或者跳转了,执行到这里,可能是上面发现了不发E5直接回复的现象
if((uc_ppi_master_step[uc_ch] == PPI_F_MASTER_ENTERED) || (uc_ppi_master_step[uc_ch] == PPI_F_MASTER_E5AGAIN)) //已经发过了确认命令了,现在接受来的应该是68,12,12(写),68,2x,2x,(读)
{
if((*puc_rec_buf == 0xe5) && (uc_rec_len == 1))//还来E5,发10,PLC,ME,7C/5C
{
if(++uc_ppi_EnterCount[uc_ch] >10)
{
uc_ppi_EnterCount[uc_ch] = 0; //计数器清除
*puc_send_buf++ = 0xDC;
*puc_send_buf++ = me_address;
*puc_send_buf = me_address;
uc_ppi_master_step[uc_ch] = PPI_F_MASTER_ANSW_DC;
*next_send_ms_count = 250; //本命令只发了3个字节,应该什么也收不到,50ms后主发确认,并把step = PPI_F_MASTER_E5AGAIN
return(2);
}
else
{
if(uc_ppi_acq_cmd_5c[uc_ch])//现在是确认指令,请求是5C,则此次就发5C,反转呼叫申请和确认的5C和7C
{
uc_mid = 0x5c;
uc_ppi_acq_cmd_5c[uc_ch] = 0;
}
else
{
uc_mid = 0x7c;
uc_ppi_acq_cmd_5c[uc_ch] = 1;
}
uc_ppi_master_step[uc_ch] = PPI_F_MASTER_E5AGAIN;
*next_send_ms_count = 250;
//应该收到68,或者E5
//50MS什么数也没收到的话,转主发了,并且发的实际上是DC
return(ppi_send_command_10(puc_send_buf,me_address,uc_plc_address,uc_mid));
}
}
//又来E5处理完毕了
if(*puc_rec_buf == 0x68)
{
if(stMod_Master_OP[*uc_op_table_pos].uc_cmd == PPI_READ_BYTE_REG)//我读PLC的数,要填写到我的表中
{
if(*(puc_rec_buf + 4) != me_address){return(0xfe);} //地址效验
puc_rec_buf += 3; //从第二个68开始
uc_rec_len -= 3; //长度跟着调整
if(*puc_rec_buf != 0x68){return(0xfe);} //是不是0x68
if(uc_rec_len < 24){return(0xfe);} //至少要有的长度
if(*(puc_rec_buf-1) != *(puc_rec_buf-2)){return(0xfe);}//有错
if(*(puc_rec_buf-1) <= 15){return(0xfe);}
if(uc_ppi_addtest(puc_rec_buf+1,uc_rec_len-3) != *(puc_rec_buf + uc_rec_len - 2)) //和效验
{
return(0xfe);
}
//以下效验也对了
//总的接受字节数量,注意以后是不是可能超过255
uc_mid = *(puc_rec_buf+13) - 4;
u16 = stMod_Master_OP[*uc_op_table_pos].ui_mem_begin_addr;
for(uc_loop = 0; uc_loop < uc_mid; uc_loop++)
{
PPI_write_singleReg(u16 + uc_loop, *(puc_rec_buf+ 22 + uc_loop));
}
}
//else我写PLC的数,返回应该是68,12,12,不管是不是,都发DC了
}
//全当成功了
*next_send_ms_count = 1;//50;
uc_ppi_master_step[uc_ch] = PPI_F_MASTER_SUCCESS;
return(0xfe);
//上两个分支的解释在上面
//也就是说当PPI_F_MASTER_ENTERED时,收到E5则发7C的确认命令,收到68,并且大约对就都不发了
//但若PPI_F_MASTER_E5AGAIN后再来E5,也不是68,则发DC,ME,ME
}
return(0xfe);//为了严谨
}
///////////////////////////////////////////////////////////////////////////////
//以下是自己发出了写PLC内部命令组成发送数据串,返回串长度
///////////////////////////////////////////////////////////////////////////////
uchar ppi_master_send(uchar uc_ch,uchar *uc_op_table_pos,uchar uc_plc_address,uchar *puc_send_buf,uchar me_address,uchar *next_send_ms_count)
{
uchar uc_mid,uc_loop,uc_count;
UCHAR ucp_send_count = 0;
unsigned long l16;
uint u16;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//进入本函数,有如下可能:
// 1:没响应 则由g_uc_commmain_send_count超时引起
// 分两种 (1)没PLC <- 我发了REQ命令
// (2)我发了DC me me命令
// 都在本函数中预设g_uc_commmain_send_count
// 2: 接收程序发送了DC me me命令,导致无响应,也由g_uc_commmain_send_count导致
// 在本函数中判断uc_ppi_master_step,看是谁导致的无响应
//
//能进入本函数,则必须发信息,因为进入本函数有可能是接收函数发了DC指令导致的没有响应,
//由接收函数g_uc_commmain_send_count设置的引起的超时,主程序中发送is_ppi_master_need_send
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uc_mid = uc_ppi_master_step[uc_ch];
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 主接收程序发DC ME ME 指令引发的没反应
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if(uc_mid == PPI_F_MASTER_ANSW_DC)
{
if(uc_ppi_acq_cmd_5c[uc_ch]) //上次请求命令是5C,则这次改为7C
{
uc_ppi_acq_cmd_5c[uc_ch] = 0;
uc_mid = 0x5c; //请求命令改为7C了,则确认命令发5C
}
else
{
uc_ppi_acq_cmd_5c[uc_ch] = 1;
uc_mid =0x7c;
}
uc_ppi_master_step[uc_ch] = PPI_F_MASTER_E5AGAIN;
*next_send_ms_count = 250; //无响应超时,PLC可能发E5,或者苏醒发68,XX,XX,68....都将在接受程序中处理了next_send_ms_count
//所以再进入本函数的话,那是没反应了,所以应该发DC
return( ppi_send_command_10(puc_send_buf,me_address,uc_plc_address,uc_mid) );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 发申请指令
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//先把OP表的指针++
if(uc_mid == PPI_F_MASTER_SEND_DC)
{
if(++(*uc_op_table_pos) >= OP_TABLE_LENTH){*uc_op_table_pos = 0;}
uc_mid = stMod_Master_OP[*uc_op_table_pos].uc_cmd;
if(uc_mid == PPI_READ_BYTE_REG)
{uc_count = 0x1b;}
else
{uc_count = 0x1f + stMod_Master_OP[*uc_op_table_pos].uc_lenth;}
*(puc_send_buf + ucp_send_count++) = 0x68;
*(puc_send_buf + ucp_send_count++) = uc_count;
*(puc_send_buf + ucp_send_count++) = uc_count;
*(puc_send_buf + ucp_send_count++) = 0x68;
*(puc_send_buf + ucp_send_count++) = uc_plc_address; //address
*(puc_send_buf + ucp_send_count++) = me_address;
if(uc_ppi_is_connect[uc_ch] == 0)
{
*(puc_send_buf + ucp_send_count++) = 0x6c;
uc_ppi_comm_count[uc_ch] = 2;
uc_ppi_is_connect[uc_ch] = 1;
}
else
{
uc_ppi_is_connect[uc_ch]++;
if(uc_ppi_is_connect[uc_ch] > 5)
{
if(uc_ppi_acq_cmd_5c[uc_ch]){uc_ppi_acq_cmd_5c[uc_ch]=0;}else{uc_ppi_acq_cmd_5c[uc_ch]=-1;}
uc_ppi_is_connect[uc_ch] = 1;
}
if(uc_ppi_acq_cmd_5c[uc_ch])//如果申请是5C,则确认是7C,否则反之
{
*(puc_send_buf + ucp_send_count++) = 0x5c;
}
else
{
*(puc_send_buf + ucp_send_count++) = 0x7c;
}
}
*(puc_send_buf + ucp_send_count++) = 0x32;
*(puc_send_buf + ucp_send_count++) = 0x01;
*(puc_send_buf + ucp_send_count++) = 0x00;
*(puc_send_buf + ucp_send_count++) = 0x00;
*(puc_send_buf + ucp_send_count++) = uc_ppi_comm_count[uc_ch];
*(puc_send_buf + ucp_send_count++) = uc_ppi_comm_count[uc_ch];
uc_ppi_comm_count[uc_ch] += 1;
*(puc_send_buf + ucp_send_count++) = 0x00;
*(puc_send_buf + ucp_send_count++) = 0x0e;
*(puc_send_buf + ucp_send_count++) = 0x00;
l16 =stMod_Master_OP[*uc_op_table_pos].ui_plc_begin_addr;
l16 *=8;
if(uc_mid == PPI_READ_BYTE_REG)
{
*(puc_send_buf + ucp_send_count++) = 0x00;
*(puc_send_buf + ucp_send_count++) = 0x04;
}
else
{
*(puc_send_buf + ucp_send_count++) =stMod_Master_OP[*uc_op_table_pos].uc_lenth + 4;
*(puc_send_buf + ucp_send_count++) = 0x05;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -