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

📄 channel_est.c

📁 完整的OFDM系统,含Matlab仿真代码和DSP源代码下载.平台Tms320C6000.含项目说明文档.绝对高质量的源代码.
💻 C
字号:
//channel_est.c
//
// Project Red 2002: High Performance OFDM Modem 
// Against Channel Imperfections
// Auther: Linus Falk

#include "complex_math.h"
#include <mathf.h>
#include "sync.h"
#include "ofdm.h"

#pragma DATA_SECTION (mod_training_bits, ".sysmem");
static float mod_training_bits[32];
const char position[16] = {3,11,19,27,35,43,51,59,67,75,83,91,99,107,115,123};
#pragma DATA_SECTION (received_training_symbols, ".sysmem");
float received_training_symbols[32];

#pragma DATA_SECTION (H, ".sysmem");
float H[254];
#pragma DATA_SECTION (H_abs_sqr, ".sysmem");
float H_abs_sqr[127];
#pragma DATA_SECTION (H_mean, ".sysmem");
float H_mean[254];
#pragma DATA_SECTION (H_mean_abs_sqr, ".sysmem");
float H_mean_abs_sqr[127];
#pragma DATA_SECTION (cosV, ".sysmem");
static float cosV[256];
#pragma DATA_SECTION (sinV, ".sysmem");
static float sinV[256];
short first_time = 1;
#pragma DATA_SECTION (noise_var_V, ".sysmem");
float noise_var_V[16]={0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
#pragma DATA_SECTION (noise_var, ".sysmem");
float noise_var = 0;
#pragma DATA_SECTION (snr, ".sysmem");
float snr;
#pragma DATA_SECTION (snr_int, ".sysmem");
int snr_int;

void scale(float *complex_frame);
void init_channel_est(void);
void interpolateFilter(float filter[254]);
void create_mean(void);
void calc_noise_var(void);
void calculate_snr(float *complex_frame);
void calculate_channel_abs_sqr(void);
void calc_noise(void);

//#pragma CODE_SECTION(channel_est,"SBSRAM_PROG_MEM");
void channel_est(float *complex_frame){
	int j=0;
	int index=0;
	static int do_what = 1;
	
	#pragma MUST_ITERATE(16,16);
	for(j=0; j<16; j++){
		index = position[j]*2;
		H[index] = complex_frame[index];
		H[index+1] = complex_frame[index+1];
		received_training_symbols[j*2] = complex_frame[index];
		received_training_symbols[j*2+1] = complex_frame[index+1];
		complex_division(H +index, mod_training_bits +j*2);
	}
	create_mean();	
	interpolateFilter(H);
	scale(complex_frame);
	
	interpolateFilter(H_mean);
	calc_noise_var();
	switch(do_what){ //do not need to do everything every time
		case 1:
			calculate_channel_abs_sqr();
		break;
		case 2:
			calculate_snr(complex_frame);
		break;
		default :
			do_what = 0;
		break;
	}
	do_what++;
}

#pragma CODE_SECTION(init_channel_est,"SBSRAM_PROG_MEM");
void init_channel_est(void){	
	const unsigned char training[] = {1,0,3,1,2,2,3,2,0,1,1,1,1,3,1,3};
	int i;
	float tal;
	tal = 9.0;

	#pragma MUST_ITERATE(254,254);
	for(i=0; i<254; i++){
		H[i] = 0;
		H_mean[i] = 0;
	}
	
	#pragma MUST_ITERATE(16,16);
	for(i=0; i<16; i++){
		switch ((int)training[i]){
			case 0:
				mod_training_bits[i*2]   = -tal;
				mod_training_bits[i*2+1] = -tal;
				break;
			case 1:
				mod_training_bits[i*2]   =  tal;
				mod_training_bits[i*2+1] = -tal;
				break;
			case 2:
				mod_training_bits[i*2]   = -tal;
				mod_training_bits[i*2+1] =  tal;
				break;
			case 3:
				mod_training_bits[i*2]   =  tal;
				mod_training_bits[i*2+1] =  tal;
				break;
			default:
				break;

		}
	}
	
	#pragma MUST_ITERATE(256,256);
	for(i=0; i<256; i++){
		cosV[i] = cosf(2*PI*i*0.00390625);
		sinV[i] = sinf(2*PI*i*0.00390625);
	}
}

//#pragma CODE_SECTION(interpolateFilter,"SBSRAM_PROG_MEM");
void interpolateFilter(float filter[254]){
	int i,j;
	float Re_step;
	float Im_step;

	filter[0] = filter[6];
	filter[1] = filter[7];
	filter[2] = filter[6];
	filter[3] = filter[7];
	filter[4] = filter[6];
	filter[5] = filter[7];
	#pragma MUST_ITERATE(15,15);
	for(i=0; i<15; i++){
		Re_step = (filter[position[i+1]*2] - filter[position[i]*2])*0.125;
		Im_step = (filter[position[i+1]*2+1] - filter[position[i]*2+1])*0.125;
		#pragma MUST_ITERATE(7,7);
		for(j=1; j<8; j++){
			filter[(position[i]+j)*2] = filter[position[i]*2] + j*Re_step;
			filter[(position[i]+j)*2+1] = filter[position[i]*2+1] + j*Im_step;
		}
	}
	filter[248] = filter[246];
	filter[249] = filter[247];
	filter[250] = filter[246];
	filter[251] = filter[247];
	filter[252] = filter[246];
	filter[253] = filter[247];
}

//#pragma CODE_SECTION(scale,"SBSRAM_PROG_MEM");
void scale(float *complex_frame){
	int i;
	#pragma MUST_ITERATE(127,127);
	for(i=0; i<127; i++){	//complex division
		complex_division(complex_frame +2*i, H +2*i);
	}
}

//#pragma CODE_SECTION(create_mean,"SBSRAM_PROG_MEM");
void create_mean(void){
    int j=0;
	int index=0;
	float phase_coef[2];
	int arg;
    
    if(first_time == 1){ 					//first time
       	first_time = 0;
       	#pragma MUST_ITERATE(16,16);
       	for(j=0; j<16; j++){
			index = position[j]*2;			//position in H_mean an H
			H_mean[index] = H[index];		//copy
			H_mean[index+1] = H[index+1];
			calculate_channel_abs_sqr();
		}
    }else{									//not first time
    	#pragma MUST_ITERATE(16,16);
    	for(j=0; j<16; j++){
    		index = position[j]*2;			//position in H_mean an H
			arg = (sync_diff*(position[j]+1))%256;	//cos and sin arg
			if(arg < 0){
				arg = 256 + arg;
			}
			phase_coef[0] = cosV[arg];		//calculate phase coef
       		phase_coef[1] = sinV[arg];
       		//phase_coef[0] = cosf(2*PI*sync_diff*(position[j]+1)*0.00390625);
       		//phase_coef[1] = sinf(2*PI*sync_diff*(position[j]+1)*0.00390625);
			complex_multiplication(H_mean+index, phase_coef);		//shift phase
			H_mean[index] = H_mean[index]*0.9 + H[index]*0.1;		//calculate mean
			H_mean[index+1] = H_mean[index+1]*0.9 + H[index+1]*0.1;
		}	
    }
}

#pragma CODE_SECTION(calc_noise_var,"SBSRAM_PROG_MEM");
void calc_noise_var(void){
	int i;
	float symbol_est[2];
	float diff[2];
	float abs_sqr;
	
	#pragma MUST_ITERATE(16,16);
	for(i=0; i<16; i++){
		symbol_est[0] = mod_training_bits[i*2];
		symbol_est[1] = mod_training_bits[i*2+1];
		complex_multiplication(symbol_est, H_mean + position[i]*2);
		diff[0] = received_training_symbols[i*2] - symbol_est[0];
		diff[1] = received_training_symbols[i*2+1] - symbol_est[1];
		complex_abs_sqr(diff,&abs_sqr);
		noise_var_V[i] = abs_sqr; 	
	}
	calc_noise();
}

//#pragma CODE_SECTION(calc_noise,"SBSRAM_PROG_MEM");
void calc_noise(void){
	int i;
	float new_noise = 0;
	for(i=0; i<16; i++){
		new_noise += noise_var_V[i];	
	}
	new_noise *= 0.065; //mean
	if(noise_var == 0){
		noise_var = new_noise;	
	}else{
		noise_var = noise_var*0.9+new_noise*0.1;
	}
}


//#pragma CODE_SECTION(calculate_snr,"SBSRAM_PROG_MEM");
void calculate_snr(float *complex_frame){
	int i;
	snr = 0;
	#pragma MUST_ITERATE(127,127);
	for(i=0; i<127; i++){
		snr += (complex_frame[i*2]*complex_frame[i*2] + complex_frame[i*2+1]*complex_frame[i*2+1])*0.007874;
	}
	snr *= _rcpsp(noise_var);
	snr_int = (int)(snr*1000);
}

//#pragma CODE_SECTION(calculate_channel_abs_sqr,"SBSRAM_PROG_MEM");
void calculate_channel_abs_sqr(void){
	int i;
	#pragma MUST_ITERATE(127,127);
	for(i=0; i<127; i++){
		H_abs_sqr[i] = H[i*2]*H[i*2] + H[i*2+1]*H[i*2+1];
		H_mean_abs_sqr[i] = H_mean[i*2]*H_mean[i*2] + H_mean[i*2+1]*H_mean[i*2+1];
	}
}


⌨️ 快捷键说明

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