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

📄 dtmf_gen.c

📁 pic16c6x和pic16c7xxx都可以通用
💻 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 + -