900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 使用C语言编写DTMF检测程序 单片机IO口模拟DTMF信号的实践问题

使用C语言编写DTMF检测程序 单片机IO口模拟DTMF信号的实践问题

时间:2018-09-23 10:38:13

相关推荐

使用C语言编写DTMF检测程序 单片机IO口模拟DTMF信号的实践问题

自己顶顶~

我把问题简单化下,不谈自己的实践,网上有个 “双龙DTMF演示程序的两点疑问,做过DTMF(软件PWM方法)的请进”的帖子,我是看了这个帖子去动手实践的,实例代码如下

#include

#include

#defineXtal 8000000 // 系统时钟频率

#defineprescaler1// T1预分频系数

#defineN_samples128 // 在查找表中的样本数

#defineFck Xtal/prescaler // T1工作频率

#definedelaycyc 10// 读取port C口延时循环数

#pragma interrupt_handler ISR_T1_Overflow:7

/*************************** 正弦表 *****************************

样本表: 一个周期分成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 auc_frequencyH [4] = {

107,96,

87,79};

const unsigned char auc_frequencyL [4] = {

61,56,

50,46};

//**************************全局变量 ****************************

unsigned char x_SWa = 0x00;// 高频信号脉冲宽度

unsigned char x_SWb = 0x00;// 低频信号脉冲宽度

unsigned intX_LUTaExt = 0;

unsigned intX_LUTbExt = 0;

unsigned intX_LUTa;

unsigned intX_LUTb;

/*****************************************************************

定时器溢出中断服务程序

******************************************************************/

void ISR_T1_Overflow (void)

{

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)));

}

/***********************************************************

初始化

***********************************************************/

void init (void)

{

MCUCR=0x00;

TIMSK= 0x80; // T1 溢出中断使能

TCCR1A = (1<

TCCR1B = (1<

DDRD = (1 <

_SEI();// 全局中断使能

}

/*********************************************************************

为从PORT C口读取稳定的按键数据,所必须的延时程序(消抖延时)

*********************************************************************/

void Delay (void)

{

int i;

for (i = 0; i < delaycyc; i++) _NOP();

}

/********************************************************************

主程序

从PORT C口读取按键数据(如:SL+ AVR实验板) ,来确定产生哪个

高频(列)和低频(行)信号的混合信号,并且修正 x_SWa 和 x_SWb。

行-> PINC 高四位

列-> PINC 低四位

*********************************************************************/

void main (void)

{

unsigned char uc_Input;

unsigned char uc_Counter = 0;

init();

for(;;){

// 高四位 - 行

DDRC= 0x0F; // 高四位输入、低四位输出

PORTC = 0xF0; // 高四位打开上位、低四位输出低电平

uc_Counter = 0;

Delay(); // 延时等待 Port C 电平稳定

uc_Input = PINC;// 读取 Port C

do

{

if(!(uc_Input & 0x80)) // 检查MSB是否为低

{

// 取低音脉冲宽度并结束循环

x_SWb = auc_frequencyL[uc_Counter];

uc_Counter = 4;

}

else

{

x_SWb = 0;// 没有频率调制要求

}

uc_Counter++;

uc_Input = uc_Input << 1; // 左移一位

}

while ((uc_Counter < 4));

// 低四位 - 列

DDRC= 0xF0; // 高四位输出、低四位输入

PORTC = 0x0F; // 高四位输出低电平、低四位打开上拉

uc_Counter = 0;

Delay();// 延时等待 Port C 电平稳定

uc_Input = PINC;

uc_Input = uc_Input << 4;

do

{

if(!(uc_Input & 0x80)) // 检查 MSB 是否为低

{

x_SWa = auc_frequencyH[uc_Counter];//取高音脉冲宽度并结束循环

uc_Counter = 4;

}

else

{

x_SWa = 0;

}

uc_Counter++;

uc_Input = uc_Input<< 1;

}

while (uc_Counter < 4);

}

}

----------------------------------------------------------------------

我实践中的疑问点就一个,定时器溢出中断的时间是多长??????

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。