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

📄 txrx.c

📁 基于TMS320F2812的AMR+RS编解码+OFDM调制解调源程序。是stand alone运行版本
💻 C
字号:

#include <stdio.h>
//#include <stdlib.h>
#include <math.h>
#include "Setting.H"
#include "RS.H"
#include "Function.H"
#include "FrameOfdm.H"

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

int 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
											 */
long int  RefPhaseRx[UsedCarrier];             /* Buffer for received reference
											 * phase
											 */

unsigned long int Seed;                /* Initial seed of Random() */
short LastStartPnt;                         /* Jump-off position of last frame */
short OFDMFrameNum;                     /* Used in FindFrame */


//extern long asin_tab[];
int *point_FinalData;
long int *point_TmpDataR;
long int *point_TmpDataI;
DType *point_ChannelData;
static WordType i, k;


WordType Transmit(int SourceCode[], int FinalData[])
{
	DType ChannelData[RSTotalSym];
	DType ConvData[UsedCarrier * SymPerFrame];
	long int TmpDataR[FFTSize], TmpDataI[FFTSize];
	
	//point_FinalData=FinalData;
    point_TmpDataR=TmpDataR;
    point_TmpDataI=TmpDataI;
    point_ChannelData=ChannelData;
        
    /* 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))
		{
	
			asm (" push xar0");
            asm (" push xar3");
			asm (" push xar4");
			asm (" movl xar4,@_point_ChannelData");
            asm (" movl xar3,#_OriInforTx");
			for (i = 0; i < RSInforSym; i++)
		    {
			  // ChannelData[i] = OriInforTx[i];
               asm (" movz ar0,@_i");
               asm (" mov  ah, *+xar3[ar0]");
               asm (" mov  *+xar4[ar0], ah");
            }
            asm (" pop  xar4");
            asm (" pop  xar3");
            asm (" pop  xar0");
			for (i = RSInforSym; i <= TxSymbolMark; i++)
			{
				OriInforTx[i - RSInforSym] = OriInforTx[i];
			}
			TxSymbolMark -= RSInforSym;
		}
		/* Second part of 5 source coded frames */
		else
		{
			asm (" push xar0");
			asm (" push xar3");
            asm (" push xar4");
            asm (" movl xar4,@_point_ChannelData");
            asm (" movl xar3,#_OriInforTx");
			for (i = 0; i < RSInforSym; i++)
			{
			    asm (" movz ar0,@_i");
                asm (" mov ah, *+xar3[ar0]");
                asm (" mov *+xar4[ar0], ah");
                //ChannelData[i] = OriInforTx[i];
			}
			asm (" pop  xar4");
			asm (" pop  xar3");
            asm (" pop  xar0");
			TxSymbolMark = 0;
			TxBitMark = 0;
		}

		/* RS encoding */
		Encode_RS(&ChannelData[0], &ChannelData[RSInforSym]);
		
		point_FinalData=FinalData;
		asm(" movl xar4,@_point_FinalData ");
		/* Proceed OFDM below */
		if (FrameTx == TotalFrame)          /* First subframe of OFDM        */
		{
			FrameTx = 1;
			/* Add NullSampleSize padded zero */
			asm(" push xar0");
            asm(" movl xar0,#0");
			for (i = 0; i < NullSampleSize; i++)
			{
				asm(" mov *+xar4[ar0],#0");
                asm(" inc ar0");  
				//FinalData[i] = 0;
			}
			asm(" pop xar0");
			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;
				}
			}
			asm(" push p");
            asm(" push xar3");
            asm(" push xar0");
            asm(" push xar4");
            asm(" mov ph ,#0");
            asm(" mov pl, #0");
            asm(" movl xar0,#2");
            asm(" movl xar3,@_point_TmpDataR");
            asm(" movl xar4,@_point_TmpDataI");
			for (i = 1; i < FFTSize; i += 2)
			{
				asm(" movl *+xar3[ar0],p");
                asm(" movl *+xar4[ar0],p");
                asm(" addb xar0,#4 "); 
				//TmpDataR[i] = 0;
				//TmpDataI[i] = 0;
			}
			asm(" pop xar4");
			asm(" pop xar0");
            asm(" pop xar3");
            asm(" pop p");
			
			FFT(TmpDataR, TmpDataI, -1);
			for (i = GuardTimeSize; i > 0; i--)
			{
				FinalData[k] = (int)(TmpDataR[FFTSize - i]);    //2^14
				k++;
			}
			for (i = 0; i < FFTSize; i++)
			{
				FinalData[k] = (int)(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;       //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;
				}
			}
			
						
			FFT(TmpDataR, TmpDataI, -1);
			for (i = GuardTimeSize; i > 0; i--)
			{
				FinalData[k] = (int)(TmpDataR[FFTSize - i]);
				k++;
			}
			for (i = 0; i < FFTSize; i++)
			{
				FinalData[k] = (int)(TmpDataR[i]);
				k++;
			}
			/* Adjust amplitude of frame synchronization & reference phase */
	/*		j = 0;
			for (i = k - 2 * SymbolSize; i < k; i++)
			{
				h =(float)fabs(FinalData[i]);
				if (j < h)
		        {
			 	    j = h;
			    }
				if (j < (float)fabs(FinalData[i]))
				{
					j = (float)fabs(FinalData[i]);
				}*/
		/*	}
			h =(float) (0.95/j);
			for (i = k - 2 * SymbolSize; i < k; i++)
			{
				FinalData[i] *=h;
				//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++)
		{
			h =(float)fabs(FinalData[i]);
			if (j < h)
			{
				j = h;
			}
			if (j < (float)fabs(FinalData[i]))
			{
				j = (float)fabs(FinalData[i]);
			}*/
	//	}
	/*	h = (float) (0.95 / j);
		for (i = k; i < k + SymbolSize * SymPerFrame; i++)
		{
			FinalData[i] *= h;
			//FinalData[i] *= (float) (0.95 / j);
		}*/
		
		return (k + SymbolSize * SymPerFrame);
    }
	else
	{
		return 0;
	}
}

WordType Receive(int RecData[], int SourceCode[])
{
	WordType i, k;
	DType ChanCodeData[RSTotalSym];
	DType ConvData[UsedCarrier * SymPerFrame];
	long int TmpDataR[FFTSize], TmpDataI[FFTSize];
	//int   index;
   	long int *pTmpDataR, *pTmpDataI,*pRefPhaseRx;//,xI,xR;


	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);
		pTmpDataR = TmpDataR + CarrierJumpPos - 1;
		pTmpDataI = TmpDataI + CarrierJumpPos - 1;
		pRefPhaseRx = RefPhaseRx;
		for (i = 0 ; i < UsedCarrier; i++)
		{
        /*	xR = *pTmpDataR;
			xI = *pTmpDataI;
			index = (float)90 * xI*xI/(xI*xI+xR*xR);
			*pRefPhaseRx = asin_tab[index];
			if(xR>=0 && xI<0)
			{
				*pRefPhaseRx = -(*pRefPhaseRx) + PI2Q15;
			}
			else if(xR<0 && xI<=0)
			{
				*pRefPhaseRx = *pRefPhaseRx + PIQ15;
			}
			else if(xR<0 && xI>0)
			{
				*pRefPhaseRx = -(*pRefPhaseRx) + PIQ15;
			}*/
			*pRefPhaseRx = arctan2(*pTmpDataI, *pTmpDataR);
			pTmpDataR++;
			pTmpDataI++;
			pRefPhaseRx++;
		}
	}
	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;
	}
}

WordType FindFrame(int SignalIn[])
{
	WordType i, j;
	WordType FrameStart, FineStart;
	long int FilterData[FindFrameDataLen];
    long int tmp;
	long int Sxx[3 * GuardTimeSize + 1];
	long int Syy[3 * GuardTimeSize + 1];
	long int Sxy[3 * GuardTimeSize + 1];
	long int Sumx[3 * GuardTimeSize + 1];
	long int Sumy[3 * GuardTimeSize + 1];
	long int RR[3 * GuardTimeSize + 1];
	long int k1,k2,k3;

	FineStart=0;
	
	
	/* Get the processed signal and change to envelope type */
	for (i = 0; i < FindFrameDataLen; i++)
	{
		DataBuffer[i] = abs(SignalIn[i]);
		FilterData[i] = 0;
	}
	
	for (i = 0; i < 3 * GuardTimeSize + 1; i++)
	{
		Sxx[i] = 0;
		Syy[i] = 0;
		Sxy[i] = 0;
		Sumx[i] = 0;
		Sumy[i] = 0;
	}
		



	/* Filter the signal 
	for (i = 0; i < NullSampleSize / 2 + NullSampleSize + SymbolSize * 3; i++)
	{
		FilterData[i] = 0;
	}

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

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

	FrameStart++;
	/* Calculate the correlation coefficient */
	for (i = FrameStart; i < FrameStart + FFTSize / 2; i++)
	{
		k1 = DataBuffer[i - (WordType)(3 * GuardTimeSize / 2)];
		k2 = DataBuffer[i + FFTSize / 2 - (WordType)(3 * GuardTimeSize / 2)];
		Sxx[0] += k1 * k1;
		Syy[0] += k2 * k2;
		Sxy[0] += k1 * k2;
		Sumx[0] += k1;
		Sumy[0] += k2;
	}
	j = FrameStart - (WordType)(3 * GuardTimeSize / 2);
	for (i = 0; i < 3 * GuardTimeSize; i++)
	{
	    asm(" spm 0");
		k1 = DataBuffer[i + j + FFTSize / 2];
		k2 = DataBuffer[i + j]; 
		k3 = DataBuffer[i + j + FFTSize];
		Sxx[i + 1] = Sxx[i] + k1  * k1  - k2  * k2;
		Syy[i + 1] = Syy[i] + k3  * k3  - k1  * k1;
		Sxy[i + 1] = Sxy[i] + k3  * k1  - k1  *	k2;
		Sumx[i + 1] = Sumx[i] + k1 - k2;
		Sumy[i + 1] = Sumy[i] + k3 - k1;
	}

	for (i = 0; i < 3 * GuardTimeSize + 1; i++)
	{
		asm(" spm 0");
		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] = Q15* (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 < GuardTimeSize; i++)
	{
		FilterData[GuardTimeSize] += RR[GuardTimeSize - i];
	}

	for (j = 1; i < 3 * GuardTimeSize + 1; i++,j++)
	{
		FilterData[i] += FilterData[i-1] + RR[i] - RR[j];
	}

	/* Fine frame synchronization using correlation coefficient */
	tmp = 0x80000000;
	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            */

	FineStart -= (5 * HalfGuardTimeSize + FineSynFilterLen -1);
										/* 1 GuardTimes is the data from CP
										* is also correlative to the second part
										* 1.5 GuardTimes is for the start point.
										*/
	FrameStart += FineStart;
	if (OFDMFrameNum > 0)
	{
		LastStartPnt = FrameStart;
		OFDMFrameNum--;
	}
	else
	{
		LastStartPnt = Round((float)((LastStartPnt + FrameStart) / 2.0));
	}

	return  LastStartPnt;
}
	

⌨️ 快捷键说明

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