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

📄 main.c

📁 32路DTMF、MFC编解码
💻 C
字号:
#include <std.h>
#include <math.h>
#include "subaddrdef.h"
#include "tab.h"

int f[32];
int ftemp[32];

unsigned int TS,TSctr; 
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;
			ctrDP[tmpPMST]=0x1A;
		} 
		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=0x4000;			//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=0x4141;		//dmmcr;
	/******接收DMA-4设定*******/
	addrsrc=DRR11_ADD;
	addrdst=(unsigned int)buffer;
	*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 = 0x1020;				//设定可屏蔽中断运行改为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=0x4001;		//启动接收
	*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;
	unsigned 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=0x1111;//*DMPREC | 0x0001;//启动DMA0
	}
	else
	{	
		if(datacount == 0)
		{
			memcpy(oldctrmem,ctrmem,32);	//存储旧指令字
			memcpy(ctrmem,ctrDP,32);		//读取新指令字
		}
		
		for(i=0;i<32;i=i+2)
		{
			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,result,mask;
	unsigned int channel,j;
	int coseff[8];
	int tempdata[32][32];
	int data;
	long tempQ0[8],tempQ1[8],tempQ2[8];
	long cose;
	memcpy(tempdata,buffer,1024);
	//叠代运算
	
	for(channel=0;channel<32;channel=channel+2)
	{	//17400
		FBM1 = (ctrmem[channel] & 0x60)>>5;	//取得接收控制指令
		//取得coseff系数		
		memcpy(coseff,cosefftab[FBM1],8);
		//取得前次计算结果
		memcpy(tempQ0,Q[channel][0],16);
		memcpy(tempQ1,Q[channel][1],16);		
		//j=0;
		//while(j<32)
		for(j=0;j<32;j++)
		{	
			//数据修正幅值控制
			data=tempdata[channel][j]>>3; 
			
			//计算2*cos(2Pi*Fk/Fs)*Q(n-1)
			coseff[0]=coseff[0]*tempQ1[0]>>12;	
			
			coseff[1]=coseff[1]*tempQ1[1]>>12;	
			
			coseff[2]=coseff[2]*tempQ1[2]>>12;	
			
			coseff[3]=coseff[3]*tempQ1[3]>>12;	
			
			coseff[4]=coseff[4]*tempQ1[4]>>12;	
			
			coseff[5]=coseff[5]*tempQ1[5]>>12;	
			
			coseff[6]=coseff[6]*tempQ1[6]>>12;	
			
			coseff[7]=coseff[7]*tempQ1[7]>>12;	
				
			//16b		12b		12b		  12b		
			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(tempQ0,tempQ1,16);
			memcpy(tempQ1,tempQ2,16);	
			//j++;	
		}
		
		memcpy(Q[channel][0],tempQ0,16);
		memcpy(Q[channel][1],tempQ1,16);
	
		if((G_flag & 0x1) !=0)
		{
			//0
			cose=coseff[0] * tempQ1[0];
			tempQ2[0]=tempQ1[0]*tempQ1[0] + tempQ0[0]*tempQ0[0]-cose;
			//1
			cose=coseff[1] * tempQ1[1];
			tempQ2[1]=tempQ1[1]*tempQ1[1] + tempQ0[1]*tempQ0[1]-cose;
			//2
			cose=coseff[2] * tempQ1[2];
			tempQ2[2]=tempQ2[2]*tempQ2[2] + tempQ0[2]*tempQ0[2]-cose;
			//3
			cose=coseff[3] * tempQ1[3];
			tempQ2[3]=tempQ1[3]*tempQ1[3] + tempQ0[3]*tempQ0[3]-cose;
			//4
			cose=coseff[4] * tempQ1[4];
			tempQ2[4]=tempQ1[4]*tempQ1[4] + tempQ0[4]*tempQ0[4]-cose;
			//5
			cose=coseff[5] * tempQ1[5];
			tempQ2[5]=tempQ1[5]*tempQ1[5] + tempQ0[5]*tempQ0[5]-cose;
			//6
			cose=coseff[6] * tempQ1[6];
			tempQ2[6]=tempQ1[6]*tempQ1[6] + tempQ0[6]*tempQ0[6]-cose;
			//7
			cose=coseff[7] * tempQ1[7];
			tempQ2[7]=tempQ1[7]*tempQ1[7] + tempQ0[7]*tempQ0[7]-cose;
			
			result=0;
			mask=0x1;
			for(j=0;j<8;j++)	
			{	
				if(tempQ2[j]>=threshold)
				{
					result=result | mask;
				}
				mask=mask<<1;
			}
		
			for(j=0;j<16;j++)
			{
				if(result==decodetab[FBM1][j])
				{
					result=j;
					j=16;
				}			
			}		
			ackmem[channel]=(result | 0x10) & (ctrmem[channel] & 0x80); 
		}
		
		
	}
	

	//TS=TS ^ TSctr;
	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;
}


/********************************************/
/*				定时器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 + -