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

📄 main17600.c

📁 32路DTMF、MFC编解码
💻 C
字号:
#include <std.h>
#include <math.h>
#include "subaddrdef.h"
#include "tab.h"
#define FBmask 		0x0080
#define FCmask 		0x0040
#define Fmask  		0xFFBF
#define M1mask 		0x0020
#define M0mask 		0x0010
#define Threshold	0x03E8 
int f[32];
int ftemp[32];
unsigned int ctrDP[32];		//控制存储器缓存
unsigned int ackDP[32];		//应答存储器缓存
unsigned int ctrmem[32];	//控制存储器缓存
unsigned int oldctrmem[32];	//控制存储器缓存

unsigned int ackmem[32];	//应答存储器缓存
long threshold=20000000;		//阈值
unsigned FSerr;		//帧同步错误标志(0:正常 1:错误)


long Q[32][2][8];

#pragma DATA_SECTION(buffer,"dmabuff"); 
int buffer[32][32];	//接收数据缓存

void delay(unsigned x,unsigned y);
void interrupt McBSP0_xint(void);
void interrupt McBSP1_rint(void);
void interrupt timer1(void);
void interrupt timer0(void);

void interrupt DMA0_xint(void);		//DMA for data receive
void interrupt DMA4_rint(void);		//DMA for data sent

/************************************/
/*				MAIN				*/			
/************************************/
void main()
{		
	unsigned int addrsrc,addrdst;
	unsigned tmpPMST;
	unsigned int ii;
	
	//禁止所有可屏蔽中断
	asm(" SSBX INTM");
	//设定PLL		
	CLKMD=0x0;
	ii=CLKMD & 0x0001;
	while(ii)
	{
		ii=CLKMD & 0x0001;
	}
	CLKMD=0x9007;
	delay(1,256);	//等待PLL锁定	
	//初试化DPRAM
	for(ii=0;ii<32;ii++)
	{
		ctrDP[ii]=0;
		ackmem[ii]=0;
		
		f[ii]=0;
		ftemp[ii]=0;
		for(tmpPMST=0;tmpPMST<32;tmpPMST++)
		{
			buffer[ii][tmpPMST]=0;
			//f[ii][tmpPMST]=0;
		} 
		for(tmpPMST=0;tmpPMST<8;tmpPMST++)
		{
			Q[ii][tmpPMST][0]=0;
			Q[ii][tmpPMST][1]=0;
			Q[ii][tmpPMST][2]=0;
		
		}
	}

/**************所有McBSP复位******************/
	//McBSP0
	*SPSA0=SPCR1_SUBADD;
	*SPSD0=*SPSD0 & 0xFFFE;
	*SPSA0=SPCR2_SUBADD;
	*SPSD0=*SPSD0 & 0xFF3E;
	//McBSP1
	*SPSA1=SPCR1_SUBADD;
	*SPSD1=*SPSD1 & 0xFFFE;
	*SPSA1=SPCR2_SUBADD;
	*SPSD1=*SPSD1 & 0xFF3E;
/****************McBSP特性设定*****************/
	/*******发送McBSP-0设定***********/
	*SPSA0=SPCR1_SUBADD;	 
	*SPSD0=0x4000;			//spcr1
	*SPSA0=SPCR2_SUBADD;
	*SPSD0=0x0010;			//spcr2
	*SPSA0=RCR1_SUBADD;
	*SPSD0=0x1F00;			//rcr1
	*SPSA0=RCR2_SUBADD;
	*SPSD0=0x001C;			//rcr2
	*SPSA0=XCR1_SUBADD;
	*SPSD0=0x1F00;			//xcr1
	*SPSA0=XCR2_SUBADD;
	*SPSD0=0x001C;			//xcr2
	*SPSA0=MCR1_SUBADD;
	*SPSD0=0x0001;			//mcr1
	*SPSA0=MCR2_SUBADD;
	*SPSD0=0x0001;			//mcr2	
	
	*SPSA0=RCERA_SUBADD;
	*SPSD0=0xFFFF;
	*SPSA0=RCERB_SUBADD;
	*SPSD0=0xFFFF;
	*SPSA0=XCERA_SUBADD;
	*SPSD0=0xFFFF;
	*SPSA0=XCERB_SUBADD;
	*SPSD0=0xFFFF;
	/******McBSP0时钟及帧同步设定*******/	
	*SPSA0=SRGR1_SUBADD;
	*SPSD0=0x0031;			//srgr1
	*SPSA0=SRGR2_SUBADD;
	*SPSD0=0x30FF;			//srgr2
	/********McBSP0管脚特性设定********/	
	*SPSA0=PCR_SUBADD;
	*SPSD0=0x0F00;			//pcr	同步信号由外部输入上升沿有效
	
/****************接收McBSP-1特性设定*****************/
	*SPSA1=SPCR1_SUBADD;
	*SPSD1=0x4030;			//spcr1
	*SPSA1=SPCR2_SUBADD;
	*SPSD1=0x0010;			//spcr2
	*SPSA1=RCR1_SUBADD;
	*SPSD1=0x1F00;			//rcr1
	*SPSA1=RCR2_SUBADD;
	*SPSD1=0x001C;			//rcr2
	*SPSA1=XCR1_SUBADD;
	*SPSD1=0x1F00;			//xcr1
	*SPSA1=XCR2_SUBADD;
	*SPSD1=0x001C;			//xcr2
	*SPSA1=MCR1_SUBADD;
	*SPSD1=0x0001;			//mcr1
	*SPSA1=MCR2_SUBADD;
	*SPSD1=0x0001;			//mcr2	
	
	*SPSA1=RCERA_SUBADD;
	*SPSD1=0xFFFF;
	*SPSA1=RCERB_SUBADD;
	*SPSD1=0xFFFF;
	*SPSA1=XCERA_SUBADD;
	*SPSD1=0xFFFF;
	*SPSA1=XCERB_SUBADD;
	*SPSD1=0xFFFF;
	/******McBSP1时钟及帧同步设定*******/	
	*SPSA1=SRGR1_SUBADD;
	*SPSD1=0x0000;				//srgr1
	*SPSA1=SRGR2_SUBADD;
	*SPSD1=0x8000;				//srgr2
	/********McBSP1管脚特性设定*********/	
	*SPSA1=PCR_SUBADD;
	*SPSD1=0x0000;			//pcr	
/*************所有DMA通道复位*****************/
	*DMPREC=0x0;
	*DMSA=0x0;
	for (ii= 0;ii < 40; ii++)
  	{
      *DMSDI=0x00; 
    }  
/*****************DMA设定**********************/	
	/******发送DMA-0设定*******/
	addrsrc=(unsigned int)f;
	addrdst=DXR10_ADD;
	*DMSA=0;
 	*DMSDI=addrsrc;
	*DMSDI=addrdst;
	*DMSDI=0x001F;
	*DMSDI=0x2000;		//dmsfc
	*DMSDI=0xC141;		//dmmcr;
	/******接收DMA-4设定*******/
	addrsrc=DRR11_ADD;
	addrdst=(unsigned int)buffer[0];
	*DMSA=20;
	*DMSDI=addrsrc;
	*DMSDI=addrdst;
	*DMSDI=0x001F; 
	*DMSDI=0x501F;	//dmsfc
	*DMSDI=0xC055;	//dmmcr;
	/******DMA全局设定*******/
	*DMSA=DMSRCP_SUBADD;
	*DMSDI=0x0;			//dmsrcp
	*DMSDI=0x0;			//dmstp
	*DMSDI=32;			//dmidx0
	*DMSDI=32;			//dmidx1
	*DMSDI=-991;		//dmfri0
	*DMSDI=-991;		//dmfri1
	*DMSDI=addrsrc;		//dmgsa
	*DMSDI=addrdst;		//dmgda
	*DMSDI=0x1F;		//dmgcr
	*DMSDI=0x1F;		//dmgfr
	
	/******DMA优先级设定******/
	*DMPREC=0x1100;			//dmprec
	
/*************中断及时钟设定****************/
	tmpPMST = PMST; 	      	//读PMST
	PMST = tmpPMST & 0xff;		//IPTR=0000,0000,1(重定向中断矢量表)
	
	IMR = 0x1060;				//设定可屏蔽中断运行改为0x00B8
	PRD0=0xC349;				//设定定时器分频系数(500us)
	TCR0=0x0019;				//初试化定时器
	TIM0=0x000;
	
	PRD1=0xC349;				//设定定时器分频系数
	TCR1=0x0017;				//初试化定时器
	TIM1=0x000;
	
	//TCR1=0x0007;				//启动定时器
	//TCR0=0x0009;
	
	IFR = 0xFFFF;				//清中断标志位
	asm(" RSBX INTM");      	//开中断
	
	
	*DMPREC=*DMPREC | 0x0001;//启动DMA0
	
	*DMPREC=*DMPREC | 0x0010;//启动DMA4
	
	*SPSA0=SPCR2_SUBADD;//发送
	*SPSD0=0x0040;		//启动采样率发生器
	*SPSA1=SPCR2_SUBADD;//接收
	*SPSD1=0x0040;		//启动采样率发生器
	delay(1,50);
	*SPSA0=SPCR2_SUBADD;//发送
	*SPSA1=SPCR1_SUBADD;//接收
	
	//*SPSD0=0x0050;		//启动发送时钟	
	//*SPSD0=0x00D0;		//启动帧同步
	*SPSD1=0x4031;		//启动接收
	*SPSD0=0x00D1;
	ii=0;	
	while(1)
	{	
		//同步错误判断
 		*SPSA1=SPCR1_SUBADD;
		FSerr=*SPSD1 & 0x0008;
		*SPSA0=SPCR2_SUBADD;
		FSerr=FSerr | (*SPSD0);
		FSerr=FSerr & 0x0008;
		if(FSerr!=0)
		{
			ii++;
			if(ii>10)
			{	
				asm(" SSBX INTM");
				//点亮报警信号灯
				*SPSA1=PCR_SUBADD;
			 	*SPSD1=*SPSD1 & 0xFFDF;
				ii=0;
			}
		}
		else
		{
			ii=0;
		}
		
	}

}


void delay(unsigned x,unsigned y)
{
	int i,j;
	for(i=0;i<x;i++)
	{
		for(j=0;j<y;j++)
		{
			;
		}	
	}
}
/********************************************************/
/*					McBSP0传送中断程序					*/
/*	功能1:将新数据搬移至DMA_X缓存						*/
/*		2:读取控制存储器至缓存ctrmem					*/
/*		3:判别并进行相应PCM编码运算						*/
/*														*/
/********************************************************/
void interrupt McBSP0_xint()
{	
	static unsigned datacount=0;
	static unsigned Framcount[32]={0,0,0,0,0,0,0,0
								  ,0,0,0,0,0,0,0,0
								  ,0,0,0,0,0,0,0,0
								  ,0,0,0,0,0,0,0,0};
	
	unsigned int addrsrc,addrdst;
	unsigned int old,new,M1M0,code;
	unsigned int index0,index1;
	int i;
	datacount=datacount & 0x3;
	if(datacount & 0x1 != 0)
	{
		addrsrc=(unsigned int)f;
		addrdst=DXR10_ADD;
		*DMSA=0;
		*DMSDI=addrsrc;
		*DMSDI=addrdst;
		*DMSDI=0x001F;
		//*DMSDI=0x2000;		//dmsfc
		//*DMSDI=0x6141;		//dmmcr;
		memcpy(f,ftemp,32);
		*DMPREC=*DMPREC | 0x0001;//启动DMA0
	}
	else
	{	
		if(datacount == 0)
		{
			memcpy(oldctrmem,ctrmem,32);	//存储旧指令字
			memcpy(ctrmem,ctrDP,32);		//读取新指令字
		}
		
		for(i=0;i<32;i++)
		{
			old = oldctrmem[i] & 0x3F;
			new = ctrmem[i] & 0x3F;
			if(old!=new){Framcount[i]=0;}
		
			M1M0 = (new & 0x30)>>4;	//取得发送控制指令
			code = new & 0x0F;	//取得发送码字
			//计算相对寻址地址
			index0 = (indextab[M1M0][code][0] * Framcount[i]) & 0x7FF;
			index1 = (indextab[M1M0][code][1] * Framcount[i]) & 0x7FF;
			//计算下一帧待发送PCM值并暂存	
			ftemp[i] = MFC[index0] + MFC[index1];
	
			Framcount[i]++;
		}
		
	}
	
	datacount++;
		
}	

/********************************************************/
/********************************************************/	

void interrupt DMA4_rint()
{
	static unsigned G_flag=0;
	unsigned int FBM1;
	int channel,j,k;
	int coseff[8];
	int tempdata[32][32];
	int temp,data;
	long tempQ0[8],tempQ1[8],tempQ2[8];
	long tempcos,cose,Q2;
	memcpy(tempdata,buffer,1024);
	//叠代运算
	for(channel=0;channel<32;channel++)
	{	//17600
		FBM1 = (ctrmem[channel] & 0x60)>>5;
				
		memcpy(coseff,cosefftab[FBM1],8);
		memcpy(tempQ0,Q[channel][0],16);
		memcpy(tempQ1,Q[channel][1],16);		
		for(j=0;j<32;j++)
		{	
			//数据修正幅值控制
			temp=tempdata[channel][j];
			data=(temp<0 ? -((-temp)>>3) : temp>>3); 
			
			//计算2*cos(2Pi*Fk/Fs)*Q(n-1)
			tempcos=coseff[0]*tempQ1[0];
			coseff[0]=(tempcos<0 ? -((-tempcos)>>12):(tempcos>>12));	
			
			tempcos=coseff[1]*tempQ1[1];
			coseff[1]=(tempcos<0 ? -((-tempcos)>>12):(tempcos>>12));	
			
			tempcos=coseff[2]*tempQ1[2];
			coseff[2]=(tempcos<0 ? -((-tempcos)>>12):(tempcos>>12));	
			
			tempcos=coseff[3]*tempQ1[3];
			coseff[3]=(tempcos<0 ? -((-tempcos)>>12):(tempcos>>12));	
			
			tempcos=coseff[4]*tempQ1[4];
			coseff[4]=(tempcos<0 ? -((-tempcos)>>12):(tempcos>>12));	
			
			tempcos=coseff[5]*tempQ1[5];
			coseff[5]=(tempcos<0 ? -((-tempcos)>>12):(tempcos>>12));	
			
			tempcos=coseff[6]*tempQ1[6];
			coseff[6]=(tempcos<0 ? -((-tempcos)>>12):(tempcos>>12));	
			
			tempcos=coseff[7]*tempQ1[7];
			coseff[7]=(tempcos<0 ? -((-tempcos)>>12):(tempcos>>12));	
			//数据移位
			//memcpy(tempQ0,Q[channel][1],16);	
								
			tempQ2[0]=coseff[0]-tempQ0[0]+data;
						
			tempQ2[1]=coseff[1]-tempQ0[1]+data;
						
			tempQ2[2]=coseff[2]-tempQ0[2]+data;
						
			tempQ2[3]=coseff[3]-tempQ0[3]+data;
						
			tempQ2[4]=coseff[4]-tempQ0[4]+data;
						
			tempQ2[5]=coseff[5]-tempQ0[5]+data;
						
			tempQ2[6]=coseff[6]-tempQ0[6]+data;
						
			tempQ2[7]=coseff[7]-tempQ0[7]+data;
			
			memcpy(Q[channel][0],tempQ1,16);
			memcpy(Q[channel][1],tempQ2,16);		
		}
	
		if((G_flag & 0x1) !=0)
		{
			//0
			
			cose=coseff[0] * Q[channel][0][0];
			Q2=Q[channel][1][0] * Q[channel][1][0] 
				+Q[channel][0][0] * Q[channel][0][0];
			Q[channel][2][0]=Q2-cose;
			//1
			cose=coseff[1] * Q[channel][0][1];
			Q2=Q[channel][1][1] * Q[channel][1][1] 
				+Q[channel][0][1] * Q[channel][0][1];
			Q[channel][2][1]=Q2-cose;
			//2
			cose=coseff[2] * Q[channel][0][2];
			Q2=Q[channel][1][2] * Q[channel][1][2] 
				+Q[channel][0][2] * Q[channel][0][2];
			Q[channel][2][2]=Q2-cose;
			//3
			cose=coseff[3] * Q[channel][0][3];
			Q2=Q[channel][1][3] * Q[channel][1][3] 
				+Q[channel][0][3] * Q[channel][0][3];
			Q[channel][2][3]=Q2-cose;
			//4
			cose=coseff[4] * Q[channel][0][4];
			Q2=Q[channel][1][4] * Q[channel][1][4] 
				+Q[channel][0][4] * Q[channel][0][4];
			Q[channel][2][4]=Q2-cose;
			//5
			cose=coseff[5] * Q[channel][0][5];
			Q2=Q[channel][1][5] * Q[channel][1][5] 
				+Q[channel][0][5] * Q[channel][0][5];
			Q[channel][2][5]=Q2-cose;
			//6
			cose=coseff[6] * Q[channel][0][6];
			Q2=Q[channel][1][6] * Q[channel][1][6] 
				+Q[channel][0][0] * Q[channel][0][6];
			Q[channel][2][6]=Q2-cose;
			//7
			cose=coseff[7] * Q[channel][0][7];
			Q2=Q[channel][1][7] * Q[channel][1][7] 
				+Q[channel][0][7] * Q[channel][0][7];
			Q[channel][2][7]=Q2-cose;
			
		}
	
	}
	

	
	G_flag++;

}
/********************************************************/
/********************************************************/	
void interrupt DMA0_xint()
{
	static unsigned datacount=0;
	unsigned int addrsrc,addrdst;
	
	addrsrc=(unsigned int)f[datacount];
	addrdst=DXR10_ADD;
	*DMSA=0;
	*DMSDI=addrsrc;
	*DMSDI=addrdst;
	*DMSDI=0x001F;
	*DMSDI=0x2000;		//dmsfc
	*DMSDI=0xC141;		//dmmcr;
	*DMPREC=*DMPREC | 0x0001;//启动DMA0
	//datacount++;
	//datacount=datacount & 0x1;
}

/********************************************************/
/*					McBSP0接收中断程序					*/
/*	功能1:分析控制参数									*/
/*		2:调用戈则尔算法解码							*/
/*		3:编码写入应答缓冲								*/
/*														*/
/********************************************************/
void interrupt McBSP1_rint()
{
			
		;
}



/********************************************************/
/*					T1计时中断程序						*/
/*			功能1:读取控制存储器至缓存					*/
/*				2:分析发送控制参数						*/
/********************************************************/
void interrupt timer1()
{
	
	
	;
		
	

}

/********************************************/
/*				定时器0中断					*/
/*		功能:控制Run/Err工作指示灯			*/
/********************************************/
void interrupt timer0()
{

	static unsigned Tcount;
		
	if(Tcount>=1)
	{
		*SPSA1=PCR_SUBADD;
		*SPSD1=*SPSD1 ^ 0x0020;
		Tcount=0;
	}
	
	Tcount++;


}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -