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

📄 pictone.c

📁 pic16c6x和pic16c7xxx都可以通用
💻 C
字号:
/*****************************************************************************
* Tone Generation Module
* 
* Written for "Digital Signal Processing with the PIC16C74" Application Note.
*
* This module contains a C callable module that generates single or dual 
* tones using a difference equation method:
*
* y1(n)=a1*x(n-1)+b1*y1(n-1)-y1(n-2)
* y2(n)=a2*x(n-1)+b2*y2(n-1)-y2(n-2)
*
* The routine is written in assembly language and uses the optimized signed 
* 8x8 multiply routine and scaling routine in the file 8BITMATH.C.
*
* D. Mostowfi 2/95
*****************************************************************************/
#include "8bitmath.c"  /* 8 bit signed math routines */

#define sample_flag FLAGS.1     /* sample flag */
#define no_tone2 FLAGS,2        /* no tone 2 flag */

extern char ms_cntr;            /* millisecond counter for tone loop */

char a1;                        /* first tone (low-group) coeeficient 1 */
char a2;                        /* first tone (low-group) coefficient 2 */
char b1;                        /* second tone (high group) coefficient 1 */
char b2;                        /* second tone (high group) coefficient 2 */
char duration;                  /* tone duration */

char y1;                        /* output sample y1(n) for tone 1 */
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)
{

char y1_1;                      /* y1(n-1) */
char y1_2;                      /* y1(n-2) */
char y2_1;                      /* y2(n-1) */
char y2_2;                      /* y2(n-2) */

    PIR1.TMR2IF=0;              /* clear timer 2 interrupt flag */
    PIE1.TMR2IE=1;              /* and enable timer 2 interrupt */
    ms_cntr=0;                  /* clear ms counter */
    STATUS.RP0=0;               /* set proper bank!!! */

#asm                                               
        clrf    y1              ; clear output byte and taps
        clrf    y2              ;
        clrf    y1_1            ;
        clrf    y1_2            ;
        clrf    y2_1            ;
        clrf    y2_2            ;

        bcf     no_tone2        ; clear no tone 2 flag
        clrf    ms_cntr         ; clear millisecond counter

first_sample:
        movf    a1,W            ; first iteration
        movwf   y1              ; y1(n)=a1
        movwf   y1_1            ;
        movlw   0x00            ;
        iorwf   a2,W            ;
        btfsc   STATUS,Z        ; generate second tone (a2 !=0) ?
        bsf     no_tone2        ;
        movf    a2,W            ; y2(n)=a2
        movwf   y2              ;
        movwf   y2_1            ;
        movf    y2,W            ;
        addwf   y1,F            ; y1(n)=y1(n)+y2(n) (sum two tone outputs)
                                                
tone_loop:
        movf    ms_cntr,W       ; test to see if ms=duration (done?)
        subwf   duration,W      ;
        btfsc   STATUS,Z        ;
        goto    tone_done       ;

wait_PWM:       
        btfss   FLAGS,1         ; test sample flag (sample period elapsed?)
        goto    wait_PWM        ; loop if not

        bcf     FLAGS,1         ; if set, clear sample flag

#endasm
    write_PWM((char)y1,0);      /* write y1 to PWM port */
#asm

next_sample:
        movf    b1,W            ; y1(n)=b1*y1(n-1)-y1(n-2)
        movwf   multcnd         ;
        movf    y1_1,W          ;
        movwf   multplr         ;
        call    _8x8smul        ;
        call    scale_16        ;
        movf    y1_2,W          ;
        subwf   result_l,W      ;
        movwf   y1              ;
        movf    y1_1,W          ; y1(n-2)=y1(n-1)
        movwf   y1_2            ;
        movf    y1,W            ; y1(n-1)=y1(n)
        movwf   y1_1            ;
        btfsc   no_tone2        ;
        goto    tone_loop       ;
        movf    b2,W            ; y2(n)=b2*y2(n-1)-y2(n-2)
        movwf   multcnd         ;
        movf    y2_1,W          ;
        movwf   multplr         ;
        call    _8x8smul        ;
        call    scale_16        ;
        movf    y2_2,W          ;
        subwf   result_l,W      ;
        movwf   y2              ;
        movf    y2_1,W          ; y2(n-2)=y2(n-1)
        movwf   y2_2            ;
        movf    y2,W            ; y2(n-1)=y2(n)
        movwf   y2_1            ;

        movf    y2,W            ;  
        addwf   y1,F            ; y1(n)=y1(n)+y2(n) (sum two tone outputs)

        goto    tone_loop       ; go and calculate next sample

tone_done:

#endasm

    CCP1CON.5=0;                /* reset PWM outputs to mid value */
    CCP1CON.4=0;
    CCP2CON.5=0;
    CCP2CON.4=0;
    CCPR1H=0x00;
    CCPR1L=0x20;
    CCPR2H=0x00;
    CCPR2L=0x20;
    
    PIE1.TMR2IE=0;              /* disable timer 2 interrupts */
    PIR1.TMR2IF=0;              /* and clear timer 2 interrupt flag */

}

⌨️ 快捷键说明

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