『数字信号处理实践』仅利用ArduinoUNO通过脉宽调制生成DTMF
『数字信号处理实践』仅利用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相关推荐
- 数字信号处理(一)利用FFT对信号进行频谱分析
数字信号处理(一)利用FFT对信号进行频谱分析 1.实验目的 (1) 进一步加深DFT算法原理和基本性质的理解(因为FFT只是DFT的一种快速算法,所以FFT的运算结果必然满足DFT的基本性质). ( ...
- 『数字新基建』正在加速“数字产业化”向“产业数字化”转型进程
近日,中央财经委员会第十一次会议指出,要加强信息.科技.物流等产业升级基础设施建设,布局建设新一代超算.云计算.人工智能平台.宽带基础网络等设施,推进重大科技基础设施布局建设. 新冠病毒疫情的持续进展 ...
- matlab数字音频处理实验报告,数字信号处理实践——基于matlab的音频信号分析即处理...
基于matlab的音频信号分析即处理 一直很多人都困惑,大学里学了数字信号能干嘛,很少又实践动手的机会(这都是看个人主动性的,从来不缺锻炼的机会,机会不会摆在你面前吧!).很多人也就是做做题目 pra ...
- 数字信号处理实践方法 第二版 笔记
第二章 实时DSP系统的模拟I/O接口 模拟I/O接口的作用:允许模拟和数字格式的转换 2.1 典型的实时DSP系统 ADC(analog to digital converter):模拟/ 数字转换 ...
- 经典数字信号处理图书的个人评述【转】
在一网站上得到如下的很好的内容,故存放在此,以方便以后查看... http://emuch.net/html/201206/4595181.html 经典数字信号处理图书的个人评述 数 ...
- [日推荐]『众跑联盟』懒癌拯救者
2019独角兽企业重金招聘Python工程师标准>>> 好不容易放假,懒癌发作,就想瘫在家里不动,正在厨房做饭的老妈让你去楼下卖瓶酱油,怎么破? 万能的小编这就奉上一款小程序拯救你, ...
- [日推荐]『知乐邀请函』好用的H5制作工具
2019独角兽企业重金招聘Python工程师标准>>> 今天小编要给大家推荐一款很好用的H5制作小程序. 知乐邀请函 简介:知乐邀请函,在微信小程序中制作流行的H5页面.有官方和设计 ...
- [日推荐]『车价天天报』省钱买好车
2019独角兽企业重金招聘Python工程师标准>>> 今天小编给大家推荐一个购车相关的小程序,帮你随时了解车价行情以及最新优惠情况,省钱买好车! 车价天天报 **简介:**快速连接 ...
- [日推荐]『明星在哪儿』这可能是你离爱豆最近的一次!
2019独角兽企业重金招聘Python工程师标准>>> 每个粉丝最开心最渴望的事就是可以离自己家的爱豆更近一点,小编最近体验了一款小程序,堪称追星必备神器,现在就将测评报告分享给大家 ...
- [日推荐]『质安查』买到放心的产品就靠它了
2019独角兽企业重金招聘Python工程师标准>>> 喜欢买买买的小伙伴们一定都会担忧一个问题--产品是否合格.会不会买到假货? 有没有方便又可靠的质量检测工具能够解决这个问题呢? ...
最新文章
- centos安装与配置dhcp服务
- 史上最全阿里云服务器上Docker部署Springboot项目 实战 每一步都带详细图解!!!
- 多文档版的的正则表达式工具
- centos 忘记 root 密码
- How is navigation target url request handled by backend
- python数据类型之元组类型
- A*B NTT快速数论变换
- Oracle使用Sql把XML解析成表(Table)的方法
- Laravel 项目开发规范
- C# —— IEnumerable和状态机
- 转:使用脚本关闭订单头
- 袁玉玮:简介人工智能在基金界的应用现状 (二)卖方交易员被冲击
- 松下PLC连接海创-IIoT平台案例
- 软件等于计算机程序加数据加什么,南航计算机软件数据结构上机实践报告
- android去掉锁屏界面,android怎么去掉锁屏界面
- 基于python实现检索标记敏感词并输出
- 山东省计算机科学与技术排名,2016山东省大学各学科门类最佳专业排行榜|大学排行榜|最佳专业排行榜_新浪教育_新浪网...
- Latex 操作(3) beamer(PPT)
- unity通过点击按钮获取手机验证码
- Eclipes配置代码模糊匹配(部分匹配)