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

📄 dtmf.c

📁 基于AVR Mega8的DTMF编码程序
💻 C
字号:
/********************************************************
		 键盘布置图:
		             1 2 3 A--PB4
		             4 5 6 B--PB5
					 7 8 9 C--PB6
					 * 0 # D--PB7
					 | | | |
					 P P P P
					 B B B B
					 0 1 2 3
		 喇叭接线图:PD5(OC1A)--1K电阻--喇叭			 
********************************************************/ 
#include <ioM8v.h>
#include <macros.h>
#define  Xtal       8000000          // 系统时钟频率
#define  prescaler  1                // T1预分频系数
#define  N_samples  128              // 在查找表中的样本数
#define  Fck        Xtal/prescaler   // T1工作频率
#define  delaycyc   2               // 读取port C口延时循环数
#pragma interrupt_handler ISR_T1_Overflow:9
/*************************** 正弦表 *****************************
       样本表: 一个周期分成128个点,每点按7位进行量化
****************************************************************/
flash unsigned char auc_SinParam [128] = {
64,67,
70,73,
76,79,
82,85,
88,91,
94,96,
99,102,
104,106,
109,111,
113,115,
117,118,
120,121,
123,124,
125,126,
126,127,
127,127,
127,127,
127,127,
126,126,
125,124,
123,121,
120,118,
117,115,
113,111,
109,106,
104,102,
99,96,
94,91,
88,85,
82,79,
76,73,
70,67,
64,60,
57,54,
51,48,
45,42,
39,36,
33,31,
28,25,
23,21,
18,16,
14,12,
10,9,
7,6,
4,3,
2,1,
1,0,
0,0,
0,0,
0,0,
1,1,
2,3,
4,6,
7,9,
10,12,
14,16,
18,21,
23,25,
28,31,
33,36,
39,42,
45,48,
51,54,
57,60};

//***************************  x_SW  *************************
//   x_SW 表(8倍): x_SW = ROUND(8*N_samples*f*510/Fck)
//************************************************************
const unsigned char tab_sw[32]={
79,46,//1
87,46,//2
96,46,//3

79,50,//4
87,50,//5
96,50,//6

79,56,//7
87,56,//8
96,56,//9

79,61,//*
87,61,//0
96,61,//#

107,46,//a
107,50,//b
107,56,//c
107,61//d
};
//高频(列)
//1209hz  ---> x_SW = 79
//1336hz  ---> x_SW = 87
//1477hz  ---> x_SW = 96
//1633hz  ---> x_SW = 107

const unsigned char auc_frequencyH [4] = {
107,96,
87,79};
//const unsigned char auc_frequencyH [4] = {
//106,100,
//94,89};

//低频(行)
//697hz  ---> x_SW = 46
//770hz  ---> x_SW = 50
//852hz  ---> x_SW = 56
//941hz  ---> x_SW = 61

const unsigned char auc_frequencyL [4] = {
61,56,
50,46};

/*
//高频(列)
//1209hz  ---> x_SW = 79
//1336hz  ---> x_SW = 87
//1477hz  ---> x_SW = 96
//1633hz  ---> x_SW = 107

const unsigned char auc_frequencyH [4] = {
106,100,
94,89};

//低频(行)
//697hz  ---> x_SW = 46
//770hz  ---> x_SW = 50
//852hz  ---> x_SW = 56
//941hz  ---> x_SW = 61

const unsigned char auc_frequencyL [4] = {
60,57,
56,52};///55
*/

//**************************  全局变量 ****************************
unsigned char x_SWa = 0x00;               // 高频信号脉冲宽度
unsigned char x_SWb = 0x00;               // 低频信号脉冲宽度
unsigned int  X_LUTaExt = 0;           	  
unsigned int  X_LUTbExt = 0;              
unsigned int  X_LUTa;                   
unsigned int  X_LUTb;                     

unsigned char num=0;
unsigned int  cnt=0;

/*****************************************************************
                    定时器溢出中断服务程序
******************************************************************/
void ISR_T1_Overflow (void)
{ 
  if(cnt>0) {cnt--;}
  x_SWa = tab_sw[num+num];//取高音脉冲宽度并结束循环
  x_SWb = tab_sw[num+num+1];//取低音脉冲宽度并结束循环  
  
  X_LUTaExt += x_SWa;       
  X_LUTbExt += x_SWb;
            // 数据规格化
  X_LUTa  =  (char)(((X_LUTaExt+4) >> 3)&(0x007F)); 
  X_LUTb  =  (char)(((X_LUTbExt+4) >> 3)&(0x007F));
           // 计算 PWM 值: 高频值 + 3/4 低频值
  OCR1A = (auc_SinParam[X_LUTa] + (auc_SinParam[X_LUTb]-(auc_SinParam[X_LUTb]>>2)));
  //OCR1A = auc_SinParam[X_LUTa];
  if(cnt==0) {OCR1A =0;PORTB&=0xfe;_CLI();}
}

/***********************************************************
                        初始化
***********************************************************/
void init (void)
{
  MCUCR=0x00;
  TIMSK  = 0x04;                     // T1 溢出中断使能
  TCCR1A = (1<<COM1A1)+(1<<WGM10);   // 不翻转、8位PWM
  TCCR1B = (1<<CS10);                // 预分频系数为1、即CLK/1
  DDRB   = (1 <<PB1);               // PD5 (OC1A)用作输出
  _SEI();                     	     // 全局中断使能
}

/*********************************************************************
      为从PORT C口读取稳定的按键数据,所必须的延时程序(消抖延时)
*********************************************************************/
void Delay (void)
{
  int i;
  for (i = 0; i < delaycyc; i++) {_NOP();_NOP();_NOP();}
   
}
//////////////////////
void Delay_05s(void)
{ unsigned int  sec0=0;
  unsigned char sec1=0;
  for(sec1=0;sec1<125;sec1++)
  {
      for(sec0=0;sec0<5000;sec0++)
         {;}
  }
}
//////////////////////
void dile(void)
{
   num=0;start_PWM();//1
   Delay_05s();
   num=2;start_PWM();//3
   Delay_05s();   
   num=6;start_PWM();//7
   Delay_05s();  
   num=4;start_PWM();//5
   Delay_05s();  
   num=10;start_PWM();//0
   Delay_05s();  
   num=2;start_PWM();//3
   Delay_05s(); 
   num=2;start_PWM();//3
   Delay_05s(); 
   num=5;start_PWM();//6
   Delay_05s(); 
   num=1;start_PWM();//2
   Delay_05s(); 
   num=1;start_PWM();//2
   Delay_05s(); 
   num=2;start_PWM();//3
   Delay_05s(); 
   //num=4;start_PWM();
   //Delay_05s();  
}
//////////////////////
void start_PWM(void)
{
	   //cnt=60000;
	   cnt=1000;
       x_SWa = 0x00;               // 高频信号脉冲宽度
       x_SWb = 0x00;               // 低频信号脉冲宽度
       X_LUTaExt = 0;           	  
       X_LUTbExt = 0;
	   _SEI(); 
}
/********************************************************************
                            主程序
      从PORT C口读取按键数据(如:SL?AVR实验板) ,来确定产生哪个
      高频(列)和低频(行)信号的混合信号,并且修正 x_SWa 和 x_SWb。
                   行  -> PINC 高四位
                   列  -> PINC 低四位
*********************************************************************/

void main (void)
{
  unsigned char uc_Input,keycode,keybuff,keycnt,keytemp,is_key=0;
  unsigned char uc_Counter = 0;
  init();
  
  DDRD  = 0x00;
  PORTD = 0xFF;
  DDRC  = 0xff;
  while(1)
  {
    if((PIND&0X01)==0X00)
	   {
	      Delay();
		  Delay();
		  Delay();
		  Delay();
		  Delay();
		  if((PIND&0X01)==0X00)
		     {
	           Delay();
		       Delay();
		       Delay();
		       Delay();
		       Delay();
			     if((PIND&0X01)==0X00)
				    {
					   while((PIND&0X01)==0X00)
					      {;}
					   PORTC=0Xff;
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   dile();
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   Delay_05s(); 
					   PORTC=0X00;
					}
			 }
	   }
  }
  
  
  
  for(;;){ 
     // 高四位 - 行
    DDRD  = 0x0F;           // 高四位输入、低四位输出
    PORTD = 0xF0;           // 高四位打开上位、低四位输出低电平
    //uc_Counter = 0;
    Delay();                          // 延时等待 Port C 电平稳定
	keytemp=0;
    uc_Input = PIND;                  // 读取 Port C
	uc_Input &=0xf0;
	if(uc_Input!=0xf0)
	  {
	    keytemp=uc_Input;
	  }
	  
	// 低四位 - 列
    DDRD  = 0xF0;          // 高四位输出、低四位输入
    PORTD = 0x0F;          // 高四位输出低电平、低四位打开上拉
    //uc_Counter = 0;
    Delay();               // 延时等待 Port C 电平稳定
    uc_Input = PIND;                  // 读取 Port C
	uc_Input &=0x0f;
	if(uc_Input!=0x0f)
	  {
	    keytemp|=uc_Input;
	  }
    
	if((keytemp==keybuff)&&(keytemp!=0xff))
	  {
	     if(++keycnt>20)
		    {
			   //have key
			   keycode=keybuff; 
			   is_key=1;
			   keycnt=0;
			}
	  }
	else
	  {
	    keycnt=0;
		is_key=0;
	  }
	keybuff=keytemp;
    
	if((is_key==1)&&(cnt==0)){
	   switch(keycode){
	         case 0b11101110 : num=0;start_PWM(); break;
	         case 0b11101101 : num=1;start_PWM(); break;
			 case 0b11101011 : num=2;start_PWM(); break;
			 
			 case 0b11011110 : num=3;start_PWM(); break;
			 case 0b11011101 : num=4;start_PWM(); break;
			 case 0b11011011 : num=5;start_PWM(); break;
			 
			 case 0b10111110 : num=6;start_PWM(); break;
			 case 0b10111101 : num=7;start_PWM(); break;
			 case 0b10111011 : num=8;start_PWM(); break;
			 
			 case 0b01111110 : num=9;start_PWM(); break;
			 case 0b01111101 : num=10;start_PWM(); break;
			 case 0b01111011 : num=11;start_PWM(); break;
			 
			 case 0b11100111 : num=12;start_PWM(); break;
			 case 0b11010111 : num=13;start_PWM(); break;
			 case 0b10110111 : num=14;start_PWM(); break;
			 case 0b01110111 : num=15;start_PWM(); break;
			 default         :  break;
	         }
       }///////////////////////  
       dile();
  }//for(;;)  ---end
  
}//main()  ---end

⌨️ 快捷键说明

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