|
楼主 |
发表于 2013-12-12 17:03:38
|
显示全部楼层
本帖最后由 oldbeginner 于 2013-12-12 17:07 编辑
这是一个基于对话框的程序,
在对话框初始化函数,BOOL CAAADlg::OnInitDialog(),主要调用了
MODBUS_S_Init(3,CBR_9600,8,NOPARITY,ONESTOPBIT);
用来初始化MODBUS的
端口,9600,n,8,1(次序不一样)
/*************MODBUS_SERVER.cpp*****************************/
char MODBUS_S_Init(unsigned long xPort, unsigned long xBabd, unsigned char xDataSize,
unsigned char xParity, unsigned char xStopBit)
{
if(OpenPort(xPort,xBabd,xDataSize,xParity, xStopBit,4096,4096,1000))
{
return(1);
}
else
{
return(0);
}
}
又调用了OpenPort函数,
///打开串口////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool OpenPort(unsigned long xPort, unsigned long xBabd, unsigned char xDataSize,
unsigned char xParity, unsigned char xStopBit, unsigned long InputBuffSize,
unsigned long OutputBuffSize, unsigned long dwTimerOut)
{
设置事件();
取得串口字符();
打开通讯端口();
清理缓存器();
通讯成功();
}
感觉,比VB复杂,VB只要使用MSCOMM非常方便。
*************************************************************************
理解一下读命令的流程,
void CAAADlg::OnBRead()
{
发送读指令并接受返回();
判断是否为数字();
生成并发送命令();
文本显示();
}
**************************************************
发送读指令并接受返回()
short int ilist[200];
bool blist[200];
CString rtu,regadd,regcount,strtmp;
memset(ilist,0x00,200);
memset(blist,0x00,200);
m_rtu.GetWindowText(rtu);
m_regadd.GetWindowText(regadd);
m_regcount.GetWindowText(regcount);
搜一下,memset用法
http://blog.csdn.net/yangsen2016/article/details/1638503
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
然后,
if(rtu.IsEmpty())
{
MessageBox("PLC地址不能为空","MODBUS测试",MB_OK);
return;
}
else if(regadd.IsEmpty())
{
MessageBox("变量地址不能为空","MODBUS测试",MB_OK);
return;
}
else if(regcount.IsEmpty())
{
MessageBox("变量数量不能为空","MODBUS测试",MB_OK);
return;
}
常规判断
***************************************************
判断是否为数字()
unsigned short int i_regadd, i_regcount;
unsigned char i_rtu;
for(int i=0; i<rtu.GetLength(); i++)
{
if(isdigit(rtu[0])==0)
{
MessageBox("PLC地址不能为字符","MODBUS测试",MB_OK);
return;
}
}
i_rtu= atoi(rtu);
for(i=0; i<regadd.GetLength(); i++)
{
if(isdigit(regadd[0])==0)
{
MessageBox("变量地址不能为字符","MODBUS测试",MB_OK);
return;
}
}
i_regadd= atoi(regadd);
if(i_regadd > 50000 || i_regadd <= 0)
{
MessageBox("变量地址范围不正确","MODBUS测试",MB_OK);
return;
}
for(i=0; i<regcount.GetLength(); i++)
{
if(isdigit(regcount[0])==0)
{
MessageBox("变量数量不能为字符","MODBUS测试",MB_OK);
return;
}
}
i_regcount= atoi(regcount);
if(i_regcount > 200)
{
MessageBox("变量数量不能大于200","MODBUS测试",MB_OK);
return;
}
常规用法,确保数字有效
*******************************************************
生成并发送命令()
首先,生成显示的文字
char state= 0;
int nlength=m_r_text.GetTextLength();
m_r_text.SetSel(nlength, nlength);
m_r_text.ReplaceSel("发送数据\r\n");
然后,
if(i_regadd >= 40001 && i_regadd <= 49999)
{
state= MODBUS_S_ReadMultiRegD(i_rtu,i_regadd,i_regcount,ilist);
}
else if(i_regadd >= 10001 && i_regadd <= 19999)
{
state= MODBUS_S_ReadMultiRegM_1x(i_rtu,i_regadd,i_regcount,blist);
}
else if(i_regadd >= 1 && i_regadd <= 9999)
{
state= MODBUS_S_ReadMultiRegM(i_rtu,i_regadd,i_regcount,blist);
}
根据地址选择命令,因为使用了线圈,所以调用MODBUS_S_ReadMultiRegM函数,这个函数放在后面理解。
然后,
if(state==-1)
{
nlength=m_r_text.GetTextLength();
m_r_text.SetSel(nlength, nlength);
m_r_text.ReplaceSel("接收数据CRC检验失败\r\n");
}
else if(state==-2)
{
nlength=m_r_text.GetTextLength();
m_r_text.SetSel(nlength, nlength);
m_r_text.ReplaceSel("接收数据失败,无应答\r\n");
}
else
{
nlength=m_r_text.GetTextLength();
m_r_text.SetSel(nlength, nlength);
m_r_text.ReplaceSel("接收数据成功.\r\n");
}
根据返回值判断命令执行状况,需要配合调用的函数来理解。
最后,
CString str;
if(i_regadd >= 40001 && i_regadd <= 49999)
{
for(i=0; i<i_regcount; i++)
{
strtmp.Format("%d--%d\r\n", i_regadd+i,ilist);
str+= strtmp;
}
}
else
{
for(i=0; i<i_regcount; i++)
{
strtmp.Format("%d--%2x\r\n", i_regadd+i,blist);
str+= strtmp;
}
}
要读的数值放入str中
********************************************
文本显示()
nlength=m_r_text.GetTextLength();
m_r_text.SetSel(nlength, nlength);
m_r_text.ReplaceSel(str);
把str显示出
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|