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

📄 txrx.c

📁 应用于无线通信的OFDM解调和RS解码源程序。64点FFT
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Setting.H"
#include "RS.H"
#include "Function.H"
#include "FrameOfdm.H"

WordType TxSymbolMark = 0;                  /* Indicates the symbol index in
											 * SrcToChan()
											 */
WordType TxBitMark = 0;                     /* Indicates the bit index of a
											 * symbol in SrcToChan()
											 */
WordType RxPosMark = 0;                     /* Indicates the received bit
											 * index in ChanToSrc()
											 */
extern WordType FrameTx;                    /* Indicates transmitted subframe
											 * number
											 */
extern WordType FrameRx;                    /* Indicates received subframe
											 * number
											 */

extern float DataBuffer[NullSampleSize / 2 + NullSampleSize + SymbolSize * 3];
                                            /* Processed data buffer in
											 * FindFrame()
											 */

DType  OriInforTx[52];                      /* Data buffer for the input of
											 * channel encoder;
											 * Data is converted from source
											 * coded information by SrcToChan()
											 */
WordType OriInforRx[3 * SrcVector];         /* Data buffer for the output of
											 * channel decoder;
											 * Data is converted from demodulated
											 * information by ChanToSrc()
											 */

DType  RefPhaseTx[UsedCarrier];             /* Buffer for transmit reference
											 * phase
											 */
float  RefPhaseRx[UsedCarrier];             /* Buffer for received reference
											 * phase
											 */

unsigned int Seed = 101;                    /* Initial seed of Random() */

WordType Transmit(short SourceCode[], short FinalData[])
{
	WordType i, k;
	//float j;
	DType ChannelData[RSTotalSym];
	DType ConvData[UsedCarrier * SymPerFrame];
	int TmpDataR[FFTSize], TmpDataI[FFTSize];

	/* Convert SrcVector bits to required data mode (RSInforBit bits per symbol) */
	SrcToChan(SourceCode, OriInforTx, &TxSymbolMark, &TxBitMark);

	/* Proceed RS coding and OFDM when all information symbols arrive */
	/* Get the available data */
	if (TxSymbolMark > (RSInforSym - 2))
	{
		/* First part of 5 source coded frames */
		if (TxSymbolMark > (RSInforSym - 1))
		{
			for (i = 0; i < RSInforSym; i++)
			{
				ChannelData[i] = OriInforTx[i];
			}
			for (i = RSInforSym; i <= TxSymbolMark; i++)
			{
				OriInforTx[i - RSInforSym] = OriInforTx[i];
			}
			TxSymbolMark -= RSInforSym;
		}
		/* Second part of 5 source coded frames */
		else
		{
			for (i = 0; i < RSInforSym; i++)
			{
				ChannelData[i] = OriInforTx[i];
			}
			TxSymbolMark = 0;
			TxBitMark = 0;
		}

		/* RS encoding */
		Encode_RS(&ChannelData[0], &ChannelData[RSInforSym]);
		
		/* Proceed OFDM below */
		if (FrameTx == TotalFrame)          /* First subframe of OFDM        */
		{
			FrameTx = 1;
			/* Add NullSampleSize padded zero */
			for (i = 0; i < NullSampleSize; i++)
			{
				FinalData[i] = 0;
			}
			k = NullSampleSize;
			/* Two additive lines for frame synchronization & reference phase */
			/* Add frame synchronization below in time waveform */
			for (i = 0; i < UsedCarrier; i++)
			{
				RefPhaseTx[i] = (DType) Random(&Seed, 3);
			}
			for (i = 0; i < FFTSize; i++)
			{
				if ((i > CarrierJumpPos - 2) && (i < CarrierJumpPos + UsedCarrier - 1))
				{
					switch (RefPhaseTx[i + 1 - CarrierJumpPos])
					{
					case 0: TmpDataR[i] = 16384;   TmpDataI[i] = 0;  break;       //2^14
					case 1: TmpDataR[i] = 0;   TmpDataI[i] = 16384;  break;
					case 2: TmpDataR[i] = -16384;  TmpDataI[i] = 0;  break;
					case 3: TmpDataR[i] = 0;   TmpDataI[i] = -16384;
					}
				}
				else
				{
					TmpDataR[i] = 0;
					TmpDataI[i] = 0;
				}
			}
			for (i = 1; i < FFTSize; i += 2)
			{
				TmpDataR[i] = 0;
				TmpDataI[i] = 0;
			}
			FFT(TmpDataR, TmpDataI, -1);
			for (i = GuardTimeSize; i > 0; i--)
			{
				FinalData[k] = (short)(TmpDataR[FFTSize - i]) ;   
				k++;
			}
			for (i = 0; i < FFTSize; i++)
			{
				FinalData[k] = (short)(TmpDataR[i]);
				k++;
			}

			/* Add reference phase below in time waveform */
			for (i = 0; i < UsedCarrier; i++)
			{
				RefPhaseTx[i] = (DType) Random(&Seed, 3);
			}
			for (i = 0; i < FFTSize; i++)
			{
				if ((i > CarrierJumpPos - 2) && (i < CarrierJumpPos + UsedCarrier - 1))
				{
					switch (RefPhaseTx[i + 1 - CarrierJumpPos])
					{
					case 0: TmpDataR[i] = 16384;   TmpDataI[i] = 0;  break;
					case 1: TmpDataR[i] = 0;   TmpDataI[i] = 16384;  break;
					case 2: TmpDataR[i] = -16384;  TmpDataI[i] = 0;  break;
					case 3: TmpDataR[i] = 0;   TmpDataI[i] = -16384;
					}
				}
				else
				{
					TmpDataR[i] = 0;
					TmpDataI[i] = 0;
				}
			}
			FFT(TmpDataR, TmpDataI, -1);
			for (i = GuardTimeSize; i > 0; i--)
			{
				FinalData[k] = (short)(TmpDataR[FFTSize - i]);
				k++;
			}
			for (i = 0; i < FFTSize; i++)
			{
				FinalData[k] = (short)(TmpDataR[i]);
				k++;
			}

			/* Adjust amplitude of frame synchronization & reference phase */
/*			j = 0;
			for (i = k - 2 * SymbolSize; i < k; i++)
			{
				if (j < (float)fabs(FinalData[i]))
				{
					j = (float)fabs(FinalData[i]);
				}
			}
			for (i = k - 2 * SymbolSize; i < k; i++)
			{
				FinalData[i] *= (float) (0.95 / j);
			}*/
		}
		else
		{
			FrameTx++;
			k = 0;
		}

		/* Convert the data base to CodewordBit */
		ConvBase(ChannelData, ConvData, RSTotalSym, 1);
		ConvData[UsedCarrier * SymPerFrame -1] = 0;
		/* Change to Gray code */
		Gray2(ConvData, RSTotalSym * RSInforBit / CodewordBit);

		/* OFDM modulation */
		OFDMModu(ConvData, &FinalData[k], RefPhaseTx);

		/* Adjust amplitude of transmit data */
/*		j = 0;
		for (i = k; i < k + SymbolSize * SymPerFrame; i++)
		{
			if (j < (float)fabs(FinalData[i]))
			{
				j = (float)fabs(FinalData[i]);
			}
		}
		for (i = k; i < k + SymbolSize * SymPerFrame; i++)
		{
			FinalData[i] *= (float) (0.95 / j);
		}*/
		for(i = 0; i < k + SymbolSize * SymPerFrame; i++)
			FinalData[i] = FinalData[i] & 0xffe0;
		return (k + SymbolSize * SymPerFrame);
    }
	else
	{
		return 0;
	}
}

WordType Receive(float RecData[], short SourceCode[])
{
	WordType i, k;
	DType ChanCodeData[RSTotalSym];
	DType ConvData[UsedCarrier * SymPerFrame];
	float TmpDataR[FFTSize], TmpDataI[FFTSize];

	if (FrameRx == TotalFrame)
	{
		FrameRx = 1;
		/* Two additive lines for frame synchronization & reference phase */
		/* Remove NullSampleSize padded zero & frame synchronization below */
		k = SymbolSize;
		/* Get reference phase below */
		for (i = 0; i < FFTSize; i++)
		{
			TmpDataR[i] = RecData[k + GuardTimeSize];
			TmpDataI[i] = 0;
			k++;
		}
		k += GuardTimeSize;                 /* Adjust the address access point */
		FFT(TmpDataR, TmpDataI, 1);
		for (i = CarrierJumpPos - 1; i < CarrierJumpPos + UsedCarrier - 1; i++)
		{
			RefPhaseRx[i - CarrierJumpPos + 1] = 
				(float) atan2((double)(TmpDataI[i]), (double)(TmpDataR[i]));
			if (RefPhaseRx[i - CarrierJumpPos + 1] < 0)
			{
				RefPhaseRx[i - CarrierJumpPos + 1] += (float)(PI * 2);
			}
		}
	}
	else
	{
		FrameRx++;
		k = 0;
	}

	/* OFDM modulation */
	OFDMDemo(&RecData[k], ConvData, RefPhaseRx);

	/* Change to Gray code */
	Gray2(ConvData, RSTotalSym * RSInforBit / CodewordBit);
	/* Convert the data base to CodewordBit */
	ConvBase(ConvData, ChanCodeData, RSTotalSym * RSInforBit / CodewordBit, 0);

	/* RS decoding */
 	i = Decode_RS(ChanCodeData);

	/* Convert RS data to required data mode (SrcVector bits per frame) */
	ChanToSrc(ChanCodeData, OriInforRx, &RxPosMark);
	/* Decompress the source data */
	if (RxPosMark < (3 * SrcVector - 1))
	{
		for (i = 0; i < (2 * SrcVector); i++)
		{
			SourceCode[i] = OriInforRx[i];
		}
		for (i = (2 * SrcVector); i < RxPosMark; i++)
		{
			OriInforRx[i - 2 * SrcVector] = OriInforRx[i];
		}
		RxPosMark -= (2 * SrcVector);
		return 2;
	}
	else
	{
		for (i = 0; i < (3 * SrcVector); i++)
		{
			SourceCode[i] = OriInforRx[i];
		}
		RxPosMark = 0;
		return 3;
	}
}

int FindFrame(float SignalIn[], WordType FirstFrame)
{
	WordType i, j;
	WordType FrameStart, FineStart;
	float tmp;
	float Sxx[3 * GuardTimeSize + 1] = {0};
	float Syy[3 * GuardTimeSize + 1] = {0};
	float Sxy[3 * GuardTimeSize + 1] = {0};
	float Sumx[3 * GuardTimeSize + 1] = {0};
	float Sumy[3 * GuardTimeSize + 1] = {0};
	float RR[3 * GuardTimeSize + 1];
	float FilterData[NullSampleSize / 2 + NullSampleSize + SymbolSize * 3];

	/* Get the processed signal and change to envelope type */
	if (FirstFrame == 1)
	{
		for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
		{
			DataBuffer[i] = (float) fabs((double) SignalIn[i]);
		}
	}
	else
	{
		for (i = 0; i < NullSampleSize + SymbolSize * 3; i++)
		{
			DataBuffer[i + NullSampleSize / 2] = (float) fabs((double) SignalIn[i]);
		}
	}

	/* Filter the signal */
	for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
	{
		FilterData[i] = 0;
	}
	for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
	{
		for (j = 0; j < min(i + 1, NullSampleSize - GuardTimeSize / 2); j++)
		{
			FilterData[i] += DataBuffer[i - j];
		}
	}

	/* Primary frame synchronization, find the jump-off point */
	tmp = 200.0;
	for (i = NullSampleSize - GuardTimeSize / 2 - 1; 
	i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
	{
		if (tmp > FilterData[i])
		{
			tmp = FilterData[i];
			FrameStart = i;                 /* Already in C index            */
		}
	}

	/* Calculate the correlation coefficient */
	for (i = FrameStart; i < FrameStart + FFTSize / 2; i++)
	{
		Sxx[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize)] * 
			DataBuffer[(WordType)(i - 1.5 * GuardTimeSize)];
		Syy[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize + FFTSize / 2)] * 
			DataBuffer[(WordType)(i - 1.5 * GuardTimeSize + FFTSize / 2)];
		Sxy[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize)] * 
			DataBuffer[(WordType)(i - 1.5 * GuardTimeSize + FFTSize / 2)];
		Sumx[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize)];
		Sumy[0] += DataBuffer[(WordType)(i - 1.5 * GuardTimeSize + FFTSize / 2)];
	}
	for (i = 0; i < 3 * GuardTimeSize; i++)
	{
		Sxx[i + 1] = Sxx[i] + 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] * 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] - 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize)] * 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize)];
		Syy[i + 1] = Syy[i] + 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize)] * 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize)] - 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] * 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)];
		Sxy[i + 1] = Sxy[i] + 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize)] * 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] - 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] *
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize)];
		Sumx[i + 1] = Sumx[i] + 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)] - 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize)];
		Sumy[i + 1] = Sumy[i] + 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize)] - 
			DataBuffer[(WordType)(i + FrameStart - 1.5 * GuardTimeSize + FFTSize / 2)];
	}
	for (i = 0; i < 3 * GuardTimeSize + 1; i++)
	{
		Sxx[i] -= (2 * Sumx[i] * Sumx[i] / FFTSize);
		Syy[i] -= (2 * Sumy[i] * Sumy[i] / FFTSize);
		Sxy[i] -= (2 * Sumx[i] * Sumy[i] / FFTSize);
		RR[i] = (float) (Sxy[i] / sqrt((double)(Sxx[i] * Syy[i])));
	}

	/* Filter the signal again */
	for (i = 0; i < 3 * GuardTimeSize + 1; i++)
	{
		FilterData[i] = 0;
	}
	for (i = 0; i < 3 * GuardTimeSize + 1; i++)
	{
		for (j = 0; j < min(i + 1, GuardTimeSize); j++)
		{
			FilterData[i] += RR[i - j];
		}
	}

	/* Fine frame synchronization using correlation coefficient */
	tmp = 0;
	for (i = GuardTimeSize; i < 3 * GuardTimeSize + 1; i++)
	{
		if (tmp < FilterData[i])
		{
			tmp = FilterData[i];
			FineStart = i;                 /* Already in C index            */
		}
	}
	FrameStart += Round((float)((FineStart - 1.5 * GuardTimeSize) / 2)) - 1;
	                                       /* Already in C index            */

	return FrameStart;
}

⌨️ 快捷键说明

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