我创建了一个名为 ofdm.h 的头文件,其中包含所有函数原型(prototype)。然后我创建了一个名为 ofdm.c 的源文件,其中包含在 ofdm.h 中声明的所有函数的源代码。之后,我开始在 main.c 中编码,但是当我运行它时,我收到错误:未定义对“(函数名称)”的引用。我的所有功能都收到此错误。
您可以在下面找到我所有三个文件的源代码。
ofdm.h
#ifndef OFDM_H_INCLUDED
#define OFDM_H_INCLUDED
typedef struct {
double real, img;
} Complex;
char** split(char *s, const char *delim);
void parseComplex(Complex *c, char *line);
void rbits(short* buf, int nbits);
void printbinary(short* buf, int len);
void printcomplex(Complex* buf, int len);
long bin2dec(short *bin, int len);
void dec2bin(long dec, short *bin, int len);
void binaryadd(short *bin1, short *bin2, short *erg, int len);
void leftshift(short *bin,short *erg,int shifts, int len);
void binarymult(short *bin1, short *bin2, short *erg, int len);
void binarypower(short *bin,short *erg,int power, int len);
void scrambler(short *seed, short *input, short *output, int len, int seedlen);
void encoder(short *input, short *output, int inputlen);
void interleaver(short *input, short *output, int N_CBPS,int N_BPSC);
void deinterleaver(short *input, short *output, int N_CBPS,int N_BPSC);
void fixed_point(short* input, int nbits);
void fixed_point_complex(Complex* input, int nbits);
void defixed_point(short* input, int nbits);
void BPSKmapping(short* input, short* output, int nbits);
void BPSKdemapping(short* input, short* output, int nbits);
void QPSKmapping(short* input, Complex* output, int nbits);
void QPSKdemapping(Complex* input, short* output, int nbits);
void IFFT_BPSK(short* input, Complex* output, Complex* twidder);
void IFFT_QPSK(Complex* input, Complex* output, Complex* twidder);
double uniform(double a, double b);
double gauss(double mean, int SNRdb);
void ChannelModel(Complex R[], Complex S[], int SNRdb);
#endif
ofdm.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ofdm.h"
char** split(char* string, const char* delim)
{
char* p;
int i = 0;
char** array = malloc(strlen(string) * sizeof(char*));
p = strtok(string, delim);
while(p != NULL)
{
array[i] = malloc(sizeof(char));
array[i++] = p;
p = strtok(NULL, delim);
}
return array;
}
void parseComplex(Complex *cmplx, char *number)
{
char *copy = number;
if(strchr(copy, ' ') != NULL)
{
char **result = split(copy, " ");
cmplx->real = atof(*result++);
char *sign = *result++;
cmplx->img = atof(*result++);
if(sign[0] == '-')
cmplx->img = -(cmplx->img);
}
else if(strchr(copy, 'j') != NULL)
{
cmplx->real = 0;
cmplx->img = atof(copy);
}
else
{
cmplx->real = atof(copy);
cmplx->img = 0;
}
}
void rbits(short* buf, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
buf[i] = (rand() % 2);
}
void printbinary(short* buf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%d\t", buf[i]);
}
printf("\n\n\n");
}
void printcomplex(Complex* buf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%.0lf %.0lf\t", buf[i].real, buf[i].img);
}
printf("\n\n");
}
long bin2dec(short *bin, int len)
{
long dec = 0;
int i;
for(i = 0;i < len;i++)
{
dec += bin[i]*pow(2.0,(double) (len - i -1));
}
return dec;
}
void dec2bin(long dec, short *bin, int len)
{
long temp = dec;
int i;
for(i = 0;i<len;i++)
{
bin[len - 1 - i] = temp % 2;
temp = temp/2;
}
}
void binaryadd(short *bin1, short *bin2, short *erg, int len)
{
int i;
short carry = 0;
short oldcarry = 0;
for(i = len - 1; i >= 0; i--)
{
if((bin1[i] + bin2[i] + oldcarry) > 1)
{
carry = 1;
}
else
{
carry = 0;
}
erg[i] = (bin1[i] + bin2[i] + oldcarry) % 2;
oldcarry = carry;
}
}
void leftshift(short *bin,short *erg,int shifts, int len)
{
int i;
for(i = 0;i < len - shifts;i++)
{
erg[i] = bin[i + shifts];
}
for(i = len - shifts;i < len;i++)
{
erg[i] = 0;
}
}
void binarymult(short *bin1, short *bin2, short *erg, int len)
{
int i;
short temp[len - 1];
for(i = 0;i < len;i++)
{
erg[i] = 0;
}
for(i = 0;i < len;i++)
{
if(bin2[i] == 1)
{
leftshift(bin1,temp,len - 1 - i,len);
binaryadd(temp,erg,erg,len);
}
}
}
void binarypower(short *bin,short *erg,int power, int len)
{
int i;
short temp[len - 1];
for(i = 0;i < len;i++)
{
temp[i] = 0;
}
temp[len - 1] = 1;
if(power > 1)
binarypower(bin,temp,power - 1,len);
binarymult(temp,bin,erg,len);
}
void scrambler(short *seed, short *input, short *output, int len, int seedlen)
{
int i;
short carry;
short sequence[len - 1];
for(i = 0; i < len; i++)
{
sequence[i] = (seed[0] + seed[3]) % 2;
carry = (seed[0] + seed[3]) % 2;
leftshift(seed,seed,1,seedlen);
seed[seedlen - 1] = carry;
output[i] = (sequence[i] + input[i]) % 2;
}
}
void encoder(short *input, short *output, int inputlen)
{
int i;
short SR[7] = {0,0,0,0,0,0,0};
short A;
short B;
for(i = 0; i < inputlen;i++)
{
leftshift(SR,SR,1,7);
SR[6] = input[i];
A = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) % 2;
B = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) % 2;
output[2*i] = A;
output[2*i + 1] = B;
}
}
/*
void decoder(short *input, short *output, int inputlen)
{
int i;
short SR[7] = {0}
short A;
short B;
short C1;
short C2;
for(i = 0; i < intputlen; i++)
{
leftshift(SR, SR, 1, 7)
SR[6] = input[i];
C1 = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) / 2;
C2 = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) / 2;
A = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) - (2 * C1);
B = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) - (2 * C2);
output[2*i] = A; // output[i/2] = A;
output[2*i + 1] = B; // output[i/2 + 1] = B;
}
}
*/
void interleaver(short *input, short *output, int N_CBPS,int N_BPSC)
{
int i;
int t;
int k;
int s;
short first_permutuation[N_CBPS - 1];
for (k = 0; k < N_CBPS; k++)
{
i = (N_CBPS/16)*(k % 16) + (k/16);
first_permutuation[i] = input[k];
}
s = fmax(N_BPSC/2,1);
for(i = 0; i < N_CBPS;i++)
{
t = s*(i/s) + (i + N_CBPS - ((16*i)/N_CBPS)) % s;
output[t] = first_permutuation[i];
}
}
void fixed_point(short* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] < 0)
input[i] *= 32768;
else input[i] *= 32767;
}
}
void fixed_point_complex(Complex* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i].real == -1 || input[i].img == -1)
input[i] *= 32768;
else input[i] *= 32767;
}
}
void defixed_point(short* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] < 0)
input[i] /= 32768;
else input[i] /= 32767;
}
}
void IFFT_BPSK(short* input, Complex* output, Complex* twidder)
{
int i, k;
for(i = 0; i < 64; i++)
{
for(k = 0; k < 64; k++)
{
output[i].real += (twidder[i][k].real * input[i]) / 64;
output[i].img += (twidder[i][k].img * input[i]) / 64;
}
}
}
void IFFT_QPSK(Complex* input, Complex* output, Complex* twidder)
{
int i, k;
for(i = 0; i < 64; i++)
{
for(k = 0; k < 64; k++)
{
output[i].real += (twidder[i][k].real * input[i].real) / 64;
output[i].img += (twidder[i][k].img * input[i].img) / 64;
}
}
}
void IFFT_QPSK2(Complex* input, Complex* output, Complex* twidder, int nbits)
{
int a, b, c, d, e, f, g, h, blocks;
int count1 = 7, count2 = 20, count3 = 28, count4 = 41;
int next = 0;
Complex ifft_qpsk_output[64];
blocks = nbits / 48;
for(a = 1; a <= blocks; a++)
{
// pilots
output[7].real = 32767;
output[21].real = 32767;
output[42].real = 32767;
output[56].real = -32768;
// some data
output[40].real = input[26 + (next * 48)].real;
output[40].img = input[26 + (next * 48)].img;
output[41].real = input[27 + (next * 48)].real;
output[41].img = input[27 + (next * 48)].img;
// zeroes
for(b = 28; b <= 39; b++)
output[b].real = 0;
// other data
for(c = 0; c <= 6; c++)
{
output[c].real = input[c + (next * 48)].real;
output[c].img = input[c + (next * 48)].img;
}
for(d = 8; d <= 20; d++)
{
output[d].real = input[count1++ + (next * 48)].real;
output[d].img = input[count1++ + (next * 48)].img;
}
for(e = 22; e <= 27; e++)
{
output[e].real = input[count2++ + (next * 48)].real;
output[e].img = input[count2++ + (next * 48)].img;
}
for(f = 43; f <= 55; f++)
{
output[f].real = input[count3++ + (next * 48)].real;
output[f].img = input[count3++ + (next * 48)].img;
}
for(h = 57; h <= 63; h++)
{
output[h].real = input[count4++ + (next * 48)].real;
output[h].img = input[count4++ + (next * 48)].img;
}
// IFFT function goes here
IFFT_QPSK(output, ifft_qpsk_output, twidder);
printcomplex(ifft_qpsk_output, 64);
next++;
}
}
void IFFT_BPSK2(short* input, short* output, Complex* twidder, int nbits)
{
int a, b, c, d, e, f, g, h, blocks;
int count1 = 7, count2 = 20, count3 = 28, count4 = 41;
int next = 0;
Complex ifft_bpsk_output[64];
blocks = nbits / 48;
for(a = 1; a <= blocks; a++)
{
// pilots
output[7] = 32767;
output[21] = 32767;
output[42] = 32767;
output[56] = -32768;
// some data
output[40] = input[26 + (next * 48)];
output[41] = input[27 + (next * 48)];
// zeroes
for(b = 28; b <= 39; b++)
output[b] = 0;
// other data
for(c = 0; c <= 6; c++)
output[c] = input[c + (next * 48)];
for(d = 8; d <= 20; d++)
output[d] = input[count1++ + (next * 48)];
for(e = 22; e <= 27; e++)
output[e] = input[count2++ + (next * 48)];
for(f = 43; f <= 55; f++)
output[f] = input[count3++ + (next * 48)];
for(h = 57; h <= 63; h++)
output[h] = input[count4++ + (next * 48)];
// IFFT function goes here
IFFT_BPSK(output, ifft_bpsk_output, twidder);
printcomplex(ifft_bpsk_output, 64);
next++;
}
}
void BPSKmapping(short* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] == 0)
output[i] = -1;
else output[i] = 1;
}
}
void BPSKdemapping(short* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] == -1)
output[i] == 0;
else output[i] == 1;
}
}
void QPSKmapping(short* input, Complex* output, int nbits)
{
int i;
for(i = 0; i < nbits; i += 2)
{
if(input[i] == 0 && input[i+1] == 0)
{
output[i].real = -1;
output[i+1].img = -1;
}
else if(input[i] == 0 && input[i+1] == 1)
{
output[i].real = -1;
output[i+1].img = 1;
}
else if(input[i] == 1 && input[i+1] == 0)
{
output[i].real = 1;
output[i+1].img = -1;
}
else
{
output[i].real = 1;
output[i+1].img = 1;
}
}
}
void QPSKdemapping(Complex* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i += 2)
{
if(input[i].real == -1 && input[i+1].img == -1)
{
output[i] = 0;
output[i+1] = 0;
}
else if(input[i].real == -1 && input[i+1].img == 1)
{
output[i] = 0;
output[i+1] = 1;
}
else if(input[i].real == 1 && input[i+1].img == -1)
{
output[i] = 1;
output[i+1] = 0;
}
else
{
output[i] = 1;
output[i+1] = 1;
}
}
}
//Channel Begin
double uniform(double a, double b)
{
double c;
double d;
static int firstcall = 1;
c = b - a;
if(firstcall == 1)
{
srand((unsigned int)time(NULL));
firstcall = 0;
}
d = a + (double)rand() / RAND_MAX * c;
return d;
}
double gauss(double mean, int SNRdb)
{
double dGaussNum;
double x = 0;
int i;
double sigma;
sigma = 1 / pow(10, (double)SNRdb / 10);
for(i = 0;i < 12; i ++)
{
x = x + uniform(0,1);
}
x = x - 6;
dGaussNum = mean + sqrt(sigma) * x;
return dGaussNum;
}
void ChannelModel(Complex R[], Complex S[], int SNRdb)
{
int i;
for (i=0;i<N+L;i++)
{
R[i].real = S[i].real + gauss(0, SNRdb);
R[i].img = S[i].img + gauss(0, SNRdb);
}
}
//Channel End
void deinterleaver(short *input, short *output, int N_CBPS,int N_BPSC)
{
int i;
int t;
int k;
int s;
short first_permutuation[N_CBPS - 1];
s = fmax(N_BPSC/2,1);
for (t = 0; t < N_CBPS; t++)
{
i = s*(t/s) + (t + ((16*t)/N_CBPS)) % s;
first_permutuation[i] = input[t];
}
for(i = 0; i < N_CBPS;i++)
{
k = 16*i - (N_CBPS - 1)*((16*i)/N_CBPS);
output[k] = first_permutuation[i];
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ofdm.h"
int main(int argc, char *argv[])
{
short seed[8];
int bits, i, j, k;
char mode[5], line[1024];
/* Complex twidder[64][64];
FILE *file = fopen("twidder_factor.txt", "r");
i = 0;
while(fgets(line, sizeof(line), file ) != NULL)
{
k = j = 0;
char **result = split(line, "\t");
while(result[k] != NULL)
{
parseComplex(&twidder[i][j], result[k++]);
j++;
}
i++;
}
*/
printf("How many bits do you want to transmit?: ");
scanf("%d", &bits);
short* start_input;
short* scrambler_output;
short* encoder_output;
short* interleaver_output;
short* bpsk_mapper_output;
short* ifft_bpsk_input[64];
Complex* qpsk_mapper_output;
Complex ifft_qpsk_input[64];
start_input = malloc(sizeof(short) * bits);
scrambler_output = malloc(sizeof(short) * bits);
encoder_output = malloc(sizeof(short) * (bits * 2));
interleaver_output = malloc(sizeof(short) * (bits * 2));
bpsk_mapper_output = malloc(sizeof(short) * (bits * 2));
qpsk_mapper_output = malloc(sizeof(Complex) * (bits * 2));
if(qpsk_mapper_output == NULL)
{
fprintf(stderr, "Couldn't allocate that much memory!\n");
return 1;
}
srand(time(NULL));
rbits(seed, 8);
rbits(start_input, bits);
printf("Which modulation type to you want to use? (type BPSK or QPSK): ");
scanf("%s", mode);
if((strcmp(mode, "BPSK") == 0) || (strcmp(mode, "bpsk") == 0))
{
printf("\nSelected modulation type: BPSK\n\n\n");
printf("SCRAMBLER OUTPUT:\n\n");
scrambler(seed, start_input, scrambler_output, bits, 8);
printbinary(scrambler_output, bits);
printf("ENCODER OUTPUT:\n\n");
encoder(scrambler_output, encoder_output, bits);
printbinary(encoder_output, bits*2);
printf("INTERLEAVER OUTPUT:\n\n");
interleaver(encoder_output, interleaver_output, bits, 1);
printbinary(interleaver_output, bits*2);
printf("MAPPER OUTPUT:\n\n");
BPSKmapping(interleaver_output, bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
printf("FIXED-POINT OUTPUT:\n\n");
fixed_point(bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
/*
printf("IFFT OUTPUT:\n\n");
IFFT_BPSK(bpsk_mapper_output, ifft_bpsk_input, twidder, bits*2)
defixed_point(bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
*/ }
else if((strcmp(mode, "QPSK") == 0) || (strcmp(mode, "qpsk") == 0))
{
printf("\nSelected modulation type: QPSK\n\n\n");
printf("SCRAMBLER OUTPUT:\n\n");
scrambler(seed, start_input, scrambler_output, bits, 8);
printbinary(scrambler_output, bits);
printf("ENCODER OUTPUT:\n\n");
encoder(scrambler_output, encoder_output, bits);
printbinary(encoder_output, bits*2);
printf("INTERLEAVER OUTPUT:\n\n");
interleaver(encoder_output, interleaver_output, bits, 2);
printbinary(interleaver_output, bits*2);
printf("MAPPER OUTPUT:\n\n");
QPSKmapping(interleaver_output, qpsk_mapper_output, bits*2);
printcomplex(qpsk_mapper_output, bits*2);
/*
printf("FIXED-POINT OUTPUT:\n\n");
fixed_point_complex(qpsk_mapper_output, bits*2);
printcomplex(qpsk_mapper_output, bits*2);
printf("IFFT OUTPUT:\n\n");
IFFT_QPSK(qpsk_mapper_output, ifft_qpsk_input, twidder, bits*2)
defixed_point(qpsk_mapper_output, bits*2);
printbinary(qpsk_mapper_output, bits*2);
*/ }
else
{
printf("That's an invalid modulation type!\n");
free(start_input);
free(scrambler_output);
free(encoder_output);
free(interleaver_output);
free(bpsk_mapper_output);
free(qpsk_mapper_output);
return 0;
}
free(start_input);
free(scrambler_output);
free(encoder_output);
free(interleaver_output);
free(bpsk_mapper_output);
free(qpsk_mapper_output);
system("PAUSE");
return 0;
}
如果你能帮我解决这个问题,我会很高兴。我认为我的库和主源文件之间存在某种链接问题。
提前致谢。
最佳答案
我猜你只编译 main.c。您还应该包括 ofdm.c。
$ gcc -Wall main.c ofdm.c -o output
关于c - C 中对 'function' 错误的 undefined reference ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9958076/