C语言仿真ADC的完整代码,无信道部分,仅发送端接收端

1. main文件:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "const.h"
#include "complex.h"

double CNR;

int main(void)
{
    
    
	int Eb_N0;
//	loop: 重复次数; Eb_N0:1bit含量的信号的能量 与 噪音密度的比值
	int transmitted_bit[BITN], received_bit[BITN];

	Complex modulated_signal[POINT_N], transmitted_signal[OFDM_N + GI];
	Complex received_signal[OFDM_N];
	//double *ADC_output;
	//ADC_output = (int*)malloc(sizeof(double)*OFDM_N);

	srand((unsigned)time(NULL));//rand函数必备,生成随机数
	
	for(Eb_N0=0; Eb_N0<10; Eb_N0++)
	{
    
    
		CNR = (double)Eb_N0 + 3.0;
		for(int loop=0; loop<LOOPN; loop++)
		{
    
    
			transmitter(transmitted_bit, modulated_signal);
			oversampling_GI(modulated_signal, transmitted_signal);
			removeGI(transmitted_signal,received_signal);
			ADC(received_signal);
			//statistic(loop, transmitted_bit, received_bit);
		 }
	}

    return 0;
}


3. 头文件:complex.h和complex.c调用

4. 发送端transmitter.c

#include "const.h"
#include "complex.h"
void bit_generator(int (*bit));
void QPSK_modulator(int *(bit), Complex (*signal));

void transmitter(int (*bit), Complex (*signal))
{
    
    
	bit_generator(bit);
	QPSK_modulator(bit, signal);
}

void bit_generator(int (*bit))
{
    
    
	int n;
	for(n=0; n<BITN; n++){
    
    
    	bit[n] = rand() & 0x1;
	}
}

void QPSK_modulator(int *(bit), Complex (*signal))
{
    
    
	int n, bit1, bit2, symbol;
	//状态索引数组
	int bin2sym[2][2] = {
    
    
		{
    
     0, 1},
		{
    
     3, 2}
	};

	//状态数组
	double sym2sgnl[4][2] = {
    
    
		{
    
     OneBySqrt2, OneBySqrt2},
		{
    
    -OneBySqrt2, OneBySqrt2},
		{
    
    -OneBySqrt2,-OneBySqrt2},
		{
    
     OneBySqrt2,-OneBySqrt2}
	};


	for(n=0; n<POINT_N; n++){
    
    
        //获取信号随机状态,从生成的bit[128]数组中取连续的两位
		bit1 = bit[n*2];
		bit2 = bit[n*2+1];
		//bit1,bit2取值都是从0,1中任取一个
		symbol = bin2sym[bit1][bit2];
		//更新信号量。symbol的取值是0,1,2,3四个数字中随机任一个。将对应symbol值映射到信号数组中
		signal[n].real = sym2sgnl[symbol][0];
		signal[n].image = sym2sgnl[symbol][1];
        //得到数组signal[64][2],每一行代表ABCD四个点中任一个
	}
}

5. 过采样oversampling.c

#include "const.h"
#include "complex.h"

//Complex modulated_signal[POINT_N], transmitted_signal[OFDM_N];
//POINT_N代表OFDM的subcarriers中,携带data的subcarriers的数量; OFDM_N代表所有subcarriers即FFT信号数量 
//用过采样原理对调制信号在频域上做IFFT,获得高频的OFDM信号 

void overSampling(Complex(*modulated_signal), Complex(*conjugate_signal), Complex(*OFDM_signal));
void addGI(Complex (*OFDM_signal), Complex(*transmitted_signal));

void oversampling_GI (Complex (*modulated_signal),  Complex(*transmitted_signal))
{
    
    
    Complex *OFDM_signal;
    OFDM_signal = (Complex*)malloc(sizeof(Complex) * OFDM_N);
    for (int i = 0; i < OFDM_N; i++) {
    
    
        OFDM_signal[i].real = 0;
        OFDM_signal[i].image = 0;
    }
    Complex* conjugate_signal;
    conjugate_signal = (Complex*)malloc(sizeof(Complex) * POINT_N);

    // obtain conjugate(s)
    for (int j = 0; j < POINT_N; j++)
    {
    
    
        conjugate_signal[j].real = modulated_signal[j].real;
        conjugate_signal[j].image = -modulated_signal[j].image;

    }
    overSampling(modulated_signal, conjugate_signal, OFDM_signal);
    //printf("%lf\n", OFDM_signal[0]);
    addGI(OFDM_signal, transmitted_signal);
}
//	overSampling
void overSampling (Complex (*modulated_signal), Complex(*conjugate_signal),Complex (*OFDM_signal))
{
    
    
    
	//mapping
    Complex* FFT_signal;
    FFT_signal = (Complex*)malloc(sizeof(Complex) * subcar_N);
    //Complex FFT_signal[subcar_N];//1024个subcarriers(FFT信号),其中2*POINT_N个会搭载data 
    for (int i = 0; i < subcar_N; i++) {
    
    
        FFT_signal[i].real = 0;
        FFT_signal[i].image = 0;
    }
    for (int k = 0; k < POINT_N; k++)
    {
    
    
    	FFT_signal[k+100+(subcar_N/2)] = modulated_signal[k];//[~512~]
    	FFT_signal[-k-100+(subcar_N / 2)] = conjugate_signal[k];
        
	}
    for (int m = 0; m < subcar_N; m++) 
    {
    
    
        printf("m= %d, %lf + %lf j\n", m, FFT_signal[m].real, FFT_signal[m].image);
    }
	
	//	IFFT
    // Complex temp_signal[subcar_N];
    Complex* temp_signal;
    temp_signal = (Complex*)malloc(sizeof(Complex) * subcar_N);
    for (int i = 0; i < subcar_N; i++) {
    
    
        temp_signal[i].real = 0;
        temp_signal[i].image = 0;
    }
	for (int k = 0; k < OFDM_N; k++)	
    {
    
    
    	for (int n = 0; n < subcar_N; n++)//1024=subcar_N=OFDM_N
    	{
    
    
            temp_signal[k].real = 1 / sqrt(OFDM_N) * ComplexMulti(FFT_signal[n], Exp(2 * PI * k * n / OFDM_N)).real;
            temp_signal[k].image = 1 / sqrt(OFDM_N) * ComplexMulti(FFT_signal[n], Exp(2 * PI * k * n / OFDM_N)).image;
		
		    OFDM_signal[k].real = OFDM_signal[k].real + temp_signal[k].real;
		    OFDM_signal[k].image = OFDM_signal[k].image + temp_signal[k].image;
    	}
        printf("k= %d, %lf + %lf j\n", k, OFDM_signal[k].real, OFDM_signal[k].image);
	}
    
    
}

void addGI(Complex(*OFDM_signal), Complex(*transmitted_signal))
{
    
    
	int n;
	for (n = 0; n < GI; n++)
    {
    
    
        transmitted_signal[n] = OFDM_signal[n + GI*3];
    }
    for (n = GI; n < OFDM_N; n++)
    {
    
    
        transmitted_signal[n] = OFDM_signal[n - GI];
    }
}


6. 接收端remove_GI.c

#include "const.h"
#include "complex.h"

void removeGI(Complex (*signal), Complex(*output_signal))
{
    
    
	int j;
    for (j = 0; j < OFDM_N; j++)
    {
    
    
		output_signal[j].real = signal[j+GI].real;
		output_signal[j].image = signal[j+GI].image;

    }
}

7. 接收端ADC仿真

#include "const.h"
#include "complex.h"
double estimate(double* realSignal);

void ADC(Complex(*received_signal))
{
    
    
	double estimated_signal[OFDM_N];
	for (int i = 0; i < OFDM_N; i++)
	{
    
    
		estimated_signal[i] = estimate(&received_signal[i].real);
	}
	//return 0;
}

double estimate(double *realSignal) 
{
    
    
	double estimated_signal=0;
	
	int adcN = 50; 	//取样次数.......后期写进const.h里,用频率表示

	double delta;
	double sumOfDelta=0;
	//int bitStream[adcN];
	int bitStream[50];

	double DACoutput = Vref;	//+ or -Vref

	//对于每一个信号都取adcN次平均值
	for (int j = 0; j < adcN; j++)
	{
    
    
		//初始化
		bitStream[j] = 0;
		delta = *realSignal - DACoutput;
		sumOfDelta += delta;
		//printf("delta = %f\n", delta);
		//printf("sumOfDelta = %lf\n", sumOfDelta);

		if (sumOfDelta >= 0)
		{
    
    
			bitStream[j] = 1;
			DACoutput = Vref;
		}
		else
		{
    
    
			bitStream[j] = 0;
			DACoutput = -Vref;
		}
		printf("%d\n", bitStream[j]);
		printf("DACoutput_signal = %lf\n", DACoutput);
		estimated_signal += DACoutput;
	}
	//求平均 
	estimated_signal /= adcN;
	printf("estimated_signal = %lf\n", estimated_signal);
	//随着循环次数增加,能输出一个收敛于transmitted_signal[0]的值
	return estimated_signal;
}


输出结果如下:

共轭对称后发送端OFDM信号(FFT信号)虚部趋向于无穷小, 说明过采样过程正确:
在这里插入图片描述
以下是发送端信号其中25个:
在这里插入图片描述
以下是接收端用ADC估计出来的对应的25个信号:
(循环次数adcN只设置为50, 如果增加次数, 能够更接近发送端信号)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Fky_mie/article/details/116714895
今日推荐