📄 dtmf_gen.c
字号:
/*****************************************************************************
* DTMF tone generation using PIC16C74
*
* Written for the "Digital Signal Processing Using the PIC16C74" Ap Note
*
* Generates 16 DTMF tones (1-9,0,*,#,A,B,C,D) out PWM port 1
*
* Uses PICTONE.C and ANALOGIO.C modules
*
* D. Mostowfi 4/95
******************************************************************************/
#include <delay14.h>
#include <16c74.h> /* c74 header file */
#include <math.h>
#include "analogio.c" /* analog I/O module */
#include "pictone.c" /* tone generation module */
bits pwm1;
/* Function Prototypes */
void main_isr();
void timer2_isr();
/* 16C74 I/O port bit declarations */
/* global program variables */
char tmr2_cntr; /* timer 2 interrupt counter */
char delay_cntr; /* delay time counter (10ms ticks)*/
/* Tone Coefficients for DTMF Tones */
const DTMF_1[4]={30, 51, 48, 27};
const DTMF_2[4]={30, 51, 56, 19};
const DTMF_3[4]={30, 51, 64, 11};
const DTMF_4[4]={33, 48, 48, 27};
const DTMF_5[4]={33, 48, 56, 19};
const DTMF_6[4]={33, 48, 64, 11};
const DTMF_7[4]={36, 45, 48, 27};
const DTMF_8[4]={36, 45, 56, 19};
const DTMF_9[4]={36, 45, 64, 11};
const DTMF_0[4]={40, 41, 56, 19};
const DTMF_star[4]={40, 41, 48, 27};
const DTMF_pound[4]={40, 41, 64, 11};
const DTMF_A[4]={30, 51, 75, 2};
const DTMF_B[4]={33, 48, 75, 2};
const DTMF_C[4]={36, 45, 75, 2};
const DTMF_D[4]={40, 41, 75, 2};
/*****************************************************************************
* main isr - 16C74 vectors to 0004h (MPC __INT() function) on any interrupt *
* assembly language routine saves W and Status registers then tests flags in
* INTCON to determine source of interrupt. Routine then calls appropriate isr.
* Restores W and status registers when done.
*****************************************************************************/
void __INT(void)
{
if(PIR1.TMR2IF){ /* timer 2 interrupt ? */
PIR1.TMR2IF=0; /* clear interrupt flag */
timer2_isr(); /* and call timer 2 isr */
}
/* Restore W, WImage, and STATUS registers */
#asm
BCF STATUS,RP0 ;Bank 0
MOVF temp_PCLATH, W
MOVWF PCLATH ;PCLATH restored
MOVF temp_WImage, W
MOVWF __WImage ;__WImage restored
MOVF temp_FSR, W
MOVWF FSR ;FSR restored
SWAPF temp_STATUS,W
MOVWF STATUS ;RP0 restored
SWAPF temp_WREG,F
SWAPF temp_WREG,W ;W restored
#endasm
}
/****************************************************************************
* timer 2 isr - provides PWM sample clock generation and millisecond counter
* for tone routine
*****************************************************************************/
void timer2_isr(void)
{
sample_flag=active; /* set sample flag (150us clock) */
PORTB.7=!PORTB.7; /* toggle PORTB.7 at sample rate */
if(tmr2_cntr++==7){ /* check counter */
tmr2_cntr=0; /* reset if max */
ms_cntr++; /* and increment millisecond ticks */
}
}
void main()
{
/* initialize OPTION register */
OPTION=0b11001111;
/* initialize INTCON register (keep GIE inactive!) */
INTCON=0b00000000; /* disable all interrupts */
/* initialize PIE1 and PIE2 registers (periphereal interrupts) */
PIE1=0b00000000; /* disable all interrupts */
PIE2=0b00000000;
/* initialize T1CON and T2CON registers */
T1CON=0b00000000; /* T1 not used */
T2CON=0b00101000; /* T2 postscaler=5 */
/* initialize CCPxCON registers */
CCP1CON=0b00001100; /* set CCP1CON for PWM mode */
CCP2CON=0b00001100; /* set CCP2CON for PWM mode (not used in demo) */
/* initialize SSPCON register */
SSPCON=0b00000000; /* serial port - not used */
/* initialize ADCONx registers */
ADCON0=0b00000000; /* A-D converter */
ADCON1=0b00000010;
/* initialize TRISx register (port pins as inputs or outputs) */
TRISA=0b00001111;
TRISB=0b00000000;
TRISC=0b10000000;
TRISD=0b00001111;
TRISE=0b00000000;
/* clear watchdog timer (not used) */
CLRWDT();
/* initialize program variables */
tmr2_cntr=0;
/* initialize program bit variables */
FLAGS=0b00000000;
/* intialize output port pins (display LED's on demo board) */
PORTB=0;
/* enable interrupts... */
INTCON.ADIE=1; /* Periphereal interrupt enable */
INTCON.GIE=1; /* global interrupt enable */
init_PWM(0x3e); /* initialize PWM port */
PORTB=0x01; /* write a 1 to PORTB */
a1=DTMF_1[0]; /* and send a DTMF "1" */
b1=DTMF_1[1];
a2=DTMF_1[2];
b2=DTMF_1[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x02; /* write a 2 to PORT B */
a1=DTMF_2[0]; /* and send a DTMF "2" */
b1=DTMF_2[1];
a2=DTMF_2[2];
b2=DTMF_2[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x03; /* write a 3 to PORTB */
a1=DTMF_3[0]; /* and send a DTMF "3" */
b1=DTMF_3[1];
a2=DTMF_3[2];
b2=DTMF_3[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x04; /* write a 4 to PORTB */
a1=DTMF_4[0]; /* and send a DTMF "4" */
b1=DTMF_4[1];
a2=DTMF_4[2];
b2=DTMF_4[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x05; /* write a 5 to PORTB */
a1=DTMF_5[0]; /* and send a DTMF "5" */
b1=DTMF_5[1];
a2=DTMF_5[2];
b2=DTMF_5[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x06; /* write a 6 to PORTB */
a1=DTMF_6[0]; /* and send a DTMF "6" */
b1=DTMF_6[1];
a2=DTMF_6[2];
b2=DTMF_6[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x07; /* write a 7 to PORTB */
a1=DTMF_7[0]; /* and send a DTMF "7" */
b1=DTMF_7[1];
a2=DTMF_7[2];
b2=DTMF_7[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x08; /* write a 8 to PORTB */
a1=DTMF_8[0]; /* and send a DTMF "8" */
b1=DTMF_8[1];
a2=DTMF_8[2];
b2=DTMF_8[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x09; /* write a 9 to PORTB */
a1=DTMF_9[0]; /* and send a DTMF "9" */
b1=DTMF_9[1];
a2=DTMF_9[2];
b2=DTMF_9[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x0; /* write a 0 to PORTB */
a1=DTMF_0[0]; /* and send a DTMF "0" */
b1=DTMF_0[1];
a2=DTMF_0[2];
b2=DTMF_0[3];
duration=150;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x0e; /* write a 0x0e to PORTB */
a1=DTMF_star[0]; /* and send a DTMF "*" */
b1=DTMF_star[1];
a2=DTMF_star[2];
b2=DTMF_star[3];
duration=250;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x0f; /* write a 0x0f to PORTB */
a1=DTMF_pound[0]; /* and send a DTMF "#" */
b1=DTMF_pound[1];
a2=DTMF_pound[2];
b2=DTMF_pound[3];
duration=250;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x0a; /* write a 0x0a to PORTB */
a1=DTMF_A[0]; /* and send a DTMF "A" */
b1=DTMF_A[1];
a2=DTMF_A[2];
b2=DTMF_A[3];
duration=250;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x0b; /* write a 0x0b to PORTB */
a1=DTMF_B[0]; /* and send a DTMF "B" */
b1=DTMF_B[1];
a2=DTMF_B[2];
b2=DTMF_B[3];
duration=250;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x0c; /* write a 0x0c to PORTB */
a1=DTMF_C[0]; /* and send a DTMF "C" */
b1=DTMF_C[1];
a2=DTMF_C[2];
b2=DTMF_C[3];
duration=250;
tone();
Delay_Ms_20MHz(200); /* delay 100ms (200/2 using MPC delays) */
PORTB=0x0d; /* write a 0x0d to PORTB */
a1=DTMF_D[0]; /* and send a DTMF "D" */
b1=DTMF_D[1];
a2=DTMF_D[2];
b2=DTMF_D[3];
duration=250;
tone();
PORTB=0; /* write a 0 to PORTB */
while(1){} /* done (loop) */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -