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

📄 decoder.asm

📁 DTMF的ASM解码程序(效率非常高)
💻 ASM
字号:
; decoder.asm
; Decoding a DTMF tone with Goertzel Algorithm

; specify module and ROM routine definition files
$include (maxq20ms10xf.inc)  
$include (utilityrom.inc)

; MCNT control bits
MSIG     equ 000h    ; signed operation
MUNS     equ 001h    ; unsigned operation
MACC     equ 002h    ; accumulate
MNEG     equ 004h    ; negate result
M1OP     equ 008h    ; one operand mode
MSQU     equ 010h    ; sqr mode
MCLD     equ 020h    ; clear data
MMCW     equ 040h    ; dont update MC

; coefficient for the Goertzel algorithm
a1       equ 001A5h  ; 1.65 * 2^8; a1 value for f=770Hz, Fs=8000Hz
D1       equ 00h     ; address of D1
D2       equ D1+1    ; address of D2
result   equ 00Fh    ; pointer to accumulated power result 
loop_cnt equ 205

    org 000h
Main:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;   System Initialization
;   1. initialize A[0] as the active accumulator
;   2. set all data pointer to word mode
;   3. set up DP[1] to point to input samples
;      (input samples are pre-downloaded onto program memory.
;      If samples are available elsewhere, e.g. from other 
;      peripherals, modify to point to relevant input source)
;   4. set up result pointer and loop counter
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    move APC, #00h           ; set A[0] as the active accumulator
    move DPC, #1Ch           ; set all data pointer to word mode
  
    move ACC, #x             ; map code space to data space 
    add  #8000h
    move DP[1], ACC          ; DP[1] -> input samples
    move A[1], #result       ; A[1] -> power results
    move LC[0], #loop_cnt    ; LC[0] -> number of samples


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;   Goertzel Algorithm Decoder Routine
;        D0=X = ai*D1-D2
;        D2=D1, D1=D0
;
;   Input:
;     DP[1] -> sample input
;     LC[0] -> loop_cnt
;   Output:
;     DP[1] updated to point to next sample input
;
;   Implementation:
;     1. initialize the MAC unit
;     2. get input sample
;     3. carry out the Goertzel Algorithm
;     4. calculate power information
;        This step does not need to be perform on every sample
;        It is done here for demonstration purpose
;        
;     Note: the input samples are keep to 8 bits value so that
;        all MAC operation can be kept to 16x16 operation.
;        both a1 and D2 are scaled accordingly to facilitate 
;        MAC operation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DECODER_LOOP:              

    move    MCNT, #(MSIG+MACC+MCLD); initialized MAC unit
    move MA, #100h		     ; MA = 2^8

    move DP[1], DP[1]        ; activate DP[1]
    lcall   UROM_moveDP1inc  ; get input samples, DP[0]->next input
    move MB, GR              ; MB = x, MC=x

    move DP[0], #D1          ; DP[0]-> D1 
    move MA, #a1		   	 ; MA = a1
    move MB, @DP[0]++  		 ; MB = D1, MC=x+a1*D1, DP[0]->D2
    move MA, #0FF00h		 ; MA = -2^8
    move MB, @DP[0]--		 ; MB = D2, MC=x+a1*D1-D2, DP[0]->D1
 
    move ACC, @DP[0]++       ; ACC = D1, DP[0]->D2
    move @DP[0], ACC         ; D2 = ACC = D1

    move GR, MC0             ; retrieve D0 from MC
    move GRL, MC1
    move @--DP[0], GRS       ; D1=D0, DP[0]->D1
    call CALC_P              ; Optional, can call this routine after 
                             ; the loop

    djnz  LC[0], DECODER_LOOP
    nop


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;   Calculate power of intender frequency in the sample
;     D1^2+D2^2-a1*D1*D2
;
;   Input:
;        DP[0] -> D1
;        A[1]  -> address of last power value
;   Output:
;        A[1] updated to point to next sample input
;
;   Implementation:
;        1. initialize the MAC unit
;        2. power calculation
;        3. store the resulting power value as a 4 byte value
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CALC_P:                      ; calculate power
 
    move MCNT,  #(MSIG+MCLD) ; initialized MAC unit
    
    move MA, #a1		     ; MA = a1
    move MB, @DP[0]++  		 ; MB = D1, MC=a1*D1, DP[0]->D2
    nop                      ; wait for MAC result

    move GR, MC0             ; retrieve a1*D1 from MC
    move GRL, MC1

    move MCNT, #(MSIG+MNEG)  ; negate MAC result
    move MA, GRS             ; MA = a1*D1
    move MB, @DP[0]--		 ; MB = D2, MC=-a1*D1*D2, DP[0]->D1

    move MCNT,  #(MSIG+MACC+MSQU); change to square and accumulate mode
    move MA, @DP[0]++        ; MA = D1, MC = D1^2-a1*D1*D2, DP[0]->D2
    move MA, @DP[0]          ; MA = D2, MC = D1^2+D2^2-a1*D1*D2

    move DP[0], A[1]         ; DP[0] -> result
    move GR, MC1             ; store power as 4 bytes value in big-endian format
    move @++DP[0], GRS
    move GR, MC0
    move @++DP[0], GRS
    move A[1], DP[0]         ; update A[1] to last result pointer
    ret
 
    org 100h
    ; input sample - 770 Hz sine wave
x:
 dw  000000h, 000039h, 00005eh, 000061h, 000042h, 00000ch, 00ffd1h, 00ffa7h, 00ff9dh, 00ffb6h,
 dw  00ffe9h, 000024h, 000053h, 000064h, 000052h, 000023h, 00ffe7h, 00ffb4h, 00ff9dh, 00ffa8h,
 dw  00ffd3h, 00000dh, 000043h, 000061h, 00005dh, 000038h, 00fffeh, 00ffc6h, 00ffa2h, 00ff9fh,
 dw  00ffbfh, 00fff6h, 000030h, 000059h, 000063h, 000049h, 000016h, 00ffdah, 00ffach, 00ff9ch,
 dw  00ffafh, 00ffdfh, 00001ah, 00004dh, 000064h, 000057h, 00002ch, 00fff1h, 00ffbch, 00ff9eh,
 dw  00ffa4h, 00ffcah, 000003h, 00003bh, 00005fh, 000060h, 000040h, 000009h, 00ffceh, 00ffa6h,
 dw  00ff9dh, 00ffb8h, 00ffech, 000027h, 000054h, 000064h, 000050h, 000020h, 00ffe4h, 00ffb2h,
 dw  00ff9ch, 00ffaah, 00ffd5h, 000010h, 000046h, 000062h, 00005ch, 000035h, 00fffbh, 00ffc3h,
 dw  00ffa1h, 00ffa0h, 00ffc1h, 00fff9h, 000033h, 00005bh, 000063h, 000047h, 000013h, 00ffd8h,
 dw  00ffabh, 00ff9ch, 00ffb1h, 00ffe2h, 00001dh, 00004fh, 000064h, 000056h, 000029h, 00ffeeh,
 dw  00ffb9h, 00ff9eh, 00ffa5h, 00ffcch, 000006h, 00003eh, 000060h, 00005fh, 00003dh, 000005h,
 dw  00ffcch, 00ffa5h, 00ff9eh, 00ffbah, 00ffefh, 00002ah, 000056h, 000064h, 00004eh, 00001dh,
 dw  00ffe1h, 00ffb1h, 00ff9ch, 00ffabh, 00ffd8h, 000014h, 000048h, 000063h, 00005ah, 000032h,
 dw  00fff8h, 00ffc1h, 00ffa0h, 00ffa1h, 00ffc4h, 00fffch, 000036h, 00005ch, 000062h, 000045h,
 dw  000010h, 00ffd5h, 00ffa9h, 00ff9ch, 00ffb3h, 00ffe5h, 000020h, 000050h, 000064h, 000054h,
 dw  000026h, 00ffebh, 00ffb7h, 00ff9dh, 00ffa6h, 00ffcfh, 000009h, 000040h, 000060h, 00005eh,
 dw  00003bh, 000002h, 00ffc9h, 00ffa3h, 00ff9eh, 00ffbch, 00fff2h, 00002dh, 000058h, 000063h,
 dw  00004ch, 00001ah, 00ffdeh, 00ffafh, 00ff9ch, 00ffadh, 00ffdbh, 000017h, 00004ah, 000063h,
 dw  000059h, 00002fh, 00fff5h, 00ffbeh, 00ff9fh, 00ffa2h, 00ffc6h, 00ffffh, 000038h, 00005dh,
 dw  000061h, 000043h, 00000dh, 00ffd2h, 00ffa8h, 00ff9dh, 00ffb5h, 00ffe8h, 000023h, 000052h,
 dw  000064h, 000052h, 000023h, 00ffe8h, 00ffb5h,


End

⌨️ 快捷键说明

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