📄 com.c
字号:
#include <utility.h>
#include <rs232.h>
#include <ansi_c.h>
#include <formatio.h>
#include <cvirte.h>
#include <userint.h>
#include "com.h"
static int panelHandle;
int str2sum(const char *string,char *lrc);
int send8(void);
int send2 (void) ;
int data_transform(char *databufft, char *reply) ;
int str2x(char *datain);
int transform4parts(char *part3, char *part2, char *part1, char *part0);
void read8(void);
void read2(void);
int ret=3;
int PLC_D0=0;
int PLC_D1=0;
int PLC_D2=3;
int PLC_D3=4;
int PLC_D4=5;
int PLC_D5=0;
int PLC_D6=0;
int PLC_D7=0;
int PLC_D8=0;
int PLC_D9=0;
int PLC_D10=0;
/* int PLC_M0=0;
int PLC_M1=0;
int PLC_M2=0;
int PLC_M3=0;
int PLC_M4=0;
int PLC_M5=0;
int PLC_M6=0;
int PLC_M7=0;
int PLC_M8=0;
int PLC_M9=0; */
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel (0, "com.uir", PANEL)) < 0)
return -1;
ret=OpenComConfig (1, "COM1", 9600, 2, 7, 1, 60, 60); //设置方式modbus通讯格式上有规定
if(ret!=0)MessagePopup ("提示", "串口打开失败!");
DisplayPanel (panelHandle);
RunUserInterface ();
ret = CloseCom (1);
if(ret!=0)MessagePopup ("提示", "串口关闭失败!");
DiscardPanel (panelHandle);
return 0;
}
int CVICALLBACK CallbackCancel (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
SetCtrlAttribute ( panelHandle, PANEL_TIMER, ATTR_ENABLED, 0);
QuitUserInterface (0);
break;
}
return 0;
}
int CVICALLBACK CallbackRead (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
SetCtrlAttribute (panelHandle, PANEL_TIMER, ATTR_ENABLED, 1);
break;
}
return 0;
}
int CVICALLBACK CallbackSend (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
SetCtrlAttribute (panelHandle, PANEL_TIMER, ATTR_ENABLED, 0);
GetCtrlVal (panelHandle, PANEL_D1, &PLC_D1);
GetCtrlVal (panelHandle, PANEL_D2, &PLC_D2);
GetCtrlVal (panelHandle, PANEL_D3, &PLC_D3);
GetCtrlVal (panelHandle, PANEL_D4, &PLC_D4);
GetCtrlVal (panelHandle, PANEL_D5, &PLC_D5);
GetCtrlVal (panelHandle, PANEL_D6, &PLC_D6);
GetCtrlVal (panelHandle, PANEL_D7, &PLC_D7);
GetCtrlVal (panelHandle, PANEL_D8, &PLC_D8);
GetCtrlVal (panelHandle, PANEL_D9, &PLC_D9);
GetCtrlVal (panelHandle, PANEL_D10, &PLC_D10);
send8();
send2() ;
break;
}
return 0;
}
int Ccom(char **order, int ordernum, char *data1, char *reply, int select_com)
{
int i=0;
char lrc[3]={0,0,0};
char send[60];
char receive[60];
int numwritten = 0;
strcpy(send,order[0]);
for(i=1; i<ordernum; i++)
{
strcat(send,order[i]);
}
if(data1 != 0)
{
strcat(send,data1);
}
str2sum(send,lrc);
strcpy(receive,":"); //3AH=": "
strcat(receive,send);
strcpy(send,receive);
strcat(send,lrc);
StringUpperCase(send);
strcat(send,"\r"); //0DH="\r"
strcat(send,"\n"); //0AH="\n"
i=strlen(send);
numwritten = ComWrt (select_com, send, i);
memset(reply, 0, 60);
return numwritten;
}
int str2sum(const char *string,char *lrc) //modbus规定的错误侦测检查码lrc的计算方法计算lrc
{
int convert(const char *string);
int i,j,result=0;
char temp[5]={0,0,0,0,0};
if(strlen(string)<2)return 0;
for(i=0;i<strlen(string)/2;i++)
{
for(j=0;j<2;j++)temp[j]=string[2*i+j]; //按两个字符+'\0'一组拆分字符串
temp[2]='\0';
result=result+convert(temp); //字符串(由两个字符组成)表示的16进制数求和
}
sprintf(temp,"%x",((result^(0xff))+1)); //将结果取反加1,结果以16进制小写形式输出。(^表示异或,%x表示16进制小写形式)
i=0;
if(strlen(temp)>=2) //如果temp的值大于两个字符,保留最低两位字符,舍去高位
{
while(temp[++i]);
lrc[0]=temp[i-2];
lrc[1]=temp[i-1];
lrc[2]=0;
/* i=0;
while(lrc[i])
{
if(lrc[i]>='a')lrc[i]=(lrc[i]-'a')+'A'; //小写转换成大写
i++;
} */
}
else //如果temp值只有一个字符,那高一位字符填"0",例如"0A"
{
lrc[0]='0';
lrc[1]=temp[0];
lrc[2]=0;
}
return 0;
}
int convert(const char *string) //把16进制内容的字符串变成相应的16进制数:"12\0" -->12
{
int i=0, j, l=1, m;
int *temp = NULL;
int result=0;
j=strlen(string);
temp = malloc(j*sizeof(int));
while(string[i]) //把字符变成数字
{
if(string[i]<'0'||(string[i]>'9'&&string[i]<'A')||(string[i]>'F'&&string[i]<'a')||(string[i]>'f'))
{
MessagePopup("提示","输入数字无效!");
return 0;
}
if(string[i]<'A'){temp[i]=string[i]-'0';} //0---9
else if(string[i]<'a'){temp[i]=string[i]-55;} //A---F
else {temp[i]=string[i]-87;} //a---f
i++;
}
i=0;
while(string[i]) //把数字变成16进制数(例如:1&2-->12)
{
m=i;
while(j-m-1){l=16*l;m++;}
result=result+temp[i]*l;
i++;
l=1;
}
free(temp);
temp = NULL;
return result;
}
int send8(void) //send pc data to plc
{
char *order[5] = {"00", "10", "1001", "0008", "10"}; //SlaveAddr+Fun+StartAddr+Number(个数)+ByteCount(字节数=个数×2)
char reply[60] = "\0";
char send_data[37] = "\0";
char replytemp[5] = "\0";
char datas[33];
char check[3];
sprintf(datas, "%x", PLC_D1);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcpy(send_data, replytemp);
sprintf(datas, "%x", PLC_D2);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcat(send_data, replytemp);
sprintf(datas, "%x", PLC_D3);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcat(send_data, replytemp);
sprintf(datas, "%x", PLC_D4);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcat(send_data, replytemp);
sprintf(datas, "%x", PLC_D5);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcat(send_data, replytemp);
sprintf(datas, "%x",PLC_D6);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcat(send_data, replytemp);
sprintf(datas, "%x", PLC_D7);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcat(send_data, replytemp);
sprintf(datas, "%x", PLC_D8);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcat(send_data, replytemp);
ret=Ccom(order, 5, send_data, reply, 1);
if(ret<0)MessagePopup ("提示", "数据写入出错!");
Delay(0.1);
ComRd(1, reply, 60);
check[0] = reply[11];
check[1] = reply[12];
check[2] = '\0';
/* if(strcmp(check, "06"))
{
MessagePopup("提示", "数据传输错误!");
Ccom(orders, 5, datasend, reply, 1);
Delay(0.1);
ComRd(1, reply, 60);
check[0] = reply[11];
check[1] = reply[12];
check[2] = '\0';
} */
return 0;
}
int data_transform(char *databufft, char *reply) //判断输入的数据是否超出PLC的寄存器的范围
{
char data_singleword[5] = "0000";
int i = 0;
if(strlen(databufft)>4)
{
return -1;
}
else
{
for(i=0; i<strlen(databufft); i++)
{
data_singleword[3-i] = databufft[strlen(databufft)-i-1];
}
data_singleword[4] = '\0';
strcpy(reply, data_singleword);
}
return 0;
}
int send2 (void)
{
char *orders[5] = {"00", "10", "1009", "0002", "04"};
char datasend[13] = "\0";
char reply[60] = "\0";
char replytemp[5] = "\0";
char datas[33];
char check[3];
sprintf(datas, "%x", PLC_D9);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcpy(datasend, replytemp);
sprintf(datas, "%x", PLC_D10);
if(data_transform(datas, replytemp) == -1)
{
MessagePopup("提示", "写PLC数据溢出");
}
strcat(datasend, replytemp);
ret=Ccom(orders, 5, datasend, reply, 1);
if(ret<0)MessagePopup ("提示", "数据写入出错!");
Delay(0.1);
ComRd(1, reply, 60);
check[0] = reply[11];
check[1] = reply[12];
check[2] = '\0';
/* if(strcmp(check, "02"))
{
MessagePopup("提示", "数据传输错误!");
Ccom(orders, 5, datasend, reply, 1);
Delay(0.1);
ComRd(1, reply, 60);
check[0] = reply[11];
check[1] = reply[12];
check[2] = '\0';
} */
return 0;
}
/*void read_M(void)
{
char *order[4] = {"00", "02", "0800", "000A"};
char datas[13] = "\0";
char datasend[13] = "\0";
char reply[60] = "\0";
char replytemp[5] = "\0";
unsigned char dicretionhigh = 0;
unsigned char dicretionlow = 0;
unsigned char dicretionex = 0;
Ccom(order, 4, 0, reply, 1);
Delay(0.1);
ComRd(1, reply, 60);
ProcessSystemEvents();
dicretionhigh = str2x(&reply[7]);
dicretionlow = str2x(&reply[8]);
dicretionex = str2x(&reply[10]);
PLC_M0 = (dicretionlow&0x01);
PLC_M1 = (dicretionlow&0x02)>>1;
PLC_M2 = (dicretionlow&0x04)>>2;
PLC_M3 = (dicretionlow&0x08)>>3;
PLC_M4 = (dicretionhigh&0x01);
PLC_M5 = (dicretionhigh&0x02)>>1;
PLC_M6 = (dicretionhigh&0x04)>>2;
PLC_M7 = (dicretionhigh&0x08)>>3;
PLC_M8 = (dicretionex&0x01);
PLC_M9 = (dicretionex&0x02)>>1;
} */
int str2x(char *datain) //字符变数值
{
int returnvalue = 0;
if(*datain >= 'A' && *datain < 'a' ) //如果是大写字母A---F的字符
{
returnvalue = *datain - ('A'-10); //变成数值10——15
}
else if(*datain >= 'a') //如果是小写字母a---f的字符
{
returnvalue = *datain - ('a'-10); //变成数值10——15
}
else
{
returnvalue = *datain - '0'; //否则是0---9的字符,变成数值0---9
}
return returnvalue;
}
int transform4parts(char *part3, char *part2, char *part1, char *part0) //把字符串表示的数,变成16进制数
{
int returnvalue = 0;
unsigned char part[4];
part[3] = str2x(part3); //字符变数值
part[2] = str2x(part2);
part[1] = str2x(part1);
part[0] = str2x(part0);
returnvalue = part[3]*pow(16, 3)+part[2]*pow(16, 2)+part[1]*pow(16, 1)+part[0]*pow(16, 0); //变成16进制数
return returnvalue;
}
int CVICALLBACK CallbackTimer (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_TIMER_TICK:
// read_M() ;
read8();
read2();
SetCtrlVal (panelHandle, PANEL_D1, PLC_D1);
SetCtrlVal (panelHandle, PANEL_D2, PLC_D2);
SetCtrlVal (panelHandle, PANEL_D3, PLC_D3);
SetCtrlVal (panelHandle, PANEL_D4, PLC_D4);
SetCtrlVal (panelHandle, PANEL_D5, PLC_D5);
SetCtrlVal (panelHandle, PANEL_D6, PLC_D6);
SetCtrlVal (panelHandle, PANEL_D7, PLC_D7);
SetCtrlVal (panelHandle, PANEL_D8, PLC_D8);
SetCtrlVal (panelHandle, PANEL_D9, PLC_D9);
SetCtrlVal (panelHandle, PANEL_D10, PLC_D10);
break;
}
return 0;
}
void read8(void)
{
char *order[4] = {"00", "03", "1001", "0008"}; //SlaveAddr+Fun+StartAddr+Number(个数)
char reply[60] = "\0";
ret=Ccom(order, 4, 0, reply, 1);
if(ret<0)MessagePopup ("提示", "指令写入出错!");
Delay(0.01);
ret=ComRd(1, reply, 60);
if(ret<0)MessagePopup ("提示", "数据读取出错!");
ProcessSystemEvents();
PLC_D1 = transform4parts(&reply[7], &reply[8], &reply[9], &reply[10]);
PLC_D2 = transform4parts(&reply[11], &reply[12], &reply[13], &reply[14]);
PLC_D3 = transform4parts(&reply[15], &reply[16], &reply[17], &reply[18]);
PLC_D4 = transform4parts(&reply[19], &reply[20], &reply[21], &reply[22]);
PLC_D5 = transform4parts(&reply[23], &reply[24], &reply[25], &reply[26]);
PLC_D6 = transform4parts(&reply[27], &reply[28], &reply[29], &reply[30]);
PLC_D7 = transform4parts(&reply[31], &reply[32], &reply[33], &reply[34]);
PLC_D8 = transform4parts(&reply[35], &reply[36], &reply[37], &reply[38]);
}
void read2(void)
{
char *order[4] = {"00", "03", "1009", "0002"};
char reply[60] = "\0";
ret=Ccom(order, 4, 0, reply, 1);
if(ret<0)MessagePopup ("提示", "指令写入出错!");
Delay(0.01);
ComRd(1, reply, 60);
if(ret<0)MessagePopup ("提示", "数据读取出错!");
ProcessSystemEvents();
PLC_D9 = transform4parts(&reply[7], &reply[8], &reply[9], &reply[10]);
PLC_D10 = transform4parts(&reply[11], &reply[12], &reply[13], &reply[14]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -