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

📄 8fskmodem.cpp

📁 ScopeFIR designs Finite Impulse Response [FIR] filters using the Parks-McClellan algorithm.
💻 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 + -