Arduino tone() 函数 和 IRemote库定时器冲突 实践解决方法
摘要
在使用arduino制作电子琴过程中遇 蜂鸣器发声函数tone()与红外遥控模块函数IRemote冲突问题。本文提供参考两种解决方法的实践过程,思路分别来自以下博客。
- arduino 定时器、定时中断与PWM使用以及注意事项
arduino使用tone函数播放音乐,调用两个定时器实现双音轨播放
主要思想:修改系统tone()函数库中定时器,使两个函数分别使用不同定时器,从而化解冲突。 - tone() 和 IRremote 冲突的解决办法
主要思想: 避免使用系统定义tone()函数,自定义新函数,绕开定时器。
实践1. 修改定时器
- 在arduino 安装目录下(我的是D:\arduino\hardware\arduino\avr\cores\arduino)中找到Tone.cpp
- 在大概第100行左右,看代码,修改定时器。代码注释不是很明显,灰色的地方注意一下啊,下面代码中已经修改。
//由于我使用的是MEGA2560的板子,所以在这个地方修改
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define AVAILABLE_TONE_PINS 1
//mega1280 mega2560这里修改!!!为TIMER1
#define USE_TIMER1
//这里 修改为1
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 1 /*, 3, 4, 5, 1, 0 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };
#elif defined(__AVR_ATmega8__)
#define AVAILABLE_TONE_PINS 1
#define USE_TIMER2
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
#elif defined(__AVR_ATmega32U4__)
#define AVAILABLE_TONE_PINS 1
#define USE_TIMER3
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
#else
#define AVAILABLE_TONE_PINS 1
//之前一直在这里改,然后编译不报错,但是不能发出声音,因为执行的是上边mega2560的代码
#define USE_TIMER1
// Leave timer 0 to last.
//const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 1 };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };
#endif
- 正常使用tone函数即可。
实践2. 使用自定义函数
直接复制代码,在ino文件中新建这个函数,调用即可。
缺点:效果没有库函数 tone()好,也正是因此我才去改的定时器,使用原生函数。