这里写目录标题
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, 如果增加次数, 能够更接近发送端信号)