📄 procsignal.c
字号:
#include <p30f6014.h>
#include <dsp.h>
#include "common.h"
#include "codec.h"
#include "menu.h"
#include "timers.h"
#include "gettime.h"
#include "tables.h"
#define SECSYNCBUF_LENGTH 150
#define RAWDATABUF_LENGTH (150/5)
#define SYNDATA_FILTER_DELAY 21
#define DATA_FILTER_DELAY 21
#define TIC_QUALITY_LIM1 5
#define TIC_QUALITY_LIM2 10
#define MIN_QUALITY_LIM 5
#define MAX_LIMIT 500
//定义于AsmUtils.s
extern void CalcABS( unsigned int Size, fractional* pIn);
extern void CalcLpIir( unsigned int Size, int* pIn,
fractional* pLPVal, unsigned int LPK);
int TicPos;
int SecSyncBuf[SECSYNCBUF_LENGTH];
int RawDataBuf[RAWDATABUF_LENGTH+1];
char MinSyncQuality;
static unsigned int page;
static int TicLastPos;
static int TicQuality;
static int SecSyncPtr;
static int MinSyncave;
static int Dec2Buf[PROC_BLOCK_SIZE/2];
static int Buf100[PROC_BLOCK_SIZE/(2*4)];
static unsigned long MinuteSyncSignal;
static unsigned long MinuteSyncNoise;
static fractional* offset;
static fractional EarlyAve;
static fractional LateAve;
static FIRStruct fDec2LP1800;
static FIRStruct fBPTic;
static FIRStruct fDec4LP200;
static FIRStruct fDec4LP110;
static FIRStruct fDec2LP110;
static FIRStruct fBP100;
static fractional DelayDec2LP1800[DEC2LP1800_SIZE] __attribute__ ( (__section__(".ybss")) );
static fractional DelayBPTic[BPTIC_SIZE] __attribute__ ( (__section__(".ybss")) );
static fractional DelayDec4LP200[DEC4LP200_SIZE] __attribute__ ( (__section__(".ybss")) );
static fractional DelayDec4LP110[DEC4LP110_SIZE] __attribute__ ( (__section__(".ybss")) );
static fractional DelayDec2LP110[DEC2LP110_SIZE] __attribute__ ( (__section__(".ybss")) );
static fractional DelayBP100[BP100_SIZE] __attribute__ ( (__section__(".ybss")) );
void InitProcSignal( void );
void ProcInput( fractional* pIn);
void FindSecSync(void);
void FindMinSync(void);
char CalcBit(void );
static void CalcClockError(void);
//初始化信号处理模块
void InitProcSignal( void)
{
int i;
asm("mov #psvpage(_DEC2LP1800),w0\nmov w0,_page");
asm("mov #psvoffset(_DEC2LP1800),w0\nmov w0,_offset");
FIRStructInit(&fDec2LP1800,DEC2LP1800_SIZE, offset, page, DelayDec2LP1800);
FIRDelayInit(&fDec2LP1800);
if(SemB.WWV)
{
asm("mov #psvpage(_BPTIC1000),w0\nmov w0,_page");
asm("mov #psvoffset(_BPTIC1000),w0\nmov w0,_offset");
}
else
{
asm("mov #psvpage(_BPTIC1200),w0\nmov w0,_page");
asm("mov #psvoffset(_BPTIC1200),w0\nmov w0,_offset");
}
FIRStructInit(&fBPTic, BPTIC_SIZE, offset, page, DelayBPTic);
FIRDelayInit(&fBPTic);
asm("mov #psvpage(_DEC4LP200),w0\nmov w0,_page");
asm("mov #psvoffset(_DEC4LP200),w0\nmov w0,_offset");
FIRStructInit(&fDec4LP200,DEC4LP200_SIZE, offset, page, DelayDec4LP200);
FIRDelayInit(&fDec4LP200);
asm("mov #psvpage(_DEC4LP110),w0\nmov w0,_page");
asm("mov #psvoffset(_DEC4LP110),w0\nmov w0,_offset");
FIRStructInit(&fDec4LP110,DEC4LP110_SIZE, offset, page, DelayDec4LP110);
FIRDelayInit(&fDec4LP110);
asm("mov #psvpage(_DEC2LP110),w0\nmov w0,_page");
asm("mov #psvoffset(_DEC2LP110),w0\nmov w0,_offset");
FIRStructInit(&fDec2LP110,DEC2LP110_SIZE, offset, page, DelayDec2LP110);
FIRDelayInit(&fDec2LP110);
asm("mov #psvpage(_BP100),w0\nmov w0,_page");
asm("mov #psvoffset(_BP100),w0\nmov w0,_offset");
FIRStructInit(&fBP100, BP100_SIZE, offset, page, DelayBP100);
FIRDelayInit(&fBP100);
TicPos = 0;
SecSyncPtr = 0;
for(i=0; i<SECSYNCBUF_LENGTH; i++)
SecSyncBuf[i] = 0;
for(i=0; i<RAWDATABUF_LENGTH+1; i++)
RawDataBuf[i] = 0;
SemA.SecLocked = FALSE;
SemA.MinLocked = FALSE;
EarlyAve = 0;
LateAve = 0;
MinSyncQuality = 0;
MinuteSyncSignal = 0;
MinuteSyncNoise = 0;
}
//对输入信号进行处理
void ProcInput( fractional* pIn)
{
int i;
int j;
//欠采样从7200sps到3600sps
FIRDecimate( PROC_BLOCK_SIZE/2, Dec2Buf, pIn, &fDec2LP1800, 2);
//欠采样从3600sps 到 900sps
FIRDecimate( PROC_BLOCK_SIZE/(2*4), Buf100, Dec2Buf, &fDec4LP110, 4);
// 带通滤波器过滤3600sps数据流以获得1KHz信号
FIR( PROC_BLOCK_SIZE/2, Dec2Buf, Dec2Buf, &fBPTic);
//校正调制信号到1KHz
CalcABS( PROC_BLOCK_SIZE/2, Dec2Buf); //
//欠采样调制信号到900 sps
FIRDecimate( PROC_BLOCK_SIZE/(2*4), Dec2Buf, Dec2Buf, &fDec4LP200, 4);
if(SemA.SecLocked) //如果秒锁上则获取分同步能量
{
if(SecSyncPtr > 3 )
{
if(SecSyncPtr < (SECSYNCBUF_LENGTH*8)/10 )
{ //在秒脉冲同步缓冲的首800毫秒的平均能量
for(i=0; i<PROC_BLOCK_SIZE/(2*4); i++)
MinuteSyncSignal = MinuteSyncSignal + (unsigned long)Dec2Buf[i];
}
else
{ //在秒脉冲同步缓冲的最后200毫秒的平均能量
for(i=0; i<PROC_BLOCK_SIZE/(2*4); i++)
MinuteSyncNoise = MinuteSyncNoise + (unsigned long)Dec2Buf[i];
}
}
}
else
{
MinuteSyncSignal = 0;
MinuteSyncNoise = 0;
}
//对校正的1KHz脉冲进行每一个单独的时间位进行低通处理并放入SecSyncBuf
// 做PROC_BLOCK_SIZE/(2*4) 次采样,将它们放入SecSyncBuf中,用IIR滤波求平均值。
CalcLpIir( PROC_BLOCK_SIZE/(2*4*3), &Dec2Buf[0], &SecSyncBuf[SecSyncPtr], 1000);
SecSyncPtr++;
if(SecSyncPtr>=SECSYNCBUF_LENGTH)
{
SecSyncPtr = 0;
SemA.SecRdy = TRUE;
}
CalcLpIir( PROC_BLOCK_SIZE/(2*4*3), &Dec2Buf[6], &SecSyncBuf[SecSyncPtr], 1000);
SecSyncPtr++;
if(SecSyncPtr>=SECSYNCBUF_LENGTH)
{
SecSyncPtr = 0;
SemA.SecRdy = TRUE;
}
CalcLpIir( PROC_BLOCK_SIZE/(2*4*3), &Dec2Buf[12], &SecSyncBuf[SecSyncPtr], 1000);
SecSyncPtr++;
if(SecSyncPtr>=SECSYNCBUF_LENGTH)
{
SecSyncPtr = 0;
SemA.SecRdy = TRUE;
}
if(SemA.MinLocked) //如果秒和分锁上则获取数据位
{
//欠采样调制信号从900sps到450sps
FIRDecimate( PROC_BLOCK_SIZE/(2*4*2), Buf100, Buf100, &fDec2LP110, 2);
//对450sps信号进行带通滤波以获得100Hz信号
FIR( PROC_BLOCK_SIZE/(2*4*2), Buf100, Buf100, &fBP100);
//校正调制信号以获得100Hz信号
CalcABS( PROC_BLOCK_SIZE/(2*4*2), Buf100);
if( SecSyncPtr > DATA_FILTER_DELAY )
i = SecSyncPtr - DATA_FILTER_DELAY;
else
i = SECSYNCBUF_LENGTH - (DATA_FILTER_DELAY - SecSyncPtr);
i = i / (SECSYNCBUF_LENGTH/RAWDATABUF_LENGTH);
CalcLpIir( PROC_BLOCK_SIZE/(2*4*2), &Buf100[0], &RawDataBuf[i], 20000);
}
}
//找到当前的数据位值
char CalcBit(void )
{
int i;
int noise;
int signal0;
int signal1;
noise = 0;
signal0 = 0;
signal1 = 0;
for(i=0; i<=4; i++) //加0位时隙
signal0 += RawDataBuf[i];
for(i=7; i<=11; i++) //加1位时隙
signal1 += RawDataBuf[i];
for(i=24; i<=28; i++)
noise += RawDataBuf[i]; //加噪声时隙
noise = noise << 2;
if(signal1 > noise) //需要S/N > 4
return 1;
else
if(signal0 > noise)
return -1;
else
return 0;
}
//通过找能量峰值找秒位置,每个二进制位是1/150秒
void FindSecSync(void)
{
int max;
//在SecSyncBuf找峰值位置
max = VectorMax(SECSYNCBUF_LENGTH, SecSyncBuf, &TicPos);
if( max < MAX_LIMIT )
{
SemA.SecLocked = FALSE;
SemA.MinLocked = FALSE;
MinSyncQuality = 0;
EarlyAve = 0;
LateAve = 0;
LED2_OFF
LED3_OFF
return;
}
if(!SemA.SecLocked)
{
if( TicPos == TicLastPos )
{
TicQuality++;
if(TicQuality>TIC_QUALITY_LIM1)
TicQuality = TIC_QUALITY_LIM1;
}
else
{
TicQuality = 0;
}
if(TicQuality ==TIC_QUALITY_LIM1)
{
VectorScale(SECSYNCBUF_LENGTH, SecSyncBuf, SecSyncBuf, 0); //清阵列
SecSyncBuf[0] = max; //恢复峰值能量到零位置
if(SecSyncPtr >= TicPos )
SecSyncPtr = SecSyncPtr - TicPos;
else
SecSyncPtr = SECSYNCBUF_LENGTH - (TicPos - SecSyncPtr);
TicPos = 0;
SemA.SecLocked = TRUE;
LED2_ON
}
}
else
{
if( 0 == TicPos )
{
TicQuality++;
if(TicQuality>TIC_QUALITY_LIM2 )
TicQuality = TIC_QUALITY_LIM2;
if(SemA.MinLocked)
CalcClockError();
}
else
{
TicQuality--;
if( TicQuality<=0 )
{
VectorScale(SECSYNCBUF_LENGTH, SecSyncBuf, SecSyncBuf, 0);
SemA.SecLocked = FALSE;
SemA.MinLocked = FALSE;
MinSyncQuality = 0;
EarlyAve = 0;
LateAve = 0;
LED2_OFF
LED3_OFF
}
}
}
TicLastPos = TicPos;
}
//找分的位置
void FindMinSync(void)
{
if( MinuteSyncSignal > (MinuteSyncNoise*4*5) )
{ //如果获得分同步信号
if(!SemA.MinLocked)
{
SemA.MinLocked = TRUE;
SecondsCount = 0;
MinSyncQuality = 1;
LED3_ON
}
else
{
if( 0 == SecondsCount)
MinSyncQuality++;
else
MinSyncQuality--;
if(MinSyncQuality>MIN_QUALITY_LIM)
MinSyncQuality = MIN_QUALITY_LIM;
if(MinSyncQuality<0)
{
MinSyncQuality = 0;
SemA.MinLocked = FALSE;
EarlyAve = 0;
LateAve = 0;
LED3_OFF
}
}
}
MinuteSyncSignal = 0;
MinuteSyncNoise = 0;
}
//计算时钟错误
static void CalcClockError(void)
{
//同步脉冲前后的平均位
CalcLpIir( 1, &SecSyncBuf[149], &EarlyAve, 1000);
CalcLpIir( 1, &SecSyncBuf[1], &LateAve, 1000);
if( (SecondsCount & 0x07) == 0 ) //每8秒
{
if(LateAve > (EarlyAve+400) )
AdjustClock( -1 ); //跳过一个调制解调器数据
if( EarlyAve > (LateAve+400) )
AdjustClock( 1 ); //加一个调制解调器数据
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -