📄 pictone.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 + -