把下面讨论东西的彻底搞清楚,你想要技巧都在里面。
双龙DTMF演示程序的两点疑问,做过DTMF(软件PWM方法)的请进
这是双龙DTMF演示程序
#include <io8515v.h>
#include <macros.h>
#define XTAL 8000000 // 系统时钟频率
#define prescaler 1 // T1预分频系数
#define N_samples 128 // 在查找表中的样本数
#define Fck XTAL/prescaler // T1工作频率
#define delaycyc 10 // 读取PORT.html">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 int X_LUTaExt = 0;
unsigned int X_LUTbExt = 0;
unsigned int X_LUTa;
unsigned int X_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<<COM1A1)+(1<<PWM10); // 不翻转、8位PWM
TCCR1B = (1<<CS10); // 预分频系数为1、即CLK/1
DDRD = (1 <<PD5); // PD5 (OC1A)用作输出
_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; &nb
2楼: >>参与讨论
作者: 94179411 于 2006-9-5 9:45:00 发布:
--------------------------------------------------------------------------------
关于两点疑问
1:
DTMF音频矩阵的高频组为:
1209,1336,1477,1633
低频组为:697,770,852,941(Hz)
为什么在程序中定义为:
const unsigned CHAR auc_frequencyH [4] = {
107,96,
87,79};
const unsigned CHAR auc_frequencyL [4] = {
61,56,
50,46};
2:
ATMEL官方网站提供的查表算法为
X_LUTa=ROUND( (X_LUTaExt+8*N_samples*f*510/Fck) /8 )
程序中相应语句为:
x_SW = ROUND(8*N_samples*f*510/Fck)
X_LUTaExt += x_SWa;
X_LUTa = (CHAR)(((X_LUTaExt+4) >> 3)&(0x007F));
其中的
((X_LUTaExt+4) >> 3)
怎么理解?
3楼: >>参与讨论
作者: 94179411 于 2006-9-5 9:48:00 发布:
--------------------------------------------------------------------------------
第一个问题已经解决
定义中
const unsigned CHAR auc_frequencyH [4] = {
107,96,
87,79};
不是频率,是步长,是经过x_SW = ROUND(8*N_samples*f*510/Fck)
计算过的,如107=(8*128*1633*510)/8 000 000
我主观地认为auc_frequency就是频率的定义了
见笑了
4楼: >>参与讨论
作者: 94179411 于 2006-9-6 16:10:00 发布:
--------------------------------------------------------------------------------
这么久了,都没有高人指点?我该怎么办呢?
5楼: >>参与讨论
作者: 94179411 于 2006-9-9 7:02:00 发布:
--------------------------------------------------------------------------------
眼睁睁的看着它沉下去了,伤心
6楼: >>参与讨论
作者: 123654789 于 2006-9-9 9:48:00 发布:
--------------------------------------------------------------------------------
请 把电路图 粘贴出来
请 把电路图 粘贴出来
不然很难 解决 问题
7楼: >>参与讨论
作者: mylovetus 于 2006-9-9 14:06:00 发布:
--------------------------------------------------------------------------------
没有认真分析,简单提供一个想法而已
ATMEL官方网站提供的查表算法为
X_LUTa=ROUND( (X_LUTaExt+8*N_samples*f*510/Fck) /8 )
程序中相应语句为:
x_SW = ROUND(8*N_samples*f*510/Fck)
X_LUTaExt += x_SWa;
X_LUTa = (CHAR)(((X_LUTaExt+4) >> 3)&(0x007F));
其中的
((X_LUTaExt+4) >> 3)
怎么理解?
简单判断,仅为提供思路!
其中的(X_LUTaExt + 4)>>3有点象除以8!
8楼: >>参与讨论
作者: 94179411 于 2006-9-10 9:40:00 发布:
--------------------------------------------------------------------------------
TO:mylovetus AND 123654789
TO:mylovetus
其中的(X_LUTaExt + 4)>>3其中>>3除以8很容易理解
但是+ 4的涵义我一直搞不懂
TO:123654789
电路图我也没有,我仅仅是研究算法,我觉得这跟硬件关系不大,很显然是个4*4键盘扫描电路,我觉得这跟硬件关系不大,关键是产生DTMF信号的算法实现
不过,要谢谢两位热心人
等待再有高人指点
9楼: >>参与讨论
作者: 94179411 于 2006-9-14 7:19:00 发布:
--------------------------------------------------------------------------------
我自己顶!
10楼: >>参与讨论
作者: 94179411 于 2006-9-14 16:20:00 发布:
--------------------------------------------------------------------------------
我再顶...
11楼: >>参与讨论
作者: 极限思考 于 2006-9-14 16:27:00 发布:
--------------------------------------------------------------------------------
TO 94
+4应该是为了调整进位,用来划分比例查表,N=x*1/4的关系。
比例对应0-3对应0
4-7对应1
。。。。
12楼: >>参与讨论
作者: 94179411 于 2006-9-14 19:33:00 发布:
--------------------------------------------------------------------------------
若有所悟!但是划分查表的意义何在?
划分比例查表到底是怎么回事?都在什么地方有应用?还请极限大哥好人做到底,再点化一下小弟,不胜感激!
13楼: >>参与讨论
作者: Sethhorus 于 2006-9-15 12:53:00 发布:
--------------------------------------------------------------------------------
呵呵
到ATMEL 网站上去看看 那里又详细介绍
不过该程序产生的软件DTMF波还不能用于电话网,需要外加电路
如果真要发DTMF还是用硬件(HT9200)比较可靠 |