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

📄 frameofdm.c

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

/* This script generates a COFDM waveform from an input data */ 
void OFDMModu(DType DataStr[], short BaseSignal[], DType RefPhase[])
/* DataStr:    RS coded data to transmit in the CodewordBit given,
 *             UsedCarrier * SymPerFrame in length;
 * BaseSignal: Final output modulated signal, SymbolSize * SymPerFrame in length;
 * RefPhase:   DPSK reference phase, UsedCarrier * 1 in length;
 */
{
	WordType i, j, k;
	DType DPSKdata[SymPerFrame * UsedCarrier];
	int TxSpecR[SymPerFrame * FFTSize], TxSpecI[SymPerFrame * FFTSize];
	DType *pDPSK, *pDataStr;
	int *pTxSpecR = TxSpecR, *pTxSpecI = TxSpecI;
	short *pBase = BaseSignal;

	/* Convert to DQPSK */
	for (j = 0; j < UsedCarrier; j++)
	{
		DPSKdata[j] = (DType) (DataStr[j] + RefPhase[j]) &
			(DType) ((1 << CodewordBit) - 1);
	}

	pDPSK = DPSKdata + UsedCarrier;
	pDataStr = DataStr + UsedCarrier;
	for (i = 1; i < SymPerFrame; i++)
	{
		for (j = 0; j < UsedCarrier; j++)
		{
			*pDPSK = (DType) ((*pDataStr) + (*(pDPSK - UsedCarrier))) & (DType) ((1 << CodewordBit) - 1);
			pDataStr++;
			pDPSK++;
			/*DPSKdata[j + i * UsedCarrier] = 
				(DType) (DataStr[j + i * UsedCarrier] + DPSKdata[j + (i - 1) * UsedCarrier]) &
				(DType) ((1 << CodewordBit) - 1);*/
		}
	}
	/* Store the last carrier data in RefPhase[] for next subframe */
	for (j = 0; j < UsedCarrier; j++)
	{
		RefPhase[j] = DPSKdata[j + (SymPerFrame - 1) * UsedCarrier];
	}

	/* Get the required spectrums */
	for (j = 0; j < SymPerFrame; j++)
	{
		pDPSK = &DPSKdata[j * UsedCarrier + 1 - CarrierJumpPos];
		for (i = 0; i < FFTSize; i++)
		{
			if ((i > CarrierJumpPos - 2) && (i < CarrierJumpPos + UsedCarrier - 1))
			{
				switch (*pDPSK)
				{
				case 0: *pTxSpecR = 16384;   *pTxSpecI = 0;  break;
				case 1: *pTxSpecR = 0;   *pTxSpecI = 16384;  break;
				case 2: *pTxSpecR = -16384;  *pTxSpecI = 0;  break;
				case 3: *pTxSpecR = 0;   *pTxSpecI = -16384;
				}
			}
			else
			{
				*pTxSpecR = 0;
				*pTxSpecI = 0;
			}
			pTxSpecR++;
			pTxSpecI++;
			pDPSK++;
		}
	}
	/* Change to time waveform using IFFT */
	for (i = 0; i < SymPerFrame; i++)
	{
		FFT(&TxSpecR[i * FFTSize], &TxSpecI[i * FFTSize], -1);
	}

	/* Add cycle prefixion (guardtime) */
	k = 0;
	for (i = 0; i < SymPerFrame; i++)
	{
		pTxSpecR = &TxSpecR[i * FFTSize + FFTSize - GuardTimeSize];
		for (j = GuardTimeSize; j > 0; j--)
		{
			*pBase =(short)(*pTxSpecR);
			k++;
			pBase++;
			pTxSpecR++;
		}
		pTxSpecR = &TxSpecR[i * FFTSize];
		for (j = 0; j < FFTSize; j++)
		{
			*pBase =(short)(*pTxSpecR);
			k++;
			pBase++;
			pTxSpecR++;
		}
	}
}

/* This script demodulates a COFDM waveform from an input data:
 * DataStr:    Received real signal, SymbolSize * SymPerFrame in length;
 * SpecSignal: Demodulated RS data in CodewordBit size per symbol,
 *             UsedCarrier * SymPerFrame in length;
 * RefPhase:   DPSK reference phase, UsedCarrier * 1 in length;
 */
void OFDMDemo(float BaseSignal[], DType SpecSignal[], float RefPhase[])
{
	WordType i, j;
	float RxSpecR[SymPerFrame * FFTSize], RxSpecI[SymPerFrame * FFTSize];
	float CarrPh[SymPerFrame * UsedCarrier];
	
	/* Reshape the linear time waveform into FFT segments & remove guard time */
	for (i = 0; i < SymPerFrame; i++)
	{
		for (j = 0; j < FFTSize; j++)
		{
			RxSpecR[i * FFTSize + j] = BaseSignal[i * SymbolSize + j + GuardTimeSize];
			RxSpecI[i * FFTSize + j] = 0;
		}
	}

	/* Apply FFT on the rest of received data */
	for (i = 0; i < SymPerFrame; i++)
	{
		FFT(&RxSpecR[i * FFTSize], &RxSpecI[i * FFTSize], 1);
	}
	/* Convert to QPSK phase */
	for (i = 0; i < SymPerFrame; i++)
	{
		for (j = CarrierJumpPos - 1; 
		j < CarrierJumpPos + UsedCarrier - 1; j++)
		{
			CarrPh[i * UsedCarrier + j - CarrierJumpPos + 1] = 
				(float) atan2((double)(RxSpecI[i * FFTSize + j]), 
				(double)(RxSpecR[i * FFTSize + j]));
			if (CarrPh[i * UsedCarrier + j - CarrierJumpPos + 1] < 0)
			{
				CarrPh[i * UsedCarrier + j - CarrierJumpPos + 1] += 
					(float)(PI * 2);
			}
		}
	}

	/* Apply DQPSK on the received data */
	for (j = 0; j < UsedCarrier; j++)
	{
		SpecSignal[j] = (DType) ((CarrPh[j] - RefPhase[j] + PI * 2 + PI / (1 << CodewordBit)) / 
			(PI / (1 << CodewordBit) * 2)) & (DType) ((1 << CodewordBit) - 1);
	}
	for (i = 1; i < SymPerFrame; i++)
	{
		for (j = 0; j < UsedCarrier; j++)
		{
			SpecSignal[i * UsedCarrier + j] = 
				(DType) ((CarrPh[i * UsedCarrier + j] - CarrPh[(i - 1) * UsedCarrier + j] + 
				PI * 2 + PI / (1 << CodewordBit)) / (PI / (1 << CodewordBit) * 2)) & 
				(DType) ((1 << CodewordBit) - 1);
		}
	}

	/* Save the RefPhase for next subframe */
	for (j = 0; j < UsedCarrier; j++)
	{
		RefPhase[j] = CarrPh[(SymPerFrame - 1) * UsedCarrier + j];
	}
}

⌨️ 快捷键说明

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