2024年1月21日发(作者:)

DSP作业

基于TMS320VC5509的语音处理系统

系统简要介绍:

语音信号的采集和播放是语音信号处理的基础, DSP 是各种语音信号处理的平台。TMS320VC55x DSP是德州仪器( TI)C5000 DSP系列里新的一代产品。TMS320VC55x DSP系列主要特点是低功耗, 非常适合在音频处理方面的应用。

TLV320AIC23 (以下简称AIC23)是TI公司生产的一种高性能立体声音频编解码器, 该器件的数字传输字长可以是16、20、24、32 bit,

它支持8~96 kHz的采样率。在数模转换器中的二阶多比特结构还可在采样率为96 kHz的情况下使信躁比达到100dB, 从而使得高质量的数字音频回放成为可能。该芯片在回放中的功率消耗<23 mW。因此,

对于可移动的数字音频播放和录音使用中的模拟输入输出等应用系统, AIC23无疑是十分理想的选择。

综上所述, 选择TMS320VC5509 (以下简称VC5509)作为系统的核心处理器和控制器, 利用A IC23采集语音信号, 然后传送给VC5509。

系统硬件设计:

下图是系统的硬件结构框图, 系统主要包括VC5509和A IC23 两个模块。

系统硬件结构框图

利用VC5509 的片上外设I2C( Inter - Integrated Circuit, 内部集成电路)模块配置AIC23 的内部寄存器; 通过VC5509 的McBSP

(Multi channel Buffered Serial Ports, 多通道缓存串口)接收和发送采样的音频数据。控制通道只在配置AIC23 的内部寄存器时工作, 而当传输音频数据时则处于闲置状态。AIC23通过麦克风输入或者立体声音频输入采集模拟信号, 并把模拟信号转化为数字信号,

存储到DSP的内部RAM中,以便DSP处理。当DSP完成对音频数据的处理以后, AIC23再把数字信号转化为模拟信号, 这样就能够在立体声输出端或者耳机输出端听到声音。

AIC23能够实现与VC5509 DSP的McBSP端口的无缝连接, 使系统设计更加简单。接口的原理框图, 如下图所示。

AIC23与VC5509接口原理图

系统中A IC23的主时钟12 MHz直接由外部的晶振提供。MODE接数字地, 表示利用I2 C控制接口对AIC23传输控制数据。CS接数字地, 定义了I2 C总线上AIC23的外设地址, 通过将CS接到高电平或低电平, 可以选择A IC23作为从设备在I2 C总线上的地址。SCLK和SDIN是AIC23控制端口的移位时钟和数据输入端,分别与VC5509的I2C模块端口SCL和SDA相连。收发时钟信号CLKX1和CLKR1由A

IC23的串行数据输入时钟BCLK提供, 并由A IC23的帧同步信号LRCIN、LRCOUT启动串口数据传输。DX1和DR1分别与A IC23 的D IN

和DOUT 相连, 从而完成VC5509与AIC23间的数字信号通信。

系统软件设计

语音信号在基于DSP的语音处理系统上处理过程的软件流程图如下:

程序流程图

要正确配置DSP的时钟发生器, 产生DSP工作的正常时钟频率,这一个步骤的关键就是数字琐相环PLL 的应用。I2C模块是TMS320VC55xx新增的片内集成外设, 通过I2C对TLV320AIC23进行编程控制,可以使DSP与I2C兼容设备通过该接口进行数据通信。

通过硬件和软件调试, 最终成功采集到语音信号并播放出来,

可以在CCS软件中观察到采集到的语音信号的波形。改变程序中的延迟参数, 可以明显改变混响效果。

硬件电路设计

2.1 总输入电路(自行总结设计)

从左到右各部分电路为:

话筒,开关,语音输入电路,UA741高增益放大电路,有源二阶带通滤波器。

2.2 总输出电路(自行总结设计)

从左到右各部分电路为:

LM386高频功率放大器及其外围器件连接电路,语音输出电路,开关,扬声器。

2.3语音输入与语音输出电路

语音输入电路

语音输出电路

语音信号通道包括模拟输入和模拟输出两个部分。模拟信号的输入输出电路如图 所示。上图中MICBIAS 为提供的麦克风偏压,通常是3/4 AVDD,MICIN为麦克风输入,可以根据需要调整输入增益。下图中LLINEOUT 为左声道输出,RLINEOUT为右声道输出。用户可以根据电阻阻值调节增益的大小,使语音输入输出达到最佳效果。从而实现良好的模拟语音信号输入与模拟信号的输出。

一. 程序设计

语音采集与回放:

extern void InitC5402(void);

extern void OpenMcBSP(void);

extern void CloseMcBSP(void);

extern void READAD50(void);

extern void WRITEAD50(void);

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

** Main Function Program

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

#include "stdio.h"

#include "math.h"

#define pi 3.1415926

void main(void)

{

int k=0;

int x_ad,y_da;

int *px = (int*)0x3000;

int *py = (int*)0x3100;

// for ( ; ; )

{

InitC5402();

OpenMcBSP();

for ( ; ; )

{

// for (j=0; j<=4; j++)

{

READAD50();

px = (int*)(0x3000);

x_ad = *px;

y_da = x_ad;

py = (int*)(0x3100);

*py = y_da;

WRITEAD50();

k++;

}

}

}

Asm文件:

.global _InitC5402

.global _OpenMcBSP

.global _CloseMcBSP

.global _READAD50

.global _WRITEAD50

.include MMRegs.h

_InitC5402:

NOP

LD #0, DP ; reset data–page pointer

STM #0, CLKMD ; software setting of DSP clock

STM #0, CLKMD ; (to divider mode before setting)

TstStatu1:

LDM CLKMD, A

AND #01b, A ;poll STATUS bit

BC TstStatu1, ANEQ

STM #0xF7ff, CLKMD ; set C5402 DSP clock to 10MHz

* STM #0x4007, CLKMD ; set C5402 DSP clock to 100MHz

; (based on DSK crystal at 20MHz)

******* Configure C5402 System Registers *******

STM #0x2000, SWWSR ; 2 wait cycle for IO space &

; 0 wait cycle for data&prog spaces

STM #0x0000,BSCR ; set wait states for bank switch:

; 64k mem bank, extra 0 cycle between

; consecutive prog/data read

; STM #0x1800,ST0 ; ST0 at default setting

; STM #0x2900,ST1 ; ST1 at default setting(note:INTX=1)

; STM #0x00A0,PMST ; MC mode & OVLY=1, vectors at 0080h

******* Set up Timer Control Registers *******

STM #0x0010, TCR ; stop on–chip timer0

STM #0x0010, TCR1 ; stop on–chip timer1

; Timer0 is used as main loop timer

; STM #2499, PRD ; timer0 rate=CPUCLK/1/(PRD+1)

; =40M/2500=16KHz

* STM #6249, PRD ; if CPU at 100M/6250=16KHz

******* Initialize McBSP1 Registers *******

STM SPCR1, McBSP1_SPSA ; register subaddr of SPCR1

STM #0000h, McBSP1_SPSD ; McBSP1 recv = left–justify

; RINT generated by frame sync

STM SPCR2, McBSP1_SPSA ; register subaddr for SPCR2

; XINT generated by frame sync

STM #0000h, McBSP1_SPSD ; McBSP1 Tx = FREE(clock stops

; to run after SW breakpoint

STM RCR1, McBSP1_SPSA ; register subaddr of RCR1

STM #0040h, McBSP1_SPSD ; recv frame1 Dlength = 16 bits

STM RCR2, McBSP1_SPSA ; register subaddr of RCR2

STM #0040h, McBSP1_SPSD ; recv Phase = 1

; ret frame2 Dlength = 16bits

STM XCR1, McBSP1_SPSA ; register subaddr of XCR1

STM #0040h, McBSP1_SPSD ; set the same as recv

STM XCR2, McBSP1_SPSA ; register subaddr of XCR2

STM #0040h, McBSP1_SPSD ; set the same as recv

STM PCR, McBSP1_SPSA ; register subaddress of PCR

STM #000eh, McBSP1_SPSD ; clk and frame from external (slave)

; FS at pulse–mode(00)

******* Finish DSP Initialization *******

STM #0x0000, IMR ; disable peripheral interrupts

STM #0xFFFF, IFR ; clear the intrupts’ flags

RET ; return to main

NOP

NOP

******* Waiting for McBSP0 RX Finished *******

IfRxRDY1:

NOP

STM SPCR1, McBSP1_SPSA ; enable McBSP1 Rx

LDM McBSP1_SPSD, A

AND #0002h, A ; mask RRDY bit

BC IfRxRDY1, AEQ ; keep checking

NOP

NOP

RET ; return

NOP

NOP

******* Waiting for McBSP0 TX Finished *******

IfTxRDY1:

NOP

STM SPCR2, McBSP1_SPSA ; enable McBSP1 Tx

LDM McBSP1_SPSD, A

AND #0002h, A ; mask TRDY bit

BC IfTxRDY1, AEQ ; keep checking

NOP

NOP

RET ; return

NOP

NOP

******************************************

******************************************

_OpenMcBSP:

rsbx xf

call wait

NOP

STM SPCR1, McBSP1_SPSA ; enable McBSP0 RX for ADC data in

LDM McBSP1_SPSD,A

OR #0x0001, A

STLM A, McBSP1_SPSD

STM SPCR2, McBSP1_SPSA ; enable McBSP0 TX for DTMF out

LDM McBSP1_SPSD,A

OR #0x0001, A

STLM A, McBSP1_SPSD

LD #0h, DP ; load data page 0

rpt #23

NOP

ssbx xf

NOP

NOP

; CALL IfTxRDY1

; STM #0x0101, McBSP1_DXR1

; CALL IfTxRDY1

; STM #0x0208, McBSP1_DXR1

;; rsbx xf

;; NOP

;;NOP

CALL IfTxRDY1

STM #0x0001, McBSP1_DXR1;request secondary communication

NOP

CALL IfTxRDY1

STM #0100h, McBSP1_DXR1;write 00h to register 1

CALL IfTxRDY1

STM #0000h, McBSP1_DXR1

NOP

NOP

rpt #20h

nop

CALL IfTxRDY1

STM #0x0001, McBSP1_DXR1;request secondary communication

CALL IfTxRDY1

STM #0200h, McBSP1_DXR1;write 00h to register 2

CALL IfTxRDY1

STM #0000h, McBSP1_DXR1

CALL IfTxRDY1

STM #0x0001, McBSP1_DXR1;request secondary communication

CALL IfTxRDY1

STM #0300h, McBSP1_DXR1;write 00h to register 3

CALL IfTxRDY1

STM #0000h, McBSP1_DXR1

CALL IfTxRDY1

STM #0x0001, McBSP1_DXR1;request secondary communication

CALL IfTxRDY1

STM #0490h, McBSP1_DXR1;write 00h to register 4

;bypass internal DPLL

;and select the Sample Frequency

CALL IfTxRDY1

STM #0000h, McBSP1_DXR1

; CALL IfTxRDY1

; STM #0x0001, McBSP1_DXR1

; CALL IfTxRDY1

; STM #0102h, McBSP1_DXR1 ;enable digital loopback

; CALL IfTxRDY1

; STM #0x0001, McBSP1_DXR1

; CALL IfTxRDY1

; STM #0208h, McBSP1_DXR1 ;enable analog loopback

RET

NOP

NOP

*********************

_CloseMcBSP:

STM SPCR1, McBSP1_SPSA ; disable McBSP0 RX

LDM McBSP1_SPSD,A

AND #0xFFFE, A

STLM A, McBSP1_SPSD

STM SPCR2, McBSP1_SPSA ; disable McBSP0 TX

LDM McBSP1_SPSD,A

AND #0xFFFE, A

STLM A, McBSP1_SPSD

RPT #5

RET

NOP

NOP

_READAD50:

stm 0x00ff,ar3

stm 0x3000,ar2

loopa:

CALL IfRxRDY1

ldm McBSP1_DRR1,b

stl b,*ar2+

; banz loopa,*ar3-

nop

nop

ret

nop

nop

_WRITEAD50:

stm 0x00ff,ar3

stm 0x3100,ar2

loopb:

CALL IfTxRDY1

ldu *ar2+,B

and #0fffeh,b ;mask the LSB

stlm B, McBSP1_DXR1

; banz loopb,*ar3-

nop

nop

ret

nop

nop

wait:

stm 20h,ar3

loop1:

stm 020h,ar4

loop2:

banz loop2,*ar4-

banz loop1,*ar3-

ret

nop

nop

nop

nop

.end

A/D模块:

xtern void InitC5402(void);

extern void OpenMcBSP(void);

extern void CloseMcBSP(void);

extern void READAD50(void);

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

** Main Function Program

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

void main(void)

{

InitC5402();

OpenMcBSP(); 初始化串口和AD50C

while (1)

{

READAD50();

}

}

D/A模块:

extern void InitC5402(void);

extern void OpenMcBSP(void);

extern void CloseMcBSP(void);

extern void WRITEAD50(void);

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

** Main Function Program

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

void main(void)

{

InitC5402();

OpenMcBSP();

while (1)

{

WRITEAD50();

}

}