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

📄 sample20.c

📁 机械工业出版社 Lab Windows/CVI逐步深入与开发实例源代码
💻 C
字号:
#include <ansi_c.h>
#include <cvirte.h>		
#include <userint.h>
#include <utility.h>
#include <analysis.h>
#include <formatio.h>
#include "sample20.h"

typedef struct CalibrateData
{
   int      inputnum;           //输入测量点数
   double  *input;              //输入测量点的值,数据长度为inputnum
   char    inputunit[10];       //输入物理量的单位
   int      roundnum;           //测量的循环数
   char    outputunit[10];      //测量所得物理量的单位
   double  *output;             //测量的值,其排列顺序为:第一循环正行程,
                                //第一循环反行程,第二循环正行程,
                                //第二循环反行程,依次类推。数据长度为
                                // inputnum*2* roundnum
}CALIDATA;


static int panelHandle,logHandle;
CALIDATA cld;

int main (int argc, char *argv[])
{
	if (InitCVIRTE (0, argv, 0) == 0)	
		return -1;	
	if ((panelHandle = LoadPanel (0, "sample20.uir", PANEL)) < 0)
		return -1;
    
	//初始化变量
    cld.inputnum=0;
    cld.input=NULL;
    strcpy (cld.inputunit, "");
    cld.roundnum=0;
    strcpy (cld.outputunit, "");
    cld.output=NULL;
	
    //初始化运行可执行文件的句柄
    logHandle=-1;
	
	//启动切换任务功能
	EnableTaskSwitching ();
    
    DisplayPanel (panelHandle);
    RunUserInterface ();
    
    //关闭切换任务功能
    DisableTaskSwitching();

    //判断log.txt文件是否已经打开
    if(ExecutableHasTerminated(logHandle)==0)
    	//如果log.txt已经打开,关闭该文件
        TerminateExecutable (logHandle);
	//释放程序句柄
    RetireExecutableHandle (logHandle);

    return 0;
}

int CVICALLBACK PanelCallback (int panel, int event, void *callbackData,
		int eventData1, int eventData2)
{
	switch (event)
		{
		case EVENT_CLOSE:
			QuitUserInterface (0);
			break;
		}
	return 0;
}

int CVICALLBACK ReadDataCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	char filename[MAX_PATHNAME_LEN]; 
	int status,i,j;
    FILE *fp;
    double max,min,*temp1,*temp2,*temp3,*temp4,temp;
    int maxind,minind;
	double slope, intercept, mse;
	
	switch (event)
		{
		case EVENT_COMMIT:
	        //打开文件选择对话框
	        status = FileSelectPopup ("", "*.cld", "", "Open File",
			        				  VAL_LOAD_BUTTON, 0, 0, 1, 0, filename);
	        if(status<=0)  return 0;

			//打开文件,并读取数据
			fp = fopen (filename, "rb");
			fread (&cld.inputnum, sizeof(int), 1, fp);
			if(cld.input==NULL)
			  cld.input=malloc(sizeof(double)*cld.inputnum);
			else
			  cld.input = realloc (cld.input, sizeof(double)*cld.inputnum);
			fread (cld.input,sizeof(double),cld.inputnum,fp);
			fread (cld.inputunit,sizeof(char),10,fp);
			fread (&cld.roundnum, sizeof(int), 1, fp);
			fread (cld.outputunit,sizeof(char),10,fp);
			if(cld.output==NULL)
			  cld.output=malloc(sizeof(double)*cld.inputnum*2*cld.roundnum);
			else
			  cld.output = realloc (cld.output, sizeof(double)*cld.inputnum*2*cld.roundnum);
			fread(cld.output,sizeof(double),cld.inputnum*2*cld.roundnum,fp);
			fclose(fp);

			//设置图形控件X、Y轴的坐标名
			SetCtrlAttribute (panel, PANEL_GRAPH, ATTR_XNAME, cld.inputunit);
			SetCtrlAttribute (panel, PANEL_GRAPH, ATTR_YNAME, cld.outputunit);
			
			//删除控件GRAPH控件中所有曲线
			DeleteGraphPlot (panel, PANEL_GRAPH, -1, VAL_IMMEDIATE_DRAW);
			
			for(i=0;i<2*cld.roundnum;i++)
			for(j=0;j<cld.inputnum;j++)
				PlotPoint (panel, PANEL_GRAPH, cld.input[j],
						   cld.output[i*cld.inputnum+j], VAL_EMPTY_SQUARE, VAL_YELLOW);

			//为变量分配空间
			temp1 = malloc (sizeof(double)*cld.inputnum*2*cld.roundnum);
			temp2 = malloc (sizeof(double)*cld.inputnum*2*cld.roundnum);
			temp3 = malloc (sizeof(double)*cld.inputnum);
			temp4 = malloc (sizeof(double)*cld.roundnum*2*cld.inputnum);
			
			for(i=0;i<2*cld.roundnum;i++)
			  for(j=0;j<cld.inputnum;j++)
			   temp1[i*cld.inputnum+j]= cld.input[j];
			
			//线形拟合
			LinFit (temp1, cld.output, cld.inputnum*2*cld.roundnum, temp2,
					&slope, &intercept, &mse);
					
			SetCtrlVal (panel, PANEL_SLOPE, slope);
			SetCtrlVal (panel, PANEL_INTERCEPT, intercept);
			SetCtrlVal (panel, PANEL_MSE, mse);

			PlotLine (panel, PANEL_GRAPH, temp1[0], temp2[0],
					  temp1[cld.inputnum*2*cld.roundnum-1],
					  temp2[cld.inputnum*2*cld.roundnum-1], VAL_GREEN);

			//计算线形度
			for(i=0;i<cld.inputnum*2*cld.roundnum;i++)
			   temp1[i]=abs(temp2[i]-cld.output[i]);
			
			MaxMin1D (temp1, cld.inputnum*2*cld.roundnum, &max, &maxind, &min,
					  &minind);
			temp=max*100/(temp2[cld.inputnum*2*cld.roundnum-1]-temp2[0]);
			SetCtrlVal (panel, PANEL_LINEARITY, temp);

			//计算重复性误差
            for(j=0;j<cld.inputnum;j++)  
			{  
			max=0;
			min=2*temp2[cld.inputnum*2*cld.roundnum-1];
               for(i=0;i<2*cld.roundnum;i++)
			   {
			     if(max<cld.output[i*cld.inputnum+j])
			      max=cld.output[i*cld.inputnum+j];
			     if(min>cld.output[i*cld.inputnum+j])
			      min=cld.output[i*cld.inputnum+j];
			    }
			     temp3[j]=max-min;
			}
            MaxMin1D (temp3, cld.roundnum, &max, &maxind, &min,
						   &minind);
            temp=max*100/(temp2[cld.inputnum*2*cld.roundnum-1]-temp2[0]);
			SetCtrlVal (panel, PANEL_REFRAIN, temp);

			//释放内存
			free(temp1);
			free(temp2);
			free(temp3);
			free(temp4);
			break;
		}
	return 0;
}

int CVICALLBACK ViewLogCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	char str[200];
	int i,j,file;
	double temp;
	switch (event)
		{
		case EVENT_COMMIT:
        //调用OpenFile函数打开log.txt文件
        file = OpenFile ("log.txt", VAL_WRITE_ONLY, 
                       VAL_TRUNCATE, VAL_ASCII);

        //向log.txt文件写入标题
        sprintf(str, "Sensor Calibrate Result \n-------------------------------\n");
		WriteFile (file, str, StringLength(str));

        //向log.txt文件写入校定日期与时间
        sprintf(str, "Date : %s    Time %s \n\n", DateStr(), TimeStr());
		WriteFile (file, str, StringLength(str));		
		
        //向log.txt文件写入基准直线的斜率
        GetCtrlVal (panel, PANEL_SLOPE, &temp);
        sprintf(str, "Slope     :  %5.3f\n", temp);
		WriteFile (file, str, StringLength(str));
			
        //向log.txt文件写入基准直线的截距
		GetCtrlVal (panel, PANEL_INTERCEPT, &temp);
        sprintf(str, "\nIntercept :  %5.3f\n", temp);
		WriteFile (file, str, StringLength(str));

        //向log.txt文件写入基准直线与实际曲线的均方差
		GetCtrlVal (panel, PANEL_MSE, &temp);
        sprintf(str, "\nMse       :  %5.3f\n", temp);
		WriteFile (file, str, StringLength(str));

	    //向log.txt文件写入传感器的线形度
        GetCtrlVal (panel, PANEL_LINEARITY, &temp);
        sprintf(str, "\nLinearity :  %5.3f\n", temp);
		WriteFile (file, str, StringLength(str));

	    //向log.txt文件写入传感器的重复性误差
		GetCtrlVal (panel, PANEL_REFRAIN, &temp);
        sprintf(str, "\nRefain    :  %5.3f\n", temp);
		WriteFile (file, str, StringLength(str));

		//关闭文件
        CloseFile (file);
			
        //判断log.txt文件是否已经打开
        if(ExecutableHasTerminated(logHandle)==0)
		//如果log.txt已经打开,关闭该文件
	        TerminateExecutable (logHandle);

        //打开log.txt文件
	    LaunchExecutableEx ("C:\\WINDOWS\\NOTEPAD.EXE log.txt",
                            LE_SHOWNORMAL,&logHandle);
			
			break;
		}
	return 0;
}

int CVICALLBACK QuitCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	switch (event)
		{
		case EVENT_COMMIT:
			QuitUserInterface (0);
			break;
		}
	return 0;
}

int CVICALLBACK PrintGraphCallback (int panel, int control, int event,
		void *callbackData, int eventData1, int eventData2)
{
	//定义变量
	int status;
	switch (event)
		{
		case EVENT_COMMIT:
	        //打印直线拟合图
	        status=PrintCtrl (panel, PANEL_GRAPH, "a.bmp", ATTR_PAPER_WIDTH, 1);
    	
    		//判断打印是否成功并弹出消息框显示打印结果,
            //如果PrintCtrl函数返回值小于0,表示失败。
			if(status>=0)
			   MessagePopup ("Message", "Print Successfully!");
            else
               MessagePopup ("Message", "Print Failure!");
			break;
		}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -