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

📄 dlgdelayselect.cpp

📁 本程序是在vc6.0开发环境
💻 CPP
字号:
// DlgDelaySelect.cpp : implementation file
//

#include "stdafx.h"
#include "FMDM.h"
#include "DlgDelaySelect.h"
#include "math.h"
#include <visa.h>
#include <iostream>
#include <stdlib.h>
#include <conio.h>


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
ViSession defaultRM, vi;
ViStatus viStatus = 0;
HANDLE hcom;
int centerFreq;//由张伟给我
short myByte[2000];//串口接收缓冲
BYTE delay;
int ntime=1;
double FreqNarrowFmdm;
double VoltNarrowFmdm;
double m_fVcoVolt[257],m_fMfVolt[257];
double fMinVcoVolt[257];
double freqvco,freqmf;



//数组排序函数
void  ArraySort(short int *pArray,int N);
void setfreq(double centerfreq);
double CacuCenterfreqLog(short *pArray,int N,int RecAverage);
bool OnWideFmdm();
void OnNarrowFmdm();
int FindLocationMinDif(double *FindFreqMinDif,int N);


/////////////////////////////////////////////////////////////////////////////
// CDlgDelaySelect dialog


CDlgDelaySelect::CDlgDelaySelect(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgDelaySelect::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgDelaySelect)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	
}


void CDlgDelaySelect::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgDelaySelect)
	DDX_Control(pDX, IDC_COMBO1, m_Combo);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgDelaySelect, CDialog)
	//{{AFX_MSG_MAP(CDlgDelaySelect)
	ON_CBN_SELCHANGE(IDC_COMBO1, OnSelchangeCombo1)
	ON_BN_CLICKED(ID_LOCKFREQ, OnLockfreq)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgDelaySelect message handlers

BOOL CDlgDelaySelect::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CDlgDelaySelect::OnSelchangeCombo1() 
{
	// TODO: Add your control notification handler code here
	int nIndex=m_Combo.GetCurSel();
	delay=nIndex;
}

void CDlgDelaySelect::OnLockfreq() //发送延迟线选择命令在此进行。清空缓冲区等也在此进行。
{ 
		
	//创建串口
	hcom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hcom!=INVALID_HANDLE_VALUE)
	{
    SetupComm(hcom,2,2);
    DCB myDCB;
    GetCommState(hcom,&myDCB);
    myDCB.BaudRate=CBR_38400;
    myDCB.fBinary=TRUE;//API只支持二进制方式。
    myDCB.fParity=FALSE;
    myDCB.ByteSize=8;
    myDCB.StopBits=ONESTOPBIT;
    SetCommState(hcom,&myDCB);
	}
    else
	{
		AfxMessageBox("创建串口失败");
		exit(0);
	}
	byte sendbyte;  //发送缓冲
	sendbyte=0x00;
	sendbyte=(sendbyte<<5) | delay;			
	WriteFile(hcom,&sendbyte,1,NULL,NULL);

	

	
//调用姜杰的函数
//	ctrCWorPM(0);暂时定义0对应脉冲调制的。1对应连续波。

	


	//第一次扫频操作
	double logsweptfreq[101];//存储扫频频率列表的
	for(int li=0;li<=100;li++)
	{
		logsweptfreq[li]=11.2e09-1e08+li*2e06;
	}

	//存储LOG鉴频数据的
	short int logdata[101];
	
	for(int ln=0;ln<=100;ln++)
	{ 
			
		//清空接收缓冲区
		PurgeComm(hcom,PURGE_RXCLEAR);

		viPrintf(vi, "FREQ %f\n",logsweptfreq[ln]);

		//延迟30ms
		Sleep(30);

		DWORD dwErrors;
		COMSTAT Rcs;

		//获得串口状态
		ClearCommError(hcom,&dwErrors,&Rcs); 
		
		if(Rcs.cbInQue>=2)
		{
		  ReadFile(hcom,&myByte,2,NULL,NULL);	               	
		  logdata[ln]=((myByte[0]<<8)|(myByte[1]));
		}
	    else
		{
		   AfxMessageBox("串口接收有问题");
		   exit(0);
		}
	}
	short int copyData[101];//复制的数组
	memcpy(copyData,logdata,101);
	//冒泡排序
	ArraySort(copyData,101);  
	int average;
	int sum=0;
	int kIndex;
	for(kIndex=0;kIndex<20;kIndex++)
	{
	  sum=sum+copyData[kIndex];
	}
	average=sum/20;
    centerFreq=CacuCenterfreqLog(logdata,10,average);
    setfreq(centerFreq);

	//调用姜杰的函数
	//ctrCWorPM(1);暂时定义0对应脉冲调制的。1对应连续波。

    //调用窄带数据接收处理函数

}


//全局函数ArraySort、setfreq、CacuCenterfreqLog
//以下为数组排序函数
void  ArraySort(short int *pArray,int N)
{
  int nround;
  int j;
  for (nround=0;nround<N-1;nround++)
	for (j=0;j<N-nround-1;j++) 
	{
	  if (pArray[j]<pArray[j+1])
	  {
		int iExchange=pArray[j];
		pArray[j]=pArray[j+1];
		pArray[j+1]=iExchange;
	  }
	}
}
void setfreq(double centerfreq)
{
	double cwfreq;
	cwfreq=centerfreq;
	viPrintf(vi, "FREQ %f\n",cwfreq); // Set the source CW frequency for 500 kHz
	viPrintf(vi, "POW:AMPL -2.3 dBm\n"); // Set the power level to -2.3 dBm
	//printf("Source power (dBm) is : %s\n", rdBuffer); // Print the power level
	viPrintf(vi, "OUTP:STAT ON\n"); // Turn source RF state on
}

double CacuCenterfreqLog(short int *pArray,int N,int RecAverage)
{   
	int j=0;
	int k=0;
	int calcenterfrequency;
	for (int i=0;i<=100;i++)
	{
		if (pArray[i]<1/2*RecAverage && pArray[i+1]>1/2*RecAverage)
		{
			j=i;
		}
		if (pArray[i]>1/2*RecAverage && pArray[i+1]<1/2*RecAverage)
		{
		 k=i;
		}
	}
	calcenterfrequency=(1/2*(k-j)+j)*1e06+11.2e09-1e08;
		
	return calcenterfrequency;	
}



//宽带接收函数
bool OnWideFmdm()
{   
    //调用姜杰的函数。
	//ctrCWorPM(0);暂时定义0对应脉冲调制的。1对应连续波。

	byte sendbyte;
	sendbyte=0x02;//使鉴频器
	sendbyte=(sendbyte<<5) | delay;
	WriteFile(hcom,&sendbyte,1,NULL,NULL);
	//以上设置确保延迟线选择以及通道选择同时工作。

	//扫频。
    double widesweptfreq[21];
    for(int mfn=0;mfn<=20;mfn++)
	{
		//由对数放大已经令其与真实频率相差2MHz范围以内。每次以2次方递减。
		widesweptfreq[mfn]=11.2e09-5.12e06/ntime+mfn*(5.12e06/ntime)/20;
	}
	
    short int widedataafterpd[21];//为数据调整后的数据。
	double freqwideafterpd[21];
	for(mfn=0;mfn<=20;mfn++)
	{   
		PurgeComm(hcom,PURGE_RXCLEAR);//清空缓冲区
		viPrintf(vi, "FREQ %f\n",widesweptfreq[mfn]);
		Sleep(15);
		ReadFile(hcom,&myByte,2,NULL,NULL); 
		widedataafterpd[mfn]=myByte[0]<<8|myByte[1];
		double difwide_mwide[257];
		for (int nMf=0;nMf<257;nMf++)
		{
			difwide_mwide[nMf]=abs(widedataafterpd[mfn]-m_fMfVolt[nMf]);
		}
		//找出在宽带列表里的对应位置。
		freqwideafterpd[mfn]=750e06-2.56e06+20e03*FindLocationMinDif(difwide_mwide,257);
	}
	double DifFreqMFVco[21];
	for (int n=0;n<21;n++)
	{
		DifFreqMFVco[n]=freqwideafterpd[n]-freqvco;		
	}
	double needfreqagilent;
	//找出上步找出的21个位置中离VCO最近的点。并将安捷伦信号源设定为对应的频率。
	needfreqagilent=widesweptfreq[FindLocationMinDif(DifFreqMFVco,21)];
    setfreq(needfreqagilent);
   	//以下判断是否满足锁相条件是否还需要继续调整信号源频率
	if (!(DifFreqMFVco[FindLocationMinDif(DifFreqMFVco,21)]-100e03<0))//小于100K即满足条件
	{  ntime=ntime<<1;
	   if (ntime==16)
	   {
		   AfxMessageBox("未锁定");
		   viClose(vi);
	       viClose(defaultRM);
		   CloseHandle(hcom);
		   return 0;
	   }
	   else	   
	   OnNarrowFmdm();		   
	}                
	else
	{
	   viClose(vi);
	   viClose(defaultRM);
	   CloseHandle(hcom);
	   return true;
	}
}
//宽带接收函数



//以下为窄带接收函数
void OnNarrowFmdm()
{
	//调用姜杰的函数。
	//ctrCWorPM(1);暂时定义0对应脉冲调制的。1对应连续波。



	//结合VHDL程序仔细考虑发送的数据
	byte sendbyte;
	sendbyte=0x01;
	sendbyte=(sendbyte<<5) | delay;
	WriteFile(hcom,&sendbyte,1,NULL,NULL);
	PurgeComm(hcom,PURGE_RXCLEAR);//清空缓冲区
	//以上设置确保延迟线选择以及通道选择同时工作。
	Sleep(15);
	int vcovoltdata;//为数据调整后的数据。
    ReadFile(hcom,&myByte,2,NULL,NULL);               
    //串口接收的数据已经成功读出,并存放在myByte数组中。
	//可以在这里加入处理数据的代码例如数据拼接.扫频设置在下面根据I值设定
	//字节1左移8位跟字节2或后获得一完整数据。
	vcovoltdata=((myByte[0]<<8)|(myByte[1]));
    
    //根据VCO测得的数据得到最接近的位置。
	for(int nVco =0; nVco < 257; nVco ++)
	{
		fMinVcoVolt[nVco] = abs(m_fVcoVolt[nVco] - vcovoltdata);
	}
	//FindLocationMinDif找出与测得的VCO数据最接近的VCO数据列表中的位置
	//以750MHz为中心,AD有效位为>=8。列表中取左右2.56MHz,频率间隔20KHz
	freqvco=750e06-2.56e06+FindLocationMinDif(fMinVcoVolt,257)*20e03;
	//调用窄带必须调用宽带
	OnWideFmdm();
}
//以上为窄带接收函数

//以下函数找出最小值所在的位置
int FindLocationMinDif(double *pArray,int N)
{   
	int vcolocation=0;
	double minelement=pArray[0];
	for(int vn=0;vn<N-1;vn++)
	{
		if (pArray[vn]<minelement)
		{
		   minelement=pArray[vn];
		   vcolocation=vn;
		}
	}
	return vcolocation;
}

⌨️ 快捷键说明

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