이하에는 첨부한 도면을 참조하여 본 발명의 바람직한 실시예에 따라 스윕 방식을 이용한 스펙트럼 분석 방법에 대해서 상세하게 설명한다.
도 1은 본 발명의 일 실시예에 따른 스윕 방식의 스펙트럼 분석 장치의 전기적인 블록 구성도이다.
도 1에 도시한 바와 같이, 본 발명에 따른 스윕 방식의 스펙트럼 분석 장치는 입력단자로부터 입력되는 RF 신호의 세기를 감쇠하기 위한 감쇠기(attenuator; 105)와, 감쇠기(105)에서 출력되는 신호를 증폭시키기 위한 증폭부(110)와, 증폭부(110)에서 출력되는 신호의 주파수 대역을 천이시키기 위한 위상고정루프(phase locked loop; PLL) 회로(170)와, 증폭부(110) 및 위상고정루프 회로(170)에서 각각 출력되는 신호들을 혼합하여 출력하는 믹서(mixer; 115)와, 믹서(115)에서 출력되 는 신호를 감쇠하기 위한 감쇠기(120)와, 감쇠기(120)에서 출력되는 신호에서 특정 범위의 주파수에 존재하는 신호를 통과시키는 대역통과필터(band pass filter; 125)와, 대역통과필터(125)에서 출력되는 신호를 증폭시키기 위한 증폭부(130)와, 증폭부(130)에서 출력되는 신호에서 특정 범위의 아주 좁은 대역(narrowband) 즉, 분해능 대역폭(resolution bandwidth; RBW)에 존재하는 신호를 통과시키는 협대역 필터(surfac acoustic wave(SAW) filter; 135)와, 협대역 필터(135)에서 출력되는 신호를 증폭시키기 위한 증폭부(140)와, 증폭부(140)에서 출력되는 신호의 전력을 로그 스케일(log scale) 값으로 변환하여 출력하는 로그 증폭부(log AMP; 145)와, 로그 증폭부(145)에서 출력되는 신호에서 낮은 대역의 신호를 통과시키는 로우패스필터(low pass filter; 155)와, 로우패스필터(155)에서 출력되는 신호 즉, 아날로그 신호를 디지털 신호로 변환하여 출력하는 ADC(analog to digital converter; 160)와, ADC(160)에서 출력되는 신호를 가지고 RF 신호의 스펙트럼을 분석하는 마이크로프로세서(165)를 포함하여 이루어질 수 있다.
이외에도, 본 발명에 따른 스윕 방식의 스펙트럼 분석 장치는 기준 클록신호(reference clock)에 기초하여 단일 주파수를 가지는 신호를 생성하여 PLL 회로(170)로 출력하는 다이렉트 디지털 신디사이저(direct digital synthesizer; DDS)(175)를 더 포함하여 이루어질 수 있다. 즉, 마이크로프로세서(165)는 DDS(175)를 제어하여, PLL 회로(170)에서 출력되는 신호의 주파수를 가변시키는 것이다.
주파수 분해능은 스윕 방식의 스펙트럼 분석 장치의 성능을 좌우하는 핵심 요소라고 할 수 있다. 다시 말해, PLL 회로(170)는 PLL 회로(170)에 주어지게 되는 파라미터에 의해 일정한 주파수 간격(fstep)대로 신호를 출력하게 된다. 즉, 주파수 간격이 스윕 방식의 스펙트럼 분석 장치의 주파수 분해능이라고 할 수 있다.
PLL 회로에서 출력되는 신호의 주파수(fPLL)는 다음 수학식 1로 표현된다.
여기서, f
OSC는 PLL 회로(170)로 입력되는 오실레이터(oscillator) 신호의 주파수이고, P, B, A 및 R은 정수형의 값이다. 즉, 주파수 간격(f
step)은
에 의해 결정된다고 볼 수 있다.
그런데, DDS(175)에서 생성되는 신호를 PLL 회로(170)의 기준 주파수 신호로 사용하게 되면, fOSC를 변경할 수 있게 되므로 주파수 분해능이 향상되는 즉, 주파수 간격이 조밀해질 수 있다는 장점이 있게 된다. 예를 들어, 100MHz 대역을 갖는 24bit DDS(175)는 100MHz/2^24 즉, 약 6Hz 간격마다 신호를 출력하게 된다. 이때, 위 수학식 1에서 R이 500이고 fOSC가 10MHz로 가정하면, 원래 PLL회로(170)가 가지는 주파수 간격은 20KHz인데 반해, DDS(175)를 사용하게 되면 6Hz/500 즉, 0.012Hz가 된다. 결국, DDS(175)를 사용하게 되면, 고주파수 대역의 주파수 분해능이 향상 된다.
또한, 스윕 방식의 스펙트럼 분석 장치에 있어서 마이크로프로세서(165)와 PLL 회로(170)는 일반적으로, 시리얼(serial) 방식으로 통신하게 된다. 즉, 마이크로프로세서(165)는 PLL 회로(170)에서 출력되는 신호의 주파수를 다음 단계의 주파수로 가변시키기 위하여, 보통 수십 비트의 데이터를 PLL 회로(170)로 출력하게 되는데, 시리얼 통신이다 보니 한 번에 한 비트씩 PLL 회로(170)로 출력하게 된다. 결국, 마이크로프로세서(165)와 PLL 회로(170) 간의 시리얼 통신은 고속 스윕의 저해 요소가 되고 있다. 반면, DDS(175)는 마이크로프로세서(165)와 병렬통신이 가능하도록 설계되어 있다. 따라서, 본 발명에 따르면 마이크로프로세서(165)는 DDS(175)를 제어함으로써 PLL 회로(170)의 출력 주파수를 빠르게 설정할 수 있게 된다.
한편, PLL 회로(170)는 DDS(175)로부터 입력되는 기준 주파수 신호가 바뀌게 되면, 그에 따라 출력되는 신호의 주파수를 가변하게 된다. 주지되어 있는 바와 같이, PLL 회로(170)는 출력되는 신호의 주파수를 피드백하여 오차를 보정함으로써 출력되는 신호의 주파수를 가변하는 것이다. 이때, 오차를 보정하는데 걸리는 시간을 일명, 안정화시간(lock time)이라고 한다.
스윕 방식의 스펙트럼 분석 장치가 임의의 주파수 대역(fspan)에 대해 스윕하는데 걸리는 전체 스윕 시간(tsweep)은 다음 수학식 2로 표현된다.
여기서, fstep은 PLL회로(170)의 주파수 간격이고, tPLL - lock은 PLL회로(170)의 안정화시간이다.
즉, 위 수학식 2를 통해 전체 스윕 시간은 안정화시간에 크게 의존하고 있음을 알 수 있다.
도 2는 스펙트럼 분석 장치로 입력되는 RF 신호의 주파수 특성을 설명하기 위한 그래프이다.
도 2에 도시한 바와 같이, 스펙트럼 분석 장치로 입력되는 RF 신호는 데이터 신호를 운반하는 캐리어(carrier) 신호와 잡음으로 볼 수 있는 피크(peak) 신호로 구분된다.
구체적으로, 캐리어 신호는 원신호인 데이터 신호와 의사잡음부호(pseudo noise code)가 혼합이 된 신호 즉, 원신호가 대역 확산(spread spectrum)이 된 신호를 일컫는다. 따라서, 캐리어 신호는 협대역 필터(135)가 통과시키는 주파수 대역 예컨대, 30KHz보다 대역폭이 크다. 예컨대, CDMA나 WCDMA에서의 데이터 신호는 노이즈에 강한 특성을 갖출 수 있도록 이와 같이 가짜 잡음이 혼합된 다음, 변조되고 있다.
결국, 도 2에 도시한 바와 같이 캐리어신호의 주파수 대역 중에서 단조증가 구간과 단조감소구간을 제외한 곳에서의 전력 증감은 가짜 잡음의 전력 변화를 나타내는 것으로 볼 수 있다. 즉, 본 발명은 신호의 스펙트럼 분석시 이러한 가짜 잡음의 전력 변화는 무시될 수 있다는 것을 주요한 핵심 포인트로 하고 있다.
반면, 피크 신호는 협대역 필터(135)가 통과시키는 주파수 대역보다 대역폭이 좁은 신호를 일컫는다. 예컨대, 주파수 성분이 하나인 정현파가 이런 특성을 보이고 있다.
도 3은 협대역 필터의 주파수 응답 특성을 보인 그래프인바, 협대역 필터를 통과하는 신호의 대역폭(BandFilter)은 다음 수학식 3으로 표현된다.
여기서, PowerPeak는 피크 지점(C)에서의 전력값이고, Q는 협대역 필터의 첨예도 일명, 큐(quality factor)를 나타내는 값이고, 분해능 대역폭(RBW)은 전력값이 Powerpeak의 절반 이상인 주파수 대역폭을 나타내는 값이다.
도 4는 본 발명의 일 실시예에 따른 스윕 방식을 이용한 스펙트럼 분석 방법을 설명하기 위한 흐름도이다.
본 발명에 따른 스윕 방식의 스펙트럼 분석 장치는 먼저, 단계 S11에서 안정화시간을 무시한 상태에서 신호의 전력 레벨을 산출하게 된다.
구체적으로, 협대역 필터(135)는 입력되는 신호에서 특정 범위의 주파수 대 역에 존재하는 신호를 통과시키게 된다. 그러면, 마이크로프로세서(165)는 ADC(160)로부터 입력되는 데이터에서 RBW에 해당하는 데이터를 획득하여 전력레벨을 산출하게 된다. 여기서, 마이크로프로세서(165)는 안정화시간 동안 기다린 후에 데이터를 획득하는 것이 아니라, PLL회로(170)의 출력 주파수를 가변시킨 후 곧바로 데이터를 획득하는 것이다. 이렇게 안정화시간을 무시한 상태에서 신호의 전력 레벨을 산출하게 되면, 안정화시간을 지킬 때보다 해당 주파수의 전력 값에는 오차가 있음은 분명하다. 그러나, 이러한 오차는 앞서 살펴본 바와 같이, 가짜 잡음의 전력 변화를 나타내는 것이므로 무시할 수 있는 수준이다.
다음으로, 단계 S13에서 마이크로프로세서(165)는 이렇게 산출한 전력값과 그 이전에 산출한 전력값을 비교하게 된다.
다음으로, 단계 S15에서 마이크로프로세서(165)는 위의 비교 결과를 토대로, 현재 전력레벨을 산출한 신호가 피크신호인지 혹은 캐리어신호인지 여부를 판단하게 된다.
예컨대, RBW가 30KHz이고 PLL회로의 주파수 간격이 10KHz라고 한다면, PLL회로(170)에서 출력되는 주파수의 순차적인 가변(상향 변환)에 따라 협대역 필터(135)를 n-1번째, n번째 및 n+1번째 통과하는 총 세 개(30/10)의 신호 간의 전력레벨 차이는 3dB이내이다. 즉, 마이크로프로세서(165)는 협대역 필터(135)를 n-1번째 통과한 신호가 그보다 앞서 통과한 n-2번째 신호의 전력레벨보다 미리 정해진 수치 예컨대, 3dB이상 크고, n+2번째 통과한 신호가 그보다 앞서 통과한 n+1번째 신호보다 미리 정해진 수치이상으로 작은 경우에는, 피크신호가 검출된 것으로 판 단하게 된다. 반면, n+2번째 신호와 n+1번째 신호 간의 전력레벨 차이가 3dB 이내인 경우에는 캐리어신호로 판단하게 된다.
단계 S15에서의 판단 결과, 현재 즉, n+2번째 전력레벨을 산출한 신호가 피크신호 구간에 해당하는 것이 아닌 캐리어신호로 판단된 경우에는 단계 S17로 진행한다. 다음으로, 단계 S17에서 마이크로프로세서(165)는 전 주파수 대역(fspan)에 대해 스펙트럼 분석을 수행하였는지 여부를 판단하게 된다. 단계 S17에서의 판단 결과, 전 주파수 대역에 대해 스펙트럼 분석을 마친 경우에는 PLL회로(170)의 출력 주파수 가변을 종료하고 반면, 전 주파수 대역에 대해 스펙트럼 분석을 마치지 못한 경우에는 단계 S19로 진행하여 PLL회로(170)가 다음 단계의 주파수로 상향 변환하여 출력하도록 PLL회로(170)에 제어신호를 보낸 다음 단계 S11 내지 단계 S15의 과정을 반복 수행하게 된다.
반면, 단계 S15에서의 판단 결과, 현재 즉, n+2번째 전력레벨을 산출한 신호가 피크신호 구간에 해당하는 경우에는 단계 S21로 진행한다. 즉, 단계 S21에서 마이크로프로세서(165)는 PLL회로(170)를 제어하여, PLL회로(170)의 출력 주파수를 피크신호의 시작점에 해당하는 이전 단계의 주파수로 하향 변환시킨다.
여기서, 피크신호를 검출한 지점 즉, n+2번째 지점으로부터 다시 전력레벨을 산출해야할 지점의 포인트 수(Preturn)는 다음 수학식 4로 표현된다.
여기서, 도 3을 참조하여 PLR은 A~B 구간의 포인트 개수이고, PLT는 B~C 구간의 포인트 개수이며, PRD는 C~E 구간 즉, BandFilter 구간 내에서의 최대 전력 지점(C)와 피크신호를 검출한 지점(E) 사이에 존재하는 포인트 개수를 나타내는 것이다.
다음으로, 단계 S23에서 마이크로프로세서(165)는 상기한 단계 S21을 수행한 다음, 안정화시간 동안 대기한 후 전력레벨을 산출한다.
그런 다음, 단계 S25에서는 단계 S23에서 전력레벨을 산출한 신호의 주파수 대역이 BandFilter 구간 즉, 저속 스윕 구간(A~F)에 존재하는지 여부를 판단하게 된다.
단계 S25에서의 판단 결과, 저속 스윕 구간인 경우에는 단계 S27로 진행하여 PLL회로(170)의 출력 주파수를 다음 단계의 주파수로 상향 변환시킨 다음, 단계 S23 및 S25의 과정을 반복하게 된다.
반면, 단계 S25에서의 판단 결과, 저속 스윕 구간을 전부 스윕한 경우에는 단계 S19로 진행하여 다음 단계의 주파수로 상향 변환시킨 다음, 단계 S11 내지단계 S15를 반복 수행하게 된다.
다음 표 1은 본 출원인이 도 1의 구성을 갖는 스펙트럼 분석 장치로 종래 방식대로 안정화시간을 지키면서 저속 스윕(normal sweep)했을 때와 본 발명에 따라 고속 스윕(fast sweep)하였을 때 걸린 총 스윕 시간(sweep time)을 나타낸 것이다.
fspan[MHz] |
총 스윕 시간[msec] |
고속 스윕 |
저속 스윕 |
피크신호 (mono tone) |
캐리어신호 (CDMA tone) |
피크신호/캐리어신호 (mono/CDMA tone) |
1.0 |
183.0 |
136.0 |
175.0 |
2.5 |
183.0 |
136.0 |
175.0 |
5.0 |
183.0 |
128.0 |
175.0 |
10.0 |
192.5 |
155.5 |
234.0 |
20.0 |
297.0 |
243.0 |
456.0 |
30.0 |
315.0 |
278.0 |
676.0 |
40.0 |
298.0 |
262.0 |
898.0 |
본 발명의 스윕 방식을 이용한 스펙트럼 분석 방법은 전술한 실시 예에 국한되지 않고 본 발명의 기술 사상이 허용하는 범위에서 다양하게 변형하여 실시할 수가 있다.
한편, 본 발명에 따른 스펙트럼 분석 방법을 실현시키기 위한 고속 스윕 알고리즘은 다음과 같다.
- 다 음 -
/*
;
; int sweepProcess();
;
; ver d3.01, 2008.05.12
; limsunglyong
;
; Innowireless co., ltd.
;
; 1. DDS Sweep Method.
;` 2. Peak Search Algorithm(Monotonic Increase/Decrease Detection) is used.
; 3. Peak Memory Method.
; 4. Peak Channel Power Offsetting.
;
*/
int sweepProcess()
{
int i = 0, j = 0;
long double ftwStartFreq = 0.0;
long double ftw = 0.0;
int port = 0;
long double scanStepSize = 0.0;
int sweepPoint = 0;
int sweepLoopPoint = 0;
float tempFloat = 0.0;
long int resultAdcCode = 0;
long int resultAdcCodeOld = 0;
unsigned long int baseDelayCount = 0;
int totalAvgNumber = 0;
int lockAvgNumber = 0;
int peakBandGap = 0;
smartSweepType smartSweep;
memset(adcBuffer, CLEAR, sizeof(adcBuffer));
// PLL lock check Informations setting.....................................
pllLockFailCount = CLEAR;
systemFlag.bit.pllLockFail = CLEAR;
//........................................................................
/***************************** PRE-SETTINGS ******************************/
rfPathSetting();
rfAttenSetting();
controlAdcPath(sweepInformation.vbwMode);
/*************************************************************************/
lockAvgNumber = LOCK_DELAY_AVG_N / (sweepInformation.vbwMode + 1);
port = (int)(sweepInformation.port * 0.5); // PORT 0 : TX, 1 : RX;
switch(port)
{
case PORT_CLASS_TX:
ftwStartFreq = sweepInformation.startFreq - (long double)INTERMEDIATE_FREQ;
//ftwEndFreq = sweepInformation.endFreq - (long double)INTERMEDIATE_FREQ;
break;
case PORT_CLASS_RX:
ftwStartFreq = sweepInformation.startFreq + (long double)INTERMEDIATE_FREQ;
//ftwEndFreq = sweepInformation.endFreq + (long double)INTERMEDIATE_FREQ;
break;
default: break;
}
/*
; * Note
; - To minimize excution latency time,
; 1. Following Codes are never does not excuted as external functions(sub routines).
; 2. Avoid using routine of loop structure.
;
*/
/* 0. Pre-Processing */
// Averaging Informations
if((avgInformation.avgMode != AVG_MODE_INSTANCE) && (avgInformation.avgNewCountFlag == TRUE))
{
// These codes are needed at
// 1. When, changed averaging mode.
// 2. When, changed averaging count number N
//avgInformation.avgNewCountFlag = CLEAR; // See below
avgInformation.currentAvgNumber = CLEAR;
avgInformation.currentAvgPointer = CLEAR;
avgInformation.currentSegmentAddr = CLEAR;
avgInformation.sweepPoint = CLEAR; /* Must be loaded (adequate value) at the end of function */
// ADC buffer Clear <- Watch Out!!! Why ?
memset((int *)&bufferOfAdc[0], CLEAR, sizeof(bufferOfAdc));
memset((int *)&autoLevel.bufferOfAdc[0], CLEAR, sizeof(autoLevel.bufferOfAdc));
}
if(avgInformation.avgMode != AVG_MODE_INFINITE)
{
// ADC buffer Clear <- Watch Out!!! Why ?
memset((int *)&bufferOfAdc[0], CLEAR, sizeof(bufferOfAdc));
memset((int *)&autoLevel.bufferOfAdc[0], CLEAR, sizeof(autoLevel.bufferOfAdc));
}
/****************************** PLL Setting ******************************/
controlPllRregister(pllRegisterValue[port].R, port);
controlPllBAregister(pllRegisterValue[port].B, pllRegisterValue[port].A, port);
/*************************************************************************/
/* Check BandWidth */
if(sweepInformation.sweepBand <= 0.0)
{
systemFlag.bit.protocolFail = SET;
return FALSE;
}
/* 3. Choose sweep point number N ****************************************/
/* Thus, split interval number is N -1 */
// Method 1. Sweep Point is N'x300 -> Band Fixed
//if(sweepInformation.sweepBand >= 60.00) sweepPoint = MAX_DATA_POINT; /* N = 2400 fixed */
//else
//{
// tempInt = (int)(sweepInformation.sweepBand / (long double)DESIRED_SCAN_STEP_SIZE);
/* Where tempInt is bar N */
// if((tempInt%FIXED_DATA_POINT) > 0)
// sweepPoint = (FIXED_DATA_POINT)*(int)(1 + tempInt/FIXED_DATA_POINT);
// else
// sweepPoint = (FIXED_DATA_POINT)*(int)(tempInt/FIXED_DATA_POINT);
//}
// Method 2. Fixed Step Size 16.6666KHz
//scanStepSize = FIXED_SCAN_STEP_SIZE;
if(sweepInformation.sweepMethod == SYSTEM_STEP_SIZE_MIXED)
{
if(sweepInformation.sweepBand <= DESIRED_SCAN_STEP_SIZE * (FIXED_DATA_POINT - 1))
{
scanStepSize = sweepInformation.sweepBand / (FIXED_DATA_POINT - 1);
// smartSweep.upThresholdLevel = 2.5 * (scanStepSize + 0.01) / SYSTEM_RBW * THRESHOLD_DELTA_FOR_SWEEP_DELAY;
// smartSweep.downThresholdLevel = -2.5 * (scanStepSize + 0.01) / SYSTEM_RBW * THRESHOLD_DELTA_FOR_SWEEP_DELAY;
smartSweep.upThresholdLevel = 2.0 * (scanStepSize + 0.01) / SYSTEM_RBW * smartSweepThresholdLevel;
smartSweep.downThresholdLevel = -2.0 * (scanStepSize + 0.01) / SYSTEM_RBW * smartSweepThresholdLevel;
}
else
{
scanStepSize = 0.020;
// smartSweep.upThresholdLevel = THRESHOLD_DELTA_FOR_SWEEP_DELAY;
// smartSweep.downThresholdLevel = -1 * THRESHOLD_DELTA_FOR_SWEEP_DELAY;
smartSweep.upThresholdLevel = smartSweepThresholdLevel;
smartSweep.downThresholdLevel = -1 * smartSweepThresholdLevel;
}
}
else// if(sweepInformation.sweepMethod == SYSTEM_STEP_SIZE_FIXED)
{
scanStepSize = DESIRED_SCAN_STEP_SIZE;
// smartSweep.upThresholdLevel = THRESHOLD_DELTA_FOR_SWEEP_DELAY;
// smartSweep.downThresholdLevel = -1 * THRESHOLD_DELTA_FOR_SWEEP_DELAY;
smartSweep.upThresholdLevel = smartSweepThresholdLevel;
smartSweep.downThresholdLevel = -1 * smartSweepThresholdLevel;
}
sweepInformation.scanStepSize = scanStepSize;
sweepPoint = (int)(sweepInformation.sweepBand/scanStepSize + 1);
/*************************************************************************/
/* 4. Step Size Calculation */
//scanStepSize = sweepInformation.sweepBand / (long double)(sweepPoint - 1);
// SAVE INFORMATIONS
sweepInformation.sweepPoint = sweepPoint;
/* START SWEEP ----------------------------------------------------------*/
ftw = ftwStartFreq;
/* Pre Running DDS */
setFreqDirectDds(ftw, port); delay1ms(10);
/* Base Delay Setup */
// baseDelayCount = DDS_SMART_BASE_DELAY;
if(sweepInformation.scanStepSize < 0.02)
{
baseDelayCount = (DDS_SMART_BASE_DELAY - 100);
}
else if(sweepInformation.sweepBand <= 10.0)
{
baseDelayCount = (DDS_SMART_BASE_DELAY * 2) * 30.0 / sweepInformation.sweepBand;
}
else if(sweepInformation.sweepBand <= 30.0)
{
baseDelayCount = DDS_SMART_BASE_DELAY * 30.0 / sweepInformation.sweepBand;
}
else if(sweepInformation.sweepBand <= 60.0)
{
baseDelayCount = (DDS_SMART_BASE_DELAY - 100) * 60.0 / sweepInformation.sweepBand;
}
else
{
baseDelayCount = (DDS_SMART_BASE_DELAY - 100);
}
/* Pre Warming ADC; for weak PCB */
adcConvStart(10);
/* Set Avgeraging Number N for each mode */
switch(avgInformation.avgMode)
{
case AVG_MODE_NORMAL:
totalAvgNumber = 1;
break;
case AVG_MODE_INFINITE:
totalAvgNumber = 1;
break;
case AVG_MODE_INSTANCE:
totalAvgNumber = avgInformation.avgNumber;
break;
default: systemFlag.bit.protocolFail = SET;
return FALSE;
break;
}
///////////////////////////////////////////////////////////////////////////
/////////////// VARIABLE SETTING FOR SMART SWEEP ALGORITHM ////////////////
///////////////////////////////////////////////////////////////////////////
// 0. Initialize Parameter & Variables
smartSweep.increaseLocation = CLEAR; // '0' Start position
smartSweep.decreaseLocation = CLEAR; // '0' Start position
smartSweep.increaseFlag = CLEAR;
smartSweep.decreaseFlag = CLEAR;
smartSweep.peakInBandPointNumber = CLEAR;
// 1. Set detection peak level for various VBW
switch(sweepInformation.vbwMode)
{
case VBW_1KHZ:
smartSweep.upThresholdLevel *= THRESHOLD_RATIO_VBW_1KHZ;
smartSweep.downThresholdLevel *= THRESHOLD_RATIO_VBW_1KHZ;
break;
case VBW_3KHZ:
smartSweep.upThresholdLevel *= THRESHOLD_RATIO_VBW_3KHZ;
smartSweep.downThresholdLevel *= THRESHOLD_RATIO_VBW_3KHZ;
break;
case VBW_10KHZ:
smartSweep.upThresholdLevel *= THRESHOLD_RATIO_VBW_10KHZ;
smartSweep.downThresholdLevel *= THRESHOLD_RATIO_VBW_10KHZ;
break;
default: break;
}
// 2. Back step margin point decision
smartSweep.backStepMargin = BACKSTEP_POINT_MARGIN;
smartSweep.backStepMargin += pow((DESIRED_SCAN_STEP_SIZE / sweepInformation.scanStepSize) * 2, 3);
// 3. Skip point decision
smartSweep.skipPointNumber = smartSweep.backStepMargin;
// 4. Unit Carrier Band Point for Peak Flag Release
smartSweep.unitCarrierBandPoint = 3 + (int)(3 * SYSTEM_RBW / sweepInformation.scanStepSize + 1.5); // 3(marginary number)
// 5. Noise Peak Band Gap
smartSweep.noisePeakBandGap = (int)(SYSTEM_RBW / sweepInformation.scanStepSize + 1);
// 6. delay
smartSweep.delay = baseDelayCount;
// 7. Velocity
smartSweep.velocity[0] = 0;
smartSweep.velocity[1] = 0;
// 8. Detection peak number
spectrumData.detectedPeakNumber = 0;
// 9. Saturation flag is being cleared.
// sweepInformation.saturationFlag = CLEAR;
// *. Initial conditions for power level
resultAdcCodeOld = adcConvStart(ADC_INTERNAL_AVG_N);
//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// START OF THE SMART SWEEP //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
for(sweepLoopPoint = 0; sweepLoopPoint < sweepPoint; sweepLoopPoint++)
{
// Peak Memory
if(smartSweep.peakInBandPointNumber == 0 && offsetPacket.peakPowerOffset[sweepLoopPoint] != 0.0)
{
delayLoop(THRESHOLD_SWEEP_DELAY_DDS);
}
else delayLoop(smartSweep.delay); // 0. Critical Delay for C.W. acquisition
// 0-1. Delay Number Clear
smartSweep.delay = baseDelayCount;
// 1. PLL Setup
// 2. PLL Lock Check
if(!checkPllLock(0)) return FALSE;//checkPllLock(port) - If Dual PLL is used.
// 3. VBW Delay :: Meaningless
vbwDelay(sweepInformation.vbwMode);
// 4. ADC Read
resultAdcCode = CLEAR;
if(smartSweep.peakInBandPointNumber || smartSweep.skipPointNumber)
{
//if(smartSweep.peakInBandPointNumber)
if((smartSweep.peakInBandPointNumber < (peakBandGap * 0.7)) && (smartSweep.peakInBandPointNumber > (peakBandGap * 0.3)))
{
resultAdcCode = (int)adcConvStart(totalAvgNumber + ADC_INTERNAL_AVG_N + lockAvgNumber);
offsetPacket.peakPowerOffset[sweepLoopPoint] = offsetPacket.peakPowerOffsetData;
}
else
{
resultAdcCode = (int)adcConvStart(totalAvgNumber + ADC_INTERNAL_AVG_N);
offsetPacket.peakPowerOffset[sweepLoopPoint] = 0.0;
}
}
else
{
resultAdcCode = (int)adcConvStart(totalAvgNumber + ADC_INTERNAL_AVG_N);
offsetPacket.peakPowerOffset[sweepLoopPoint] = 0.0;
}
// Next Setting Frequency /////////////////////////////////////////////
ftw = ftwStartFreq + scanStepSize * (sweepLoopPoint + 1);
setFreqDirectDds(ftw, port);
///////////////////////////////////////////////////////////////////////
switch(avgInformation.avgMode)
{
case AVG_MODE_NORMAL:
*(OnSystem.xRam + avgInformation.currentSegmentAddr + sweepLoopPoint) = resultAdcCode;
break;
case AVG_MODE_INFINITE:
*(OnSystem.xRam + sweepLoopPoint) = resultAdcCode;
break;
case AVG_MODE_INSTANCE:
bufferOfAdc[sweepLoopPoint] = resultAdcCode;
break;
default: break;
}
autoLevel.bufferOfAdc[sweepLoopPoint] = resultAdcCode;
smartSweep.velocity[1] = resultAdcCode - resultAdcCodeOld;
// Algorithm On!
if(smartSweep.skipPointNumber < 3 && smartSweep.peakInBandPointNumber < 3)
{
if(smartSweep.increaseFlag) // Do not use else if..
{
if(smartSweep.velocity[0] + smartSweep.velocity[1] < smartSweep.downThresholdLevel)
{
if(sweepLoopPoint > smartSweep.noisePeakBandGap + smartSweep.increaseLocation)
{
smartSweep.increaseFlag = CLEAR;
smartSweep.decreaseFlag = SET;
smartSweep.decreaseLocation = sweepLoopPoint;
smartSweep.peakInBandPointNumber = (smartSweep.decreaseLocation - smartSweep.increaseLocation + smartSweep.backStepMargin) * 2;
peakBandGap = smartSweep.peakInBandPointNumber;
sweepLoopPoint = smartSweep.increaseLocation - smartSweep.backStepMargin - 1;
if(sweepLoopPoint < -1) sweepLoopPoint = -1;
spectrumData.detectedPeakNumber++; // Detected Peak Number Count
ftw = ftwStartFreq + scanStepSize * (sweepLoopPoint + 1);
setFreqDirectDds(ftw, port);
}
}
else if(sweepLoopPoint > smartSweep.increaseLocation + smartSweep.unitCarrierBandPoint)
{
smartSweep.increaseFlag = CLEAR;
}
}
else
{
if(smartSweep.velocity[0] + smartSweep.velocity[1] > smartSweep.upThresholdLevel)
{
smartSweep.increaseFlag = SET;
smartSweep.decreaseFlag = CLEAR;
smartSweep.increaseLocation = sweepLoopPoint;
}
}
}
if(smartSweep.skipPointNumber == 0)
{
if(sweepInformation.sweepPoint - sweepLoopPoint < BACKSTEP_POINT_MARGIN)
{
//smartSweep.skipPointNumber = BACKSTEP_POINT_MARGIN;
smartSweep.delay += THRESHOLD_SWEEP_DELAY_DDS;
}
}
if(smartSweep.skipPointNumber && !smartSweep.peakInBandPointNumber)
{
smartSweep.delay += THRESHOLD_SWEEP_DELAY_DDS;
smartSweep.skipPointNumber--;
}
else if(smartSweep.peakInBandPointNumber)
{
smartSweep.delay += THRESHOLD_SWEEP_DELAY_DDS;
smartSweep.peakInBandPointNumber--;
}
// Updates for next Conditions
smartSweep.velocity[0] = smartSweep.velocity[1];
resultAdcCodeOld = resultAdcCode;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// END OF THE SMART SWEEP ///////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*
;
; AVERAGING ALGORITHM
;
; 0. AVG_MODE_INSTANCE : ADC averaging method.
; 1. AVG_MODE_NORMAL : Commercial spectrum analyzer averaging method(accumulation).
; 2. AVG_MODE_INFINITE : y(n) = {y(n-1) + x(n)} / 2;
;
;
; Usual averaging speed.
;
; AVG_MODE_INFINITE > AVG_MODE_NORMAL > AVG_MODE_INSTANCE
*/
switch(avgInformation.avgMode)
{
case AVG_MODE_NORMAL:
if((avgInformation.currentAvgNumber < AVG_MAX_NUMBER) && (avgInformation.currentAvgNumber < avgInformation.avgNumber))
{
avgInformation.currentAvgNumber++;
}
if(avgInformation.currentAvgPseudoNumber < avgInformation.avgPseudoNumber) avgInformation.currentAvgPseudoNumber++;
for(i = 0; i < sweepPoint; i++)
{
for(j = 0; j < avgInformation.currentAvgNumber + 1; j++)
{
bufferOfAdc[i] += *(OnSystem.xRam + sweepPoint * j + i);
}
}
tempFloat = 1.0 / (float)avgInformation.currentAvgNumber;
for(i = 0; i < sweepPoint; i++) bufferOfAdc[i] *= tempFloat;
/* End of Buffer Update */
// Averaging Informations for Next Time(not next sweep point)
avgInformation.sweepPoint = sweepPoint;
avgInformation.currentAvgPointer++;
avgInformation.currentAvgPointer %= avgInformation.avgNumber;
avgInformation.currentSegmentAddr = sweepPoint * avgInformation.currentAvgPointer;
/***************************** OUTSIDE LOOP ******************************/
break;
case AVG_MODE_INFINITE:
for(i = 0; i < sweepPoint; i++)
{
if(avgInformation.avgNewCountFlag) bufferOfAdc[i] = *(OnSystem.xRam + i);
else bufferOfAdc[i] = 0.5 * (bufferOfAdc[i] + *(OnSystem.xRam + i));
}
avgInformation.currentAvgNumber = avgInformation.currentAvgPseudoNumber = avgInformation.avgNumber;
break;
case AVG_MODE_INSTANCE:
avgInformation.currentAvgNumber = avgInformation.currentAvgPseudoNumber = avgInformation.avgNumber;
break;
default: break;
}
avgInformation.avgNewCountFlag = CLEAR;
// *. Stand By...
setFreqDirectDds(ftwStartFreq, port);
postProcessing();
return TRUE;
}