A/D、D/A转换器的初始化编程: /* 获取设置A/D和D/A的句柄 */ hHandset = codec_open(HANDSET_CODEC); /* 设置CODEC的工作参数 */ /* DAC和ADC工作在15+1bit模式 */
codec_dac_mode(hHandset, CODEC_DAC_15BIT); codec_adc_mode(hHandset, CODEC_ADC_15BIT); /* ADC模拟增益设置为6dB */
codec_ain_gain(hHandset, CODEC_AIN_6dB); /* 设置DAC模拟输出增益为-6dB */
codec_aout_gain(hHandset, CODEC_AOUT_MINUS_6dB); /* 设置抽样频率为8KHz */
codec_sample_rate(hHandset,SR_8000);
3.2.5 McBSP的结构及寄存器部分配置
McBSP:多通道缓冲串行口(Multi-channel Buffered Serial Port),是串行口的一种。它既可以利用DSP提供的DMA功能实现自动缓存功能,又可以实现时分多路通信功能。TMS320C5402有两个McBSP串口,分别为McBSP0、McBSP1。
McBSP由引脚、接收发送部分、时钟及祯同步信号产生、多通道选择以及CPU中断信号和DMA同步信号组成。
引脚中我们用到的只有两个: DR和DX,通过这两个引脚实现DSP与外部设备的通信和数据交换。DR用来接收数据,DX完成数据的发送。这两个引脚分别对应两个寄存器DRR和DXR,如果准备就绪,从这两个寄存器中就可以读取数据了。(注:两个McBSP串口,所以两个寄存器分别用DRR1、DXR1、 DRR2、DXR2表示)
那么如何判断接收器和发送器是否准备就绪呢?这就采用了SPCR1、SPCR2控制位来判断。当RRDY=0时,接收器未就绪;当RRDY=1时,接受器就绪,可以从DDR1或2种读取数据。当XRDY=0时,发送器尚未就绪;当XRDY=1时,发送器就绪,可以从XDR1或2种发送数据。
所以在实际实验中我们采用以下语句命令: (1).接收数据时
while (!MCBSP_RRDY(HANDSET_CODEC)) {}; //查询、等待接收handset处的采样
data = *(volatile u16*)DRR1_ADDR(HANDSET_CODEC); //从handset处读取采样
6
(2).发送数据时
while (!MCBSP_XRDY(HANDSET_CODEC)) {}; *(volatile u16*)DXR1_ADDR(HANDSET_CODEC) = data1; //a律解压完成后,DSP将数据通过串行口McBSP1发送 3.2.6均匀量化、非均匀量化
如果采用相等的量化间隔对采样得到的信号作量化,那么这种量化称为均匀量化。均匀量化就是采用相同的“等分尺”来度量采样得到的幅度,也称为线性量化,如图2所示。均匀量化PCM就是直接对声音信号作A/D转换,在处理过程中没有利用声音信号的任何特性,也没有进行压缩。该方法将输入的声音信号的振幅范围分成个等份(B为量化位数),所以落入同一等份数的采样值都编码成相同的B位二进制码。只要采样频率足够大,量化位数也适当,便能获得较高的声音信号数字化效果。为了满足听觉上的效果,均匀量化PCM必须使用较多的量化位数。这样所记录和产生的音乐,可以达到最接近原声的效果。当然提高采样率及分辨率后,将引起储存数据空间的增大。
图3-4 图3-5 PCM的编码规律
PCM: Pulse Code Modulation 脉冲编码调制,一般速率为64kbps,是指音号直接采样量化的一种编码办法,采样速率为8000Hz,每样点用8bit表示。CD 用16bit 44.1kHz采样的PCM。 数字电话用的也是PCM,PCM是非线性编码,根据G.711建议,编码结束后需要做偶数位翻转。
如果编码后结果是 0110 1001 则在发送的时候需要经过偶数位翻转得到: 0011 1100 。PCM码的压缩分a律u律,在中国使用a律。PCM码有很多种,网络上主要有4种:MANCHESTER码,差分Manchester码,AMI码,HDB3码,2B1Q码。分别用于以太网,ISDN,DDN,电话。 A律压扩其特性可表示为:
7
很明显,小信号时为线性特性,大信号时近似为对数特性。这种压扩特性常把压缩、量化和编码合为一体。A律可用13段折线逼近(相当于A=87.6),便于用数字电路实现。 13段折线的压缩特性如下图。过程为:
第一步:把x(x>0 部分)划分为不均匀的8段。第一分点取在V/2处,然后每段都是剩下部分的1/2。;依次取第八段为V~V/2 第七段为V/2~V/4;第一段为V/128~0。 第二步:把每段均匀划分为16等份,每一份表示一个量化级,显然8段共16x8=128= 个量化级,需要二进制7位编码表示。可以看出每个量化级是不均匀的。在小信号的量化台阶很小,使小信号时量化噪声减小。如果按均匀量化计算,以最小台阶为单位,最大信号需用L=128X16=2048=
个量化级表示,既需要11位编码。这样非均匀编码
使小信号量化台阶缩小了16倍,相当于小信号信噪比改善了20dB。
第三步:把y轴均匀划分为8段,每段均匀分为16分。这样y也分为128个量化级,与x轴的128个量化级对应。因此,压扩特性各段的斜率 一段斜率:
其他段为:
。
以上分段为x取正值时的情况。而x取负值时,压扩特性与x取正值成奇对称。在正8段和负8段中,正1,2段和负1,2段斜率相同,合为一段。所以原来的16段折线变为13段折线。
图3-6
是不同的。第
8
四.程序设计、调试与结果分析 4.1程序流程图
图4-1
4.2 编译流程
首先要掌握实验的编译流程,从而在其指导下进行实验。
(1).C编译器(C Compiler)将C语言源程序自动地编译为C54x的汇编语言源程序。
(2).汇编器(Assembler)将汇编语言源文件汇编成机器语言COFF目标文件。源文件中包括指令、汇编命令以及宏命令。
(3).链接器(Linker)把汇编生成的、可重新定位的COFF目标模块组合成一个可执行的COFF目标模块。当链接器生成可执行模块时,它要调整对符号的引用,并解决外部引用的问题。它也可以接受来自文档管理其中的目标文件,以及链接以前运行时所生成的输出模块。
(4).文档管理器(Archiver)将一组文件(源文件或目标文件)集中为一个文档文件库。汇编时,可以搜索宏文件库,并通过源文件中的宏命令来调用。也可以利用文档管理器,将一组目标文件集中到一个目标文件库。通过文档管理器来替换、添加、删除和提取库文件。
(5).助记符指令,将包含的助记符指令的汇编语言源文件转换成包含代数指令的汇编语言源文件。
9
(6).建库实用程序。用来建立用户自己用的、C语言编写的支持运行的库函数。链接时,用rts.src中的源文件代码和rts.lib中的目标代码提供标准的支持运行的库函数。十六进制转换程序,将COFF目标文件转换成TI、Intel等目标文件格式,可以下载到EPROM编程器,以便对用户的EPROM进行编程。
(7).绝对列表程序将链接后的目标文件作为输入,生成.abs输出文件。对.abs文件汇编产生包含绝对地址的清单。如果没有绝对制表程序,所生成清单可能是冗长的,并要求进行许多人工操作。交叉引用制表程序利用目标文件生成一个交叉引用清单,列出所链 接的源文件中的符号以及它们的定义和引用情况。
4.3源程序
/*****************************************************************************/
/* 头文件 */
/*****************************************************************************/
#include
/*****************************************************************************/
/* 变量宏定义 */
/*****************************************************************************/
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define NSEGS (8) /* Number of A-law segments. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */
/*****************************************************************************/
/* 函数声明 */
/*****************************************************************************/
void delay(s16 period); void led(s16 cnt); void initcodec(void); void flashenable(void);
unsigned char data2alaw(s16 pcm_val);
10