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

📄 dtmf_gen.lst

📁 pic16c6x和pic16c7xxx都可以通用
💻 LST
📖 第 1 页 / 共 5 页
字号:

                        ;
                        ; 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 + -