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

📄 procsignal.c

📁 dspic开发控制程序,有助开发pic单片机程序
💻 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 + -