📄 8fskmodem.cpp
字号:
// 8FSKModem.cpp : 在本系统中实现了8FSK的调制解调,在解调时使用的是包络检测法
//////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "stdio.h"
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <mbstring.h>
#include <math.h>
//////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//宏定义,常量设定
#define Ts 0.1 //脉冲间隔
#define NN 100
#define deltaT Ts/NN
#define pi 3.14159
#define PARAMHELPNUM 6
#define USEHELPNUM 2
#define READFILESIZE 4 /*一次从文件中读取多少字节*/
#define READFILESIZE_TEST 512 /*一次从文件中读取多少字节*/
///////////////////////////////////////////////////////////////////////////////
char *Commend_Help="8FSK调制解调算法实现"; //系统题目
char *Author_Help=" 周祥"; //系统编写者信息
char *PARAM_HELP[]={
"输入4个参数:",
"\t1.操作类型 1:调制;2:解调;",
"\t2.读出数据的文件名*.txt",
"\t3.写入数据的文件名*.txt",
"\t4.若是解调,输入需要解调的信号的时间",
"******************************"
}; //系统输入参数的说明
char *USE_HELP[]={
"略",
""
}; //系统的使用说明
//8个不同的频率值
double w[8]={2*pi*750,2*pi*800,2*pi*850,2*pi*900,2*pi*950,2*pi*1000,2*pi*1050,2*pi*1100};
///////////////////////////////////函数实现部分///////////////////////////////
int CharsToInt(char *array) //将三位字符转换成对应的整数
{
if(strcmp(array,"000")==0) return 0;
if(strcmp(array,"001")==0) return 1;
if(strcmp(array,"010")==0) return 2;
if(strcmp(array,"011")==0) return 3;
if(strcmp(array,"100")==0) return 4;
if(strcmp(array,"101")==0) return 5;
if(strcmp(array,"110")==0) return 6;
if(strcmp(array,"111")==0) return 7;
return -1;
}
void IntToChar(int value,char result[]) //将整数转换成对应的三位字符
{
if(value==0) strcpy(result,"000 ");
if(value==1) strcpy(result,"001 ");
if(value==2) strcpy(result,"010 ");
if(value==3) strcpy(result,"011 ");
if(value==4) strcpy(result,"100 ");
if(value==5) strcpy(result,"101 ");
if(value==6) strcpy(result,"110 ");
if(value==7) strcpy(result,"111 ");
}
int GetFileLength(FILE *file) //获取文件实际长度
{
rewind(file);
char readbuf[READFILESIZE_TEST] = { 0 };
int filelen = 0,readlen = 0;
readlen = fread( readbuf, sizeof( char ), READFILESIZE_TEST, file);
while( readlen == READFILESIZE_TEST )
{
filelen += READFILESIZE_TEST;
memset(readbuf,0,READFILESIZE_TEST);
filelen = fread(readbuf, sizeof( char ), READFILESIZE_TEST, file);
}
/*这是从文件中读出的最后一批数据,长度可能会等于0,所以要先判断*/
if ( readlen > 0 )
{
filelen += readlen;
memset(readbuf,0 ,READFILESIZE_TEST);
}
return filelen;
}
int getFileNum(FILE *file)
{
rewind(file);
int filelen = 0;
float u;
while(!feof(file))
{
fscanf(file,"%f",&u);
if(!feof(file))
filelen++;
}
filelen=filelen/NN;
return filelen;
}
void Serial(FILE *readfile,int *readin,int readinNum) //每个脉冲对应十进制值(0-7)
{
rewind(readfile);
int readlen = 0;
char readbuf[READFILESIZE] = { 0 };
readlen = fread(readbuf, sizeof( char ), READFILESIZE, readfile );
for(int i=0;i<readinNum;i++)
{
readbuf[READFILESIZE-1]='\0';
readin[i]=CharsToInt(readbuf);
readlen = fread( readbuf, sizeof(char), READFILESIZE, readfile );
}
}
void PrintHelp() //系统说明性文字的显示
{
int i ;
char view;
printf("\t");
for ( i = 0 ; i < 22 ; i++)
{
printf("%c ",5);
}
printf("\n");
printf("\t\t%s\n\n",Commend_Help);
printf("\t\t%s\n",Author_Help);
printf("\t");
for ( i = 0 ; i < 22 ; i++)
{
printf("%c ",5);
}
printf("\n");
printf("\t是否查看系统使用说明及注意事项?(y/n)\t");
scanf("%c",&view);
if(view=='y'||view=='Y')
{
for( i = 0 ; i < USEHELPNUM ; i++)
{
printf("%s\n",USE_HELP[i]);
}
}
for( i = 0 ; i < PARAMHELPNUM ; i++)
{
printf("\t%s\n",PARAM_HELP[i]);
}
return ;
}
void FSKModulate(FILE *readfile, FILE *writefile) //调制算法的具体实现函数
{
float time=0,result;
int i,readinNum,writeoutNum,num;
int fileLength=0;
fileLength=GetFileLength(readfile);
readinNum=(fileLength)/READFILESIZE; //码元个数("000"等的个数)
writeoutNum=readinNum*NN;
int *readin=new int[readinNum];
Serial(readfile,readin,readinNum);
for(i=0;i<writeoutNum;i++)
{
time+=(float)deltaT;
num=i/NN;
result=(float)cos(w[readin[num]]*time);
fprintf(writefile,"%f ",result); //将double型的数据写入文件
}
delete readin;
}
bool FSKDeModulate(FILE *readfile, FILE *writefile) //解调算法的具体实现函数
{
/*totalTime表示截取的信号持续的时间
putoutNum表示最终解调出来的码元(三个符号为一个码元)的个数
dataNum表示从文件中读出的double型数据的个数*/
int totalTime,putoutNum,dataNum,fileNum=0;
int realDataNum=0;
int i,m,q,k,maxFlag;
double energy,maxEnergy=0,everyEnergy,everyEnergyImage,dValue;
printf("请输入需要解调的信号的时间(单位为秒):\t");
scanf("%d",&totalTime);
putoutNum=(int)(totalTime/Ts);
dataNum=putoutNum*NN;
char result[READFILESIZE];
float *getIn=new float[NN];
fileNum=getFileNum(readfile);
if(fileNum<putoutNum)
{
printf("\n\t 已有数据只能提供%.1f秒内的信号解调\n",fileNum*Ts);
return false;
}
rewind(readfile);
for(i=0;i<putoutNum;i++)
{
for(m=0;m<NN;m++)
{
fscanf(readfile,"%f ",&(getIn[m]));
}
for(q=0;q<8;q++)
{
energy=0;
for(m=0;m<NN;m++)
{
everyEnergy=0;
everyEnergyImage=0;
for(k=0;k<NN;k++)
{
if(k==m)
{
dValue=getIn[k]*w[q];
}
else
{
dValue=getIn[k]*(sin(m-k)*w[q]/(m-k));
}
everyEnergy+=dValue*cos((m-k)*w[q]);
everyEnergyImage+=dValue*sin((m-k)*w[q]);
}
energy+=pow(everyEnergy,2)+pow(everyEnergyImage,2);
}
if(energy>maxEnergy)
{
maxEnergy=energy;
maxFlag=q;
}
}
IntToChar(maxFlag,result);
fprintf(writefile,"%s",result);
}
delete getIn;
return true;
}
int Modulate() //调制程序的框架函数
{
char FILENAMERead[32],FILENAMEWrite[32];
FILE *fp, *fp2;
printf("读出数据的文件名*.txt\t");
scanf("%s",&FILENAMERead);
printf("写入数据的文件名*.txt\t");
scanf("%s",&FILENAMEWrite);
if ((fp= fopen(FILENAMERead,"r+b")) == NULL || (fp2 = fopen(FILENAMEWrite,"w+b"))==NULL)
{
printf("无法打开文件!\n");
return 0;
}
FSKModulate(fp,fp2); //调制的实现函数
printf("\n\t 8FSK调制完毕,调制结果存于%s文件\n",FILENAMEWrite);
fclose(fp);
fclose(fp2);
return 1;
}
int DeModulate() //解调程序的框架函数
{
char FILENAMERead[32],FILENAMEWrite[32];
FILE *fp, *fp2;
printf("读出数据的文件名*.txt\t");
scanf("%s",&FILENAMERead);
printf("写入数据的文件名*.txt\t");
scanf("%s",&FILENAMEWrite);
if ((fp= fopen(FILENAMERead,"r")) == NULL || (fp2 = fopen(FILENAMEWrite,"w+b"))==NULL)
{
printf("无法打开文件!\n");
return 0;
}
if(FSKDeModulate(fp,fp2)==true) //解调的实现函数
{
printf("\n\t 8FSK解调完毕,解调结果存于%s文件\n",FILENAMEWrite);
}
fclose(fp);
fclose(fp2);
return 1;
}
void main(int argc, char* argv[]) //主函数,应用程序入口
{
PrintHelp();
printf("请输入操作类型 1:调制 2:解调\t");
int getInt;
scanf("%d",&getInt);
if(getInt==1)
{
Modulate(); //调制
}
else if(getInt==2)
{
DeModulate(); //解调
}
else
{
printf("输入错误!\n");
}
printf("Press Enter key to exit");
getchar();
getchar();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -