『数字信号处理实践』仅利用ArduinoUNO通过脉宽调制生成DTMF

  • 简述
    • 代码
    • 为什么用定时器?
    • 为什么不用analogWrite?
    • 为什么用正弦表?

简述

DTMF是正弦波的叠加,众所周知,Arduino没有DAC,因此要想仅用ArduinoUNO生成DTMF信号,就必须利用PWM这样的方法。

代码

效果:烧进程序后,将喇叭一边接11号,一边接地,可以考虑加几个电容来滤除谐波、阻隔直流。

#include "Arduino.h"#define WAVE_TABLE_SIZE 200#define DTMF_PORT PORTD //输出端口PORTD,0-7号
#define DTMF_DDR DDRD //GPIO_PORTD功能配置寄存器#define BUZZ_TIME 1000
#define DELAY_TIME 2000
//正弦表
unsigned char waveTable[WAVE_TABLE_SIZE] = { 64,  66,  68,  69,  71,  73,  75,  77,  79,  80,  82,  84,  86,  88,  89, 91,  93,  94,  96,  97,  99, 101, 102, 103, 105, 106, 107, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 120, 121, 121, 122, 122, 123, 123, 123, 123, 124, 124, 124, 124, 124, 123, 123, 123, 123, 122, 122, 121, 121, 120, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 107, 106, 105, 103, 102, 101,  99,  97,  96,  94,  93,  91,  89,  88,  86,  84, 82,  80,  79,  77,  75,  73,  71,  69,  68,  66,  64,  62,  60,  58,  56, 54,  53,  51,  49,  47,  45,  43,  42,  40,  38,  37,  35,  33,  32,  30, 28,  27,  26,  24,  23,  21,  20,  19,  18,  16,  15,  14,  13,  12,  11, 10,   9,   9,   8,   7,   7,   6,   6,   5,   5,   4,   4,   4,   4,   4, 04,   4,   4,   4,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   9, 10,  11,  12,  13,  14,  15,  16,  18,  19,  20,  21,  23,  24,  26,  27, 28,  30,  32,  33,  35,  37,  38,  40,  42,  43,  45,  47,  49,  51,  53, 54,  56,  58,  60,  62 };//步长表
unsigned char stepTable[]={14,15,17,19,24,27,30};unsigned char *f1_ptr;
unsigned char f1_step;unsigned char *f2_ptr;unsigned char f2_step;//Timer1使能
void enableTimer1()//fs=10khz @1Mhz Crystal
{noInterrupts();// Initialize TIMER1 registers to known state. TCCR1A = 0;TCCR1B = 0;TCNT1 = 0;TIMSK1 = 0;// Set TIMER1 to 10KHz. OCR1A = 24;TCCR1B |= (1 << WGM12);TCCR1B |= (1 << CS11) | (1 << CS10);// Enable TIMER1 interrupt.TIMSK1 |= (1 << OCIE1A);interrupts();}//Timer1关闭
void disableTimer1()
{noInterrupts();TCCR1A = 0;TCCR1B = 0;TCNT1 = 0;TIMSK1 = 0;interrupts();
}void genDTMF(int f1,int f2,int duration)
{//配置指针f1_ptr=waveTable;f1_step=stepTable[f1];f2_ptr=waveTable;f2_step=stepTable[f2];//启动Timer1enableTimer1();//等待durationfor(int i=0;i<duration;i++)delay(1);//关闭Timer1disableTimer1();Timer2PWMCtrl(0);
}//Timer1中断服务函数
ISR(TIMER1_COMPA_vect)
{//输出正弦表//DTMF_PORT=*f1_ptr+*f2_ptr;Timer2PWMCtrl(*f1_ptr+*f2_ptr);f1_ptr+=f1_step;f2_ptr+=f2_step;//指针移位 TODO:利用Duff‘s Device优化效率if(f1_ptr-waveTable>=WAVE_TABLE_SIZE)f1_ptr-=WAVE_TABLE_SIZE;if(f2_ptr-waveTable>=WAVE_TABLE_SIZE)f2_ptr-=WAVE_TABLE_SIZE;
}void Timer2PWMCtrl(unsigned char val)
{TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);//设置PWM模式和输出管脚TCCR2B = _BV(CS20);//设置不分频,实际上8分频就已经满足条件了,16m/8/256=7812.5//CS2  Divisor  Frequency//001    1        31372.55//010    8        3921.16//011    32       980.39//100    64       490.20   <--DEFAULT//101    128      245.10//110    256      122.55//111    1024     30.64OCR2A = val;//占空比0-255
}
void setup() {pinMode(11,OUTPUT);Serial.begin(9600);
}//播放DTMF
void loop() {// put your main code here, to run repeatedly:Serial.println("1");genDTMF(0,4,BUZZ_TIME);delay(DELAY_TIME);Serial.println("2");genDTMF(0,5,BUZZ_TIME);delay(DELAY_TIME);Serial.println("3");genDTMF(0,6,BUZZ_TIME);delay(DELAY_TIME);Serial.println("4");genDTMF(1,4,BUZZ_TIME);delay(DELAY_TIME);Serial.println("5");genDTMF(1,5,BUZZ_TIME);delay(DELAY_TIME);Serial.println("6");genDTMF(1,6,BUZZ_TIME);delay(DELAY_TIME);Serial.println("7");genDTMF(2,4,BUZZ_TIME);delay(DELAY_TIME);Serial.println("8");genDTMF(2,5,BUZZ_TIME);delay(DELAY_TIME);Serial.println("9");genDTMF(2,6,BUZZ_TIME);delay(DELAY_TIME);Serial.println("0");genDTMF(3,5,BUZZ_TIME);delay(DELAY_TIME);
}

为什么用定时器?

为了保证精准的采样率

为什么不用analogWrite?

Arduino自带的analogWrite默认使用64分频产生脉宽调制波,以与3和11号引脚连接的Timer2为例,16Mhz(晶振主频)/64/256=976.5625Hz,这样的调制频率远不够产生DTMF信号所需的最低采样率(请参考奈奎斯特采样定则)。

为什么用正弦表?

UNO的主控Atmega328p算力不够,很难在采样周期间隔内将下一个所需的幅值算出来,所以要用正弦表做加速,正弦表就是一个周期的sin,采样精度越高,效果越好,通过调节遍历的步长,即可产生相应频率的正弦波。

『数字信号处理实践』仅利用ArduinoUNO通过脉宽调制生成DTMF相关推荐

  1. 数字信号处理(一)利用FFT对信号进行频谱分析

    数字信号处理(一)利用FFT对信号进行频谱分析 1.实验目的 (1) 进一步加深DFT算法原理和基本性质的理解(因为FFT只是DFT的一种快速算法,所以FFT的运算结果必然满足DFT的基本性质). ( ...

  2. 『数字新基建』正在加速“数字产业化”向“产业数字化”转型进程

    近日,中央财经委员会第十一次会议指出,要加强信息.科技.物流等产业升级基础设施建设,布局建设新一代超算.云计算.人工智能平台.宽带基础网络等设施,推进重大科技基础设施布局建设. 新冠病毒疫情的持续进展 ...

  3. matlab数字音频处理实验报告,数字信号处理实践——基于matlab的音频信号分析即处理...

    基于matlab的音频信号分析即处理 一直很多人都困惑,大学里学了数字信号能干嘛,很少又实践动手的机会(这都是看个人主动性的,从来不缺锻炼的机会,机会不会摆在你面前吧!).很多人也就是做做题目 pra ...

  4. 数字信号处理实践方法 第二版 笔记

    第二章 实时DSP系统的模拟I/O接口 模拟I/O接口的作用:允许模拟和数字格式的转换 2.1 典型的实时DSP系统 ADC(analog to digital converter):模拟/ 数字转换 ...

  5. 经典数字信号处理图书的个人评述【转】

    在一网站上得到如下的很好的内容,故存放在此,以方便以后查看... http://emuch.net/html/201206/4595181.html 经典数字信号处理图书的个人评述         数 ...

  6. [日推荐]『众跑联盟』懒癌拯救者

    2019独角兽企业重金招聘Python工程师标准>>> 好不容易放假,懒癌发作,就想瘫在家里不动,正在厨房做饭的老妈让你去楼下卖瓶酱油,怎么破? 万能的小编这就奉上一款小程序拯救你, ...

  7. [日推荐]『知乐邀请函』好用的H5制作工具

    2019独角兽企业重金招聘Python工程师标准>>> 今天小编要给大家推荐一款很好用的H5制作小程序. 知乐邀请函 简介:知乐邀请函,在微信小程序中制作流行的H5页面.有官方和设计 ...

  8. [日推荐]『车价天天报』省钱买好车

    2019独角兽企业重金招聘Python工程师标准>>> 今天小编给大家推荐一个购车相关的小程序,帮你随时了解车价行情以及最新优惠情况,省钱买好车! 车价天天报 **简介:**快速连接 ...

  9. [日推荐]『明星在哪儿』这可能是你离爱豆最近的一次!

    2019独角兽企业重金招聘Python工程师标准>>> 每个粉丝最开心最渴望的事就是可以离自己家的爱豆更近一点,小编最近体验了一款小程序,堪称追星必备神器,现在就将测评报告分享给大家 ...

  10. [日推荐]『质安查』买到放心的产品就靠它了

    2019独角兽企业重金招聘Python工程师标准>>> 喜欢买买买的小伙伴们一定都会担忧一个问题--产品是否合格.会不会买到假货? 有没有方便又可靠的质量检测工具能够解决这个问题呢? ...

最新文章

  1. centos安装与配置dhcp服务
  2. 史上最全阿里云服务器上Docker部署Springboot项目 实战 每一步都带详细图解!!!
  3. 多文档版的的正则表达式工具
  4. centos 忘记 root 密码
  5. How is navigation target url request handled by backend
  6. python数据类型之元组类型
  7. A*B NTT快速数论变换
  8. Oracle使用Sql把XML解析成表(Table)的方法
  9. Laravel 项目开发规范
  10. C# —— IEnumerable和状态机
  11. 转:使用脚本关闭订单头
  12. 袁玉玮:简介人工智能在基金界的应用现状 (二)卖方交易员被冲击
  13. 松下PLC连接海创-IIoT平台案例
  14. 软件等于计算机程序加数据加什么,南航计算机软件数据结构上机实践报告
  15. android去掉锁屏界面,android怎么去掉锁屏界面
  16. 基于python实现检索标记敏感词并输出
  17. 山东省计算机科学与技术排名,2016山东省大学各学科门类最佳专业排行榜|大学排行榜|最佳专业排行榜_新浪教育_新浪网...
  18. Latex 操作(3) beamer(PPT)
  19. unity通过点击按钮获取手机验证码
  20. Eclipes配置代码模糊匹配(部分匹配)

热门文章

  1. 涉及第三方支付接口,怎么测?
  2. day12 函数高级
  3. java rx3x_GitHub - xkm123/oss-sdk-java: java sdk for oss
  4. 知其然,知其所以然——ArrayList.add()详解
  5. 开源的文件服务器有哪些,开源文件服务器
  6. 【环境部署】基于FreeSSL生成免费SSL证书
  7. 山海经电子书古文/翻译白话文版发布,免费电子书。
  8. 在MAC终端下打开Finder
  9. 用户画像 客户消费模型表
  10. ARM启动流程及启动代码分析