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

📄 dtmf_enc.asm

📁 DSP c54** 实现的DTMF产生和解码 汇编原代码 包括了goerztel算法详细讲解
💻 ASM
字号:
**************************************************************
*   (C) COPYRIGHT TEXAS INSTRUMENTS, INC. 1996               *
**************************************************************
*   Program Name:     DTMF tone generator                    *
*   File Name:        dtmf_enc.asm                           *
*   File Description: This file contains the code for a      *
*                     DTMF tone generator                    *
*                     (TMS320C54x EVM version)               *
*                                                            *
*   Author:   Gunter Schmer                                  *
*   Date:     06/06/96                                       *
*   Revision: 1.0                                            *
*   Latest working date:  06/06/96                           *
**************************************************************

	.title	"dtmf encoder"
	.mmregs

***************************************
***   Constants
***************************************
TIME_SH	.set	03ffh	;short duration (128 msec)
TIME_LG	.set	03ffh	;long duration  (128 msec)
DAC_OFS	.set	000h	;DAC offset

***************************************
***   Variables
***************************************
        .bss    aic_conf,1
	.bss	rcv,1		;receive variable
	.bss	tra,1		;transmit variable
	.bss	DIGIT,1		;current digit
	.bss	DIGIT_PTR,1	;points to current digit in PHNBR table
	.bss	TIMER,1		;timer counter
	.bss	T1_OFS,1	;offset for tone 1 (row tone)
	.bss	T2_OFS,1	;offset for tone 2 (column tone)
	.bss	TASK,1		;holds the nbr of the task that is to be executed


***************************************
***   Tables
***************************************

*******************************************************
* The following table assembles the coefficients and  *
* initial conditions for the difference equations of  *
* the digital sinusoidal oscillators.                 *
*                                                     *
* In general:                                         *
*   DEQ:    y(n) = 2*cos(2pi*f/fs)*y(n-1) - y(n-2)    *
*   I.C.:   y(-1) = 0                                 *
*           y(-2) = -A*sin(2pi*f/fs)                  *
*   where   A  = desired amplitude of sine wave       *
*           f  = desired frequency of sine wave       *
*           fs = sampling frequency                   *
*                                                     *
* Example:                                            *
*       .word    cos(2pi*f/fs)*32768	;coefficient  *
*       .word    0			;y(-1)        *
*       .word    -A*sin(2pi*f/fs)*32768	;y(-2)        *
*                                                     *
*******************************************************
        .sect   "tbl_tone"
TONES   .word    27978          ; row 1      coef
        .word        0          ;            y(n-1)
        .word     -533          ;            y(n-2)

        .word    26956          ; row 2      coef
        .word        0          ;            y(n-1)
        .word     -582		;            y(n-2)

        .word    25701          ; row 3      coef
        .word        0          ;            y(n-1)
        .word     -635		;            y(n-2)

        .word    24219          ; row 4      coef
        .word        0          ;            y(n-1)
        .word     -689		;            y(n-2)

        .word    19073          ; column 1   coef
        .word        0          ;            y(n-1)
        .word     -833		;            y(n-2)

        .word    16325          ; column 2   coef
        .word        0          ;            y(n-1)
        .word     -888		;            y(n-2)

        .word    13085          ; column 3   coef
        .word        0          ;            y(n-1)
        .word     -938		;            y(n-2)

        .word     9314          ; column 4   coef
        .word        0          ;            y(n-1)
        .word     -981		;            y(n-2)


*****************************************************************
* The following table contains offsets into the                 *
* tone table tbl_tone.                                          *
* The offset for the row-tone is the (upper byte) of each word  *
* The offset for the column-tone is the (lower byte + #12)      *
*                                                               *
*****************************************************************
	.sect	"tbl_keys"
KEYS	.word	0903h		; '0'  example: 0903h --> 3.row, 1.column (*3)
	.word	0000h		; '1'
	.word	0003h		; '2'
	.word	0006h		; '3'
	.word	0300h		; '4'
	.word	0303h		; '5'
	.word	0306h		; '6'
	.word	0600h		; '7'
	.word	0603h		; '8'
	.word	0606h		; '9'
	.word	0009h		; 'A'
	.word	0309h		; 'B'
	.word	0609h		; 'C'
	.word	0906h		; 'D'
	.word	0900h		; 'E' = '*'
	.word	0906h		; 'F' = '#'


****************************************************************
* The following table contains the phone number to be          *
* encoded. The format is as follows                            *
*                                                              *
* PH_NBR   .word   4,2,7,E,F,A,3,-1                            *
*                                                              *
* is the foll nbr: 4 2 7 * # A 3   (-1 terminates the encoding)*
****************************************************************
	.sect	"tbl_phnr"
PH_NBR	.word	1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,-1	;Phone Number



******************************************
*       Stack setup
*****************************************
BOS     .usect  "stack",20h	; setup stack
TOS     .usect  "stack",1	; Top of stack at reset


******************************************
*       Interrupt Vectors
******************************************
V_TBL	.sect   "vectors"

RESET	bd      START		; reset vector
        stm     #TOS,SP		; Setup stack

	.space	19*4*16

RINT0	retf			; 0xFFD0
	nop
	nop
	nop

XINT0	retf			; 0xFFD4
	nop
	nop
	nop

RINT1	bd    	RINT1_ISR	; 0xFFD8
	pshm    ST0             ; Save status registers on stack
	pshm    ST1

XINT1	retf			; 0xFFDC
	nop
	nop
	nop


******************************************
*       CODE STARTS HERE
******************************************
       .text
START
	ssbx	INTM		;global interrupt disable
	ld	#0,DP		;initialize data pointer


;------------ Initialize Hardware ------------------------------------

	call	hwinit		;hardware initialization subroutine


;------------ Initialize Software ------------------------------------

        ssbx    SXM		;data sign ext. before usage
        rsbx    OVM		;no saturation of accu if overflow
	ssbx	FRCT		;fractional mode bit, left shift of
				;  multiplier to compensate for extra 
				;  sign bit

	stm	#0040h,IMR	;enable RINT1 interrupt
	stm	#00c8h,IFR	;clear all pending serial port or timer interrupts
	rsbx	INTM		;global interrupt enable

	mvmd	DRR1,rcv	;dummy read
	mvdm	tra,DXR1	;dummy write

	b	Main

******************************************
*       Main Program
******************************************

Main
	ld	#aic_conf,DP	;DP to variables
	st	#PH_NBR,DIGIT_PTR  ;initialize pointer to PHNBR table
	st	#0,TASK		;initialize beginning task
	st	#0,TIMER	;initialize timer to zero

next	idle	1
	call	tasks		;actual processing following RINT interrupt
	nop
	b	next

done	b	done


************************************************************
* Task Scheduler:      
* Run this task scheduler section at the beginning of
* each RINT_ISR process
*
* 
************************************************************
tasks	cmpm	TASK,#00h
	bc	task1,NTC	;if(TASK!=0) branch to task1
				;  else branch to task0 

task0	cmpm	TIMER,#00h
	bc	task01,NTC	;branch if timer not zero
	mvdm	DIGIT_PTR,AR1	; AR1 points to digit in PHNBR table
	st	#01h,TASK	; TASK of next RINT_ISR is task1
	st	#TIME_LG,TIMER	; set timer to long duration
	ld	*AR1+,A		; load A with digit
	bc	done,alt	; done if digit is -1 !
	mvmd	AR1,DIGIT_PTR	; save new pointer to digit in PHNBR table
	call	unpack		; unpack digit: A --> T1_OFS, T2_OFS
	b	task02
task01	ld	TIMER,A
	sub	#1,A
	stl	A,TIMER		;decrement timer
task02	call	quiet
	b	task3		;branch to task3


task1	cmpm	TIMER,#00h
	bc	task11,NTC	;branch if timer not zero
	st	#00h,TASK	; TASK of next RINT_ISR is task0
	st	#TIME_SH,TIMER	; set timer to short duration
	b	task12
task11	ld	TIMER,A
	sub	#1,A
	stl	A,TIMER		;decrement timer
task12	mvdm	T1_OFS,AR2	;AR2 is offset for row-tone
	mvdm	T2_OFS,AR3	;AR3 is offset for column-tone
	call	tone

task3	ret

	


*****************************************************************
* SUBROUTINE:  unpack                                           *
* Description: Maps the key value (in A) into two offsets for   *
*              two tones and writes results into variables      *
*              T1_OFS, T2_OFS                                   *
* Uses:        AR2                                              *
* Input:       A                                                *
* Output:      none                                             *
*****************************************************************
unpack	stlm	A,AR2		;AR2 keys-map offset for unpacking
	ld	#DIGIT,DP	;DP to variables
	nop			;pipeline conflict(1) + latency(1) with AR2
	ld	*AR2(KEYS),A	;load A with keys-map value
	ld	*AR2(KEYS),B	;load B with keys-map value
	and	#0f00h,A	;mask out the row portion
	and	#000fh,B	;mask out the column portion
	sftl	A,-8		;right shift A by 8
	add	#12,B		;add 4*3 words offset to point into column portion
	stl	A,T1_OFS	;store tone 1 offset (row tone)
	stl	B,T2_OFS	;store tone 2 offset (column tone)
	ret


*****************************************************************
* SUBROUTINE:  tone                                             *
* Description: Generates the dual tone samples for DTMF         *
*              using offsets T1_OFS, T2_OFS                     *
* Uses:        AR2, AR3                                         *
* Input:       none                                             *
* Output:      none                                             *
*****************************************************************
tone	ld	#0,B			;clear B  ----ROW TONE----
	sub	*AR2(TONES+2),15,B	; (B) = -(1/2)y(n-2), in high accumulator
	ltd	*AR2(TONES+1)		; load (T) with y(n-1) and y(n-1) --> y(n-2)
	mpy	*AR2(TONES),A  		; (A) = coef*y(n-1)
	add	A,B		    	; (B) = coef*y(n-1) - (1/2)y(n-2)
	sth	B,1,*AR2(TONES+1)	; 2*(B) --> y(n-1)
	ld	#0,B			;clear B  ----COLUMN TONE----
	; b	tone1			; test only one oscillator
	sub	*AR3(TONES+2),15,B	; (B) = -(1/2)y(n-2), in high accumulator
	ltd	*AR3(TONES+1)		; load (T) with y(n-1) and y(n-1) --> y(n-2)
	mpy	*AR3(TONES),A  		; (A) = coef*y(n-1)
	add	A,B		    	; (B) = coef*y(n-1) - (1/2)y(n-2)
	sth	B,1,*AR3(TONES+1)	; 2*(B) --> y(n-1)

tone1	add	*AR2(TONES+1),15,B	; add two tone samples
	add	#DAC_OFS,B		; add DAC offset
	sth	B,tra			; write to transmit variable
	ret


*****************************************************************
* SUBROUTINE:  quiet                                            *
* Description: Generates a pause of specified duration          *
*                                                               *
* Uses:        AR2, AR3                                         *
* Input:       TIME_SH                                          *
* Output:      none                                             *
*****************************************************************
quiet	ld	#0,B		; clear B
	add	#DAC_OFS,B	; add DAC offset
	sth	B,tra		; write to transmit variable
	ret



******************************************
* Interrupt Service Routines
******************************************
RINT1_ISR:
	ld	#rcv,DP
	mvmd	DRR1,rcv
	andm	#0fffch,tra
	mvdm	tra,DXR1

	popm	ST1
	popm	ST0
	rete



*****************************************************************
* SUBROUTINE: hwinit                                            *
* Description: Initializes Processor                            *
*                          Serial Port 1                        *
*                          AIC                                  *
* Input: none                                                   *
* Output: none                                                  *
*****************************************************************

hwinit:

;----------- Initialize Processor ---------------------------

	stm	#0ffe0h,PMST	;configure on-chip RAM in OVLY mode
	stm	#02000h,SWWSR	;I/O:    2 wait states
				;memory: 0 wait states
	stm	#0000h,BSCR	;no bank switching


;----------- Initialize Serial Port 1 -----------------------

	stm     #10h, TCR       ; turn off timer
	stm     #0c008h, SPC1   ; reset serial port 1
				;     =0 (b0) : reserved, always zero
				; DBL =0 (b1) : loopback mode disabled
				; FO  =0 (b2) : 16-bit word operation
				; FSM =1 (b3) : frame sync control
				; MCM =0 (b4) : external CLKX
				; TXM =0 (b5) : external FSK
				; XRST=0 (b6) : Xmit reset
				; RRST=0 (b7) : Recv reset
	stm     #0c0c8h, SPC1   ; take serial port 1 out of reset
				; XRST=0 (b6) : Xmit reset
				; RRST=0 (b7) : Recv reset


;----------- Initialize AIC ----------------------------------

	ld      #aic_conf,DP	; reset AIC
	portr   0014h, aic_conf	; (EVM: Port 14h used as target control register
	andm    #7fffh, aic_conf;       B15 of port 14h is AICRST/  )
	portw   aic_conf,0014h

	rpt	#40		; keep low for 2usec
	nop

	ld      #aic_conf,DP	; take AIC out of reset
	portr   0014h,aic_conf
	orm     #8000h,aic_conf
	portw   aic_conf,0014h


	stm     #0080h,IMR	; allow TINT1 interrupt
	stm     #00c8h,IFR	; clear pending serial port 1 and timer interrupts
	rsbx	INTM		; global interrupt enable
	stm     #0h,DXR1	; dummy Xmit for synchronization

	stm     #3h,DXR1	; request secondary Xmit mode to send control word
	idle	1		; wait for TINT1 interrupt
        stm     #0124h,DXR1	; CONVERSION RATE:   sample rate      DXR1 value
	idle	1		; (Reg1)		16 kHz		0112h
				;			 8 kHz		0124h
				;			 4 kHz		0148h         
	stm     #3h,DXR1
	idle	1
	stm     #0212h,DXR1	; PRESCALER:	FCLK = 288 kHz
	idle	1		; (Reg2)
	
	stm     #3h,DXR1
	idle	1
	stm     #0300h,DXR1	; PHASE ADJUSTMENTS: none  
	idle	1		; (Reg3)

	stm     #3h,DXR1 
	idle	1
	stm     #0426h,DXR1	; OUTPUT GAINS:	-8dB (monitor)
	idle	1		; (Reg4)	 0dB (analog input)
				;		-6dB (analog output)
	
	ssbx	INTM		; global interrupt disable
	stm     #0h, DXR1

	ret

;------------ END OF H/W INITIALIZATION SUBROUTINE---------------------


        .end

⌨️ 快捷键说明

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