⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 com.c

📁 pc与plc通信程序
💻 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 + -