📄 dtmf_gen.lst
字号:
;
; 8x8 signed multiply routine
; called from PICTONE.C module (assembly language routine)
;
.MACRO mult_core bit
btfss multplr,bit
goto \no_add
movf multcnd,W
addwf result_h,F
\no_add:
rrf result_h
rrf result_l
MPC "C" COMPILER BC.193 22-Aug-1995 PAGE 6
.ENDM
_8x8smul:
007B 0832 movf multcnd,W ; get multiplicand
007C 0633 xorwf multplr,W ; and xor with multiplier
007D 00B6 movwf sign ; and save sign of result
007E 1FB2 btfss multcnd,7 ; check sign bit of multiplicand
007F 2882 goto chk_multplr ; go and check multipier if positive
0080 09B2 comf multcnd ; negate if negative
0081 0AB2 incf multcnd ;
chk_multplr:
0082 1FB3 btfss multplr,7 ; check sign bit of multiplier
0083 2886 goto multiply ; go to multiply if positive
0084 09B3 comf multplr ; negate if negative
0085 0AB3 incf multplr ;
multiply:
0086 0832 movf multcnd,W ; set up multiply registers
0087 1003 bcf STATUS,C ;
0088 01B4 clrf result_h ;
0089 01B5 clrf result_l ;
mult_core 0 ; and do multiply core 8 times
0114 1C33 2800 32
00088C 07B4 0CB4
008F 0CB5
mult_core 1 ;
0120 1CB3 2800 32
000892 07B4 0CB4
0095 0CB5
mult_core 2 ;
012C 1D33 2800 32
000898 07B4 0CB4
009B 0CB5
mult_core 3 ;
0138 1DB3 2800 32
00089E 07B4 0CB4
00A1 0CB5
mult_core 4 ;
0144 1E33 2800 32
0008A4 07B4 0CB4
00A7 0CB5
mult_core 5 ;
0150 1EB3 2800 32
0008AA 07B4 0CB4
00AD 0CB5
mult_core 6 ;
015C 1F33 2800 32
0008B0 07B4 0CB4
00B3 0CB5
mult_core 7 ;
0168 1FB3 2800 32
0008B6 07B4 0CB4
00B9 0CB5
MPC "C" COMPILER BC.193 22-Aug-1995 PAGE 7
set_sign:
00BA 1FB6 btfss sign,7 ; test sign to see if result negative
00BB 3400 retlw 0 ; done if not! (clear W)
00BC 09B5 comf result_l ; negate result if sign set
00BD 0AB5 incf result_l ;
00BE 1903 btfsc STATUS,Z ;
00BF 03B4 decf result_h ;
00C0 09B4 comf result_h ;
00C1 3400 retlw 0 ; done (clear W)
;
; Scaling Routine (used after a multiply to scale 16 bit result)
; Operates on result_h and result_l - final result is in result_l
; routine divides by 32 to restore Q7 result of 2*b*y(n-1) in tone
; generation algorithm
;
scale_16:
00C2 1FB6 btfss sign,7 ; test if negative (sign set from mult)
00C3 28C9 goto start_shift ; go to start shift if pos.
00C4 09B5 comf result_l ; negate first if neg.
00C5 0AB5 incf result_l ;
00C6 1903 btfsc STATUS,Z ;
00C7 03B4 decf result_h ;
00C8 09B4 comf result_h ;
start_shift:
00C9 1003 bcf STATUS,C ; clear status
00CA 0CB4 rrf result_h ; and shift result left 5x (/32)
00CB 0CB5 rrf result_l ;
00CC 0CB4 rrf result_h ;
00CD 0CB5 rrf result_l ;
00CE 0CB4 rrf result_h ;
00CF 0CB5 rrf result_l ;
00D0 0CB4 rrf result_h ;
00D1 0CB5 rrf result_l ;
00D2 0CB4 rrf result_h ;
00D3 0CB5 rrf result_l ;
00D4 1FB6 btfss sign,7 ; test if result negative
00D5 28DB goto scale_done ; done if not negative
00D6 09B5 comf result_l ; negate result if negative
00D7 0AB5 incf result_l ;
00D8 1903 btfsc STATUS,Z ;
00D9 03B4 decf result_h ;
00DA 09B4 comf result_h ;
scale_done: ;
00DB 3400 retlw 0 ; done (clear W)
#endasm
MPC "C" COMPILER BC.193 22-Aug-1995 PAGE 8
#define sample_flag FLAGS.1 /* sample flag */
0004 #define no_tone2 FLAGS,2 /* no tone 2 flag */
0037 extern char ms_cntr; /* millisecond counter for tone loop */
0038 char a1; /* first tone (low-group) coeeficient 1 */
0039 char a2; /* first tone (low-group) coefficient 2 */
003A char b1; /* second tone (high group) coefficient 1 */
003B char b2; /* second tone (high group) coefficient 2 */
003C char duration; /* tone duration */
003D char y1; /* output sample y1(n) for tone 1 */
003E char y2; /* output sample y2(n) for tone 2 */
/******************************************************************************
* Tone function - generates single or dual tone signals out PWM port 1.
*
* usage:
* - write coefficients for tone 1 to a1 and b1
* - write coefficents for tone 2 to a2 and b2 (0 if no tone 2)
* - write duration of tone in milliseconds to duration
* - call tone() function
*******************************************************************************/
void tone(void)
{
003F char y1_1; /* y1(n-1) */
0040 char y1_2; /* y1(n-2) */
0041 char y2_1; /* y2(n-1) */
0042 char y2_2; /* y2(n-2) */
00DC 1283 BCF STATUS,RP0 PIR1.TMR2IF=0; /* clear timer 2 interrupt flag */
00DD 108C BCF PIR1,1
00DE 1683 BSF STATUS,RP0 PIE1.TMR2IE=1; /* and enable timer 2 interrupt */
00DF 148C BSF PIR1,1
00E0 1283 BCF STATUS,RP0 ms_cntr=0; /* clear ms counter */
00E1 01B7 CLRF 37
00E2 1283 BCF STATUS,RP0 STATUS.RP0=0; /* set proper bank!!! */
#asm
00E3 01BD clrf y1 ; clear output byte and taps
00E4 01BE clrf y2 ;
00E5 01BF clrf y1_1 ;
00E6 01C0 clrf y1_2 ;
00E7 01C1 clrf y2_1 ;
00E8 01C2 clrf y2_2 ;
00E9 112C bcf no_tone2 ; clear no tone 2 flag
00EA 01B7 clrf ms_cntr ; clear millisecond counter
first_sample:
00EB 0838 movf a1,W ; first iteration
00EC 00BD movwf y1 ; y1(n)=a1
00ED 00BF movwf y1_1 ;
MPC "C" COMPILER BC.193 22-Aug-1995 PAGE 9
00EE 3000 movlw 0x00 ;
00EF 0439 iorwf a2,W ;
00F0 1903 btfsc STATUS,Z ; generate second tone (a2 !=0) ?
00F1 152C bsf no_tone2 ;
00F2 0839 movf a2,W ; y2(n)=a2
00F3 00BE movwf y2 ;
00F4 00C1 movwf y2_1 ;
00F5 083E movf y2,W ;
00F6 07BD addwf y1,F ; y1(n)=y1(n)+y2(n) (sum two tone outputs)
tone_loop:
00F7 0837 movf ms_cntr,W ; test to see if ms=duration (done?)
00F8 023C subwf duration,W ;
00F9 1903 btfsc STATUS,Z ;
00FA 2921 goto tone_done ;
wait_PWM:
00FB 1CAC btfss FLAGS,1 ; test sample flag (sample period elapsed?)
00FC 28FB goto wait_PWM ; loop if not
00FD 10AC bcf FLAGS,1 ; if set, clear sample flag
#endasm
00FE 083D MOVF 3D,W write_PWM((char)y1,0); /* write y1 to PWM port */
00FF 0084 MOVWF FSR
0100 3000 MOVLW 00h
0101 203D CALL 003Dh
#asm
next_sample:
0102 083A movf b1,W ; y1(n)=b1*y1(n-1)-y1(n-2)
0103 00B2 movwf multcnd ;
0104 083F movf y1_1,W ;
0105 00B3 movwf multplr ;
0106 207B call _8x8smul ;
0107 20C2 call scale_16 ;
0108 0840 movf y1_2,W ;
0109 0235 subwf result_l,W ;
010A 00BD movwf y1 ;
010B 083F movf y1_1,W ; y1(n-2)=y1(n-1)
010C 00C0 movwf y1_2 ;
010D 083D movf y1,W ; y1(n-1)=y1(n)
010E 00BF movwf y1_1 ;
010F 192C btfsc no_tone2 ;
0110 28F7 goto tone_loop ;
0111 083B movf b2,W ; y2(n)=b2*y2(n-1)-y2(n-2)
0112 00B2 movwf multcnd ;
0113 0841 movf y2_1,W ;
0114 00B3 movwf multplr ;
0115 207B call _8x8smul ;
0116 20C2 call scale_16 ;
0117 0842 movf y2_2,W ;
0118 0235 subwf result_l,W ;
0119 00BE movwf y2 ;
011A 0841 movf y2_1,W ; y2(n-2)=y2(n-1)
MPC "C" COMPILER BC.193 22-Aug-1995 PAGE 10
011B 00C2 movwf y2_2 ;
011C 083E movf y2,W ; y2(n-1)=y2(n)
011D 00C1 movwf y2_1 ;
011E 083E movf y2,W ;
011F 07BD addwf y1,F ; y1(n)=y1(n)+y2(n) (sum two tone outputs)
0120 28F7 goto tone_loop ; go and calculate next sample
tone_done:
#endasm
0121 1283 BCF STATUS,RP0 CCP1CON.5=0; /* reset PWM outputs to mid value */
0122 1297 BCF CCP1CON,5
0123 1217 BCF CCP1CON,4 CCP1CON.4=0;
0124 129D BCF CCP2CON,5 CCP2CON.5=0;
0125 121D BCF CCP2CON,4 CCP2CON.4=0;
0126 0196 CLRF CCPR1H CCPR1H=0x00;
0127 3020 MOVLW 20h CCPR1L=0x20;
0128 0095 MOVWF CCPR1L
0129 019C CLRF CCPR2H CCPR2H=0x00;
012A 009B MOVWF CCPR2L CCPR2L=0x20;
012B 1683 BSF STATUS,RP0 PIE1.TMR2IE=0; /* disable timer 2 interrupts */
012C 108C BCF PIR1,1
012D 1283 BCF STATUS,RP0 PIR1.TMR2IF=0; /* and clear timer 2 interrupt flag */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -