<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-cn">
		<id>http://wiki.ywrobot.net/index.php?action=history&amp;feed=atom&amp;title=Tone.cpp</id>
		<title>Tone.cpp - 版本历史</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.ywrobot.net/index.php?action=history&amp;feed=atom&amp;title=Tone.cpp"/>
		<link rel="alternate" type="text/html" href="http://wiki.ywrobot.net/index.php?title=Tone.cpp&amp;action=history"/>
		<updated>2026-05-14T11:01:32Z</updated>
		<subtitle>本wiki的该页面的版本历史</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>http://wiki.ywrobot.net/index.php?title=Tone.cpp&amp;diff=86&amp;oldid=prev</id>
		<title>YWrobot CYB：创建页面，内容为“&lt;pre style=&quot;color:blue&quot;&gt; /* Tone.cpp    A Tone Generator Library    Written by Brett Hagman    This library is free software; you can redistribute it and/or   modify...”</title>
		<link rel="alternate" type="text/html" href="http://wiki.ywrobot.net/index.php?title=Tone.cpp&amp;diff=86&amp;oldid=prev"/>
				<updated>2016-04-25T02:18:07Z</updated>
		
		<summary type="html">&lt;p&gt;创建页面，内容为“&amp;lt;pre style=&amp;quot;color:blue&amp;quot;&amp;gt; /* Tone.cpp    A Tone Generator Library    Written by Brett Hagman    This library is free software; you can redistribute it and/or   modify...”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre style=&amp;quot;color:blue&amp;quot;&amp;gt;&lt;br /&gt;
/* Tone.cpp&lt;br /&gt;
&lt;br /&gt;
  A Tone Generator Library&lt;br /&gt;
&lt;br /&gt;
  Written by Brett Hagman&lt;br /&gt;
&lt;br /&gt;
  This library is free software; you can redistribute it and/or&lt;br /&gt;
  modify it under the terms of the GNU Lesser General Public&lt;br /&gt;
  License as published by the Free Software Foundation; either&lt;br /&gt;
  version 2.1 of the License, or (at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
  This library is distributed in the hope that it will be useful,&lt;br /&gt;
  but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;
  Lesser General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
  You should have received a copy of the GNU Lesser General Public&lt;br /&gt;
  License along with this library; if not, write to the Free Software&lt;br /&gt;
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA&lt;br /&gt;
&lt;br /&gt;
Version Modified By Date     Comments&lt;br /&gt;
------- ----------- -------- --------&lt;br /&gt;
0001    B Hagman    09/08/02 Initial coding&lt;br /&gt;
0002    B Hagman    09/08/18 Multiple pins&lt;br /&gt;
0003    B Hagman    09/08/18 Moved initialization from constructor to begin()&lt;br /&gt;
0004    B Hagman    09/09/26 Fixed problems with ATmega8&lt;br /&gt;
0005    B Hagman    09/11/23 Scanned prescalars for best fit on 8 bit timers&lt;br /&gt;
                    09/11/25 Changed pin toggle method to XOR&lt;br /&gt;
                    09/11/25 Fixed timer0 from being excluded&lt;br /&gt;
0006    D Mellis    09/12/29 Replaced objects with functions&lt;br /&gt;
0007    M Sproul    10/08/29 Changed #ifdefs from cpu to register&lt;br /&gt;
0008    S Kanemoto  12/06/22 Fixed for Leonardo by @maris_HY&lt;br /&gt;
*************************************************/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
#include &amp;quot;Arduino.h&amp;quot;&lt;br /&gt;
#include &amp;quot;pins_arduino.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)&lt;br /&gt;
#define TCCR2A TCCR2&lt;br /&gt;
#define TCCR2B TCCR2&lt;br /&gt;
#define COM2A1 COM21&lt;br /&gt;
#define COM2A0 COM20&lt;br /&gt;
#define OCR2A OCR2&lt;br /&gt;
#define TIMSK2 TIMSK&lt;br /&gt;
#define OCIE2A OCIE2&lt;br /&gt;
#define TIMER2_COMPA_vect TIMER2_COMP_vect&lt;br /&gt;
#define TIMSK1 TIMSK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// timerx_toggle_count:&lt;br /&gt;
//  &amp;gt; 0 - duration specified&lt;br /&gt;
//  = 0 - stopped&lt;br /&gt;
//  &amp;lt; 0 - infinitely (until stop() method called, or new play() called)&lt;br /&gt;
&lt;br /&gt;
#if !defined(__AVR_ATmega8__)&lt;br /&gt;
volatile long timer0_toggle_count;&lt;br /&gt;
volatile uint8_t *timer0_pin_port;&lt;br /&gt;
volatile uint8_t timer0_pin_mask;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
volatile long timer1_toggle_count;&lt;br /&gt;
volatile uint8_t *timer1_pin_port;&lt;br /&gt;
volatile uint8_t timer1_pin_mask;&lt;br /&gt;
volatile long timer2_toggle_count;&lt;br /&gt;
volatile uint8_t *timer2_pin_port;&lt;br /&gt;
volatile uint8_t timer2_pin_mask;&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK3)&lt;br /&gt;
volatile long timer3_toggle_count;&lt;br /&gt;
volatile uint8_t *timer3_pin_port;&lt;br /&gt;
volatile uint8_t timer3_pin_mask;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK4)&lt;br /&gt;
volatile long timer4_toggle_count;&lt;br /&gt;
volatile uint8_t *timer4_pin_port;&lt;br /&gt;
volatile uint8_t timer4_pin_mask;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK5)&lt;br /&gt;
volatile long timer5_toggle_count;&lt;br /&gt;
volatile uint8_t *timer5_pin_port;&lt;br /&gt;
volatile uint8_t timer5_pin_mask;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)&lt;br /&gt;
&lt;br /&gt;
#define AVAILABLE_TONE_PINS 1&lt;br /&gt;
#define USE_TIMER2&lt;br /&gt;
&lt;br /&gt;
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };&lt;br /&gt;
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };&lt;br /&gt;
&lt;br /&gt;
#elif defined(__AVR_ATmega8__)&lt;br /&gt;
&lt;br /&gt;
#define AVAILABLE_TONE_PINS 1&lt;br /&gt;
#define USE_TIMER2&lt;br /&gt;
&lt;br /&gt;
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };&lt;br /&gt;
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };&lt;br /&gt;
&lt;br /&gt;
#elif defined(__AVR_ATmega32U4__)&lt;br /&gt;
 &lt;br /&gt;
#define AVAILABLE_TONE_PINS 1&lt;br /&gt;
#define USE_TIMER3&lt;br /&gt;
 &lt;br /&gt;
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 3 /*, 1 */ };&lt;br /&gt;
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };&lt;br /&gt;
 &lt;br /&gt;
#else&lt;br /&gt;
&lt;br /&gt;
#define AVAILABLE_TONE_PINS 1&lt;br /&gt;
#define USE_TIMER2&lt;br /&gt;
&lt;br /&gt;
// Leave timer 0 to last.&lt;br /&gt;
const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };&lt;br /&gt;
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
static int8_t toneBegin(uint8_t _pin)&lt;br /&gt;
{&lt;br /&gt;
  int8_t _timer = -1;&lt;br /&gt;
&lt;br /&gt;
  // if we're already using the pin, the timer should be configured.  &lt;br /&gt;
  for (int i = 0; i &amp;lt; AVAILABLE_TONE_PINS; i++) {&lt;br /&gt;
    if (tone_pins[i] == _pin) {&lt;br /&gt;
      return pgm_read_byte(tone_pin_to_timer_PGM + i);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  // search for an unused timer.&lt;br /&gt;
  for (int i = 0; i &amp;lt; AVAILABLE_TONE_PINS; i++) {&lt;br /&gt;
    if (tone_pins[i] == 255) {&lt;br /&gt;
      tone_pins[i] = _pin;&lt;br /&gt;
      _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (_timer != -1)&lt;br /&gt;
  {&lt;br /&gt;
    // Set timer specific stuff&lt;br /&gt;
    // All timers in CTC mode&lt;br /&gt;
    // 8 bit timers will require changing prescalar values,&lt;br /&gt;
    // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar&lt;br /&gt;
    switch (_timer)&lt;br /&gt;
    {&lt;br /&gt;
      #if defined(TCCR0A) &amp;amp;&amp;amp; defined(TCCR0B)&lt;br /&gt;
      case 0:&lt;br /&gt;
        // 8 bit timer&lt;br /&gt;
        TCCR0A = 0;&lt;br /&gt;
        TCCR0B = 0;&lt;br /&gt;
        bitWrite(TCCR0A, WGM01, 1);&lt;br /&gt;
        bitWrite(TCCR0B, CS00, 1);&lt;br /&gt;
        timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));&lt;br /&gt;
        timer0_pin_mask = digitalPinToBitMask(_pin);&lt;br /&gt;
        break;&lt;br /&gt;
      #endif&lt;br /&gt;
&lt;br /&gt;
      #if defined(TCCR1A) &amp;amp;&amp;amp; defined(TCCR1B) &amp;amp;&amp;amp; defined(WGM12)&lt;br /&gt;
      case 1:&lt;br /&gt;
        // 16 bit timer&lt;br /&gt;
        TCCR1A = 0;&lt;br /&gt;
        TCCR1B = 0;&lt;br /&gt;
        bitWrite(TCCR1B, WGM12, 1);&lt;br /&gt;
        bitWrite(TCCR1B, CS10, 1);&lt;br /&gt;
        timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));&lt;br /&gt;
        timer1_pin_mask = digitalPinToBitMask(_pin);&lt;br /&gt;
        break;&lt;br /&gt;
      #endif&lt;br /&gt;
&lt;br /&gt;
      #if defined(TCCR2A) &amp;amp;&amp;amp; defined(TCCR2B)&lt;br /&gt;
      case 2:&lt;br /&gt;
        // 8 bit timer&lt;br /&gt;
        TCCR2A = 0;&lt;br /&gt;
        TCCR2B = 0;&lt;br /&gt;
        bitWrite(TCCR2A, WGM21, 1);&lt;br /&gt;
        bitWrite(TCCR2B, CS20, 1);&lt;br /&gt;
        timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));&lt;br /&gt;
        timer2_pin_mask = digitalPinToBitMask(_pin);&lt;br /&gt;
        break;&lt;br /&gt;
      #endif&lt;br /&gt;
&lt;br /&gt;
      #if defined(TCCR3A) &amp;amp;&amp;amp; defined(TCCR3B) &amp;amp;&amp;amp;  defined(TIMSK3)&lt;br /&gt;
      case 3:&lt;br /&gt;
        // 16 bit timer&lt;br /&gt;
        TCCR3A = 0;&lt;br /&gt;
        TCCR3B = 0;&lt;br /&gt;
        bitWrite(TCCR3B, WGM32, 1);&lt;br /&gt;
        bitWrite(TCCR3B, CS30, 1);&lt;br /&gt;
        timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));&lt;br /&gt;
        timer3_pin_mask = digitalPinToBitMask(_pin);&lt;br /&gt;
        break;&lt;br /&gt;
      #endif&lt;br /&gt;
&lt;br /&gt;
      #if defined(TCCR4A) &amp;amp;&amp;amp; defined(TCCR4B) &amp;amp;&amp;amp;  defined(TIMSK4)&lt;br /&gt;
      case 4:&lt;br /&gt;
        // 16 bit timer&lt;br /&gt;
        TCCR4A = 0;&lt;br /&gt;
        TCCR4B = 0;&lt;br /&gt;
        #if defined(WGM42)&lt;br /&gt;
          bitWrite(TCCR4B, WGM42, 1);&lt;br /&gt;
        #elif defined(CS43)&lt;br /&gt;
          #warning this may not be correct&lt;br /&gt;
          // atmega32u4&lt;br /&gt;
          bitWrite(TCCR4B, CS43, 1);&lt;br /&gt;
        #endif&lt;br /&gt;
        bitWrite(TCCR4B, CS40, 1);&lt;br /&gt;
        timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));&lt;br /&gt;
        timer4_pin_mask = digitalPinToBitMask(_pin);&lt;br /&gt;
        break;&lt;br /&gt;
      #endif&lt;br /&gt;
&lt;br /&gt;
      #if defined(TCCR5A) &amp;amp;&amp;amp; defined(TCCR5B) &amp;amp;&amp;amp;  defined(TIMSK5)&lt;br /&gt;
      case 5:&lt;br /&gt;
        // 16 bit timer&lt;br /&gt;
        TCCR5A = 0;&lt;br /&gt;
        TCCR5B = 0;&lt;br /&gt;
        bitWrite(TCCR5B, WGM52, 1);&lt;br /&gt;
        bitWrite(TCCR5B, CS50, 1);&lt;br /&gt;
        timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));&lt;br /&gt;
        timer5_pin_mask = digitalPinToBitMask(_pin);&lt;br /&gt;
        break;&lt;br /&gt;
      #endif&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return _timer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// frequency (in hertz) and duration (in milliseconds).&lt;br /&gt;
&lt;br /&gt;
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t prescalarbits = 0b001;&lt;br /&gt;
  long toggle_count = 0;&lt;br /&gt;
  uint32_t ocr = 0;&lt;br /&gt;
  int8_t _timer;&lt;br /&gt;
&lt;br /&gt;
  _timer = toneBegin(_pin);&lt;br /&gt;
&lt;br /&gt;
  if (_timer &amp;gt;= 0)&lt;br /&gt;
  {&lt;br /&gt;
    // Set the pinMode as OUTPUT&lt;br /&gt;
    pinMode(_pin, OUTPUT);&lt;br /&gt;
    &lt;br /&gt;
    // if we are using an 8 bit timer, scan through prescalars to find the best fit&lt;br /&gt;
    if (_timer == 0 || _timer == 2)&lt;br /&gt;
    {&lt;br /&gt;
      ocr = F_CPU / frequency / 2 - 1;&lt;br /&gt;
      prescalarbits = 0b001;  // ck/1: same for both timers&lt;br /&gt;
      if (ocr &amp;gt; 255)&lt;br /&gt;
      {&lt;br /&gt;
        ocr = F_CPU / frequency / 2 / 8 - 1;&lt;br /&gt;
        prescalarbits = 0b010;  // ck/8: same for both timers&lt;br /&gt;
&lt;br /&gt;
        if (_timer == 2 &amp;amp;&amp;amp; ocr &amp;gt; 255)&lt;br /&gt;
        {&lt;br /&gt;
          ocr = F_CPU / frequency / 2 / 32 - 1;&lt;br /&gt;
          prescalarbits = 0b011;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if (ocr &amp;gt; 255)&lt;br /&gt;
        {&lt;br /&gt;
          ocr = F_CPU / frequency / 2 / 64 - 1;&lt;br /&gt;
          prescalarbits = _timer == 0 ? 0b011 : 0b100;&lt;br /&gt;
&lt;br /&gt;
          if (_timer == 2 &amp;amp;&amp;amp; ocr &amp;gt; 255)&lt;br /&gt;
          {&lt;br /&gt;
            ocr = F_CPU / frequency / 2 / 128 - 1;&lt;br /&gt;
            prescalarbits = 0b101;&lt;br /&gt;
          }&lt;br /&gt;
&lt;br /&gt;
          if (ocr &amp;gt; 255)&lt;br /&gt;
          {&lt;br /&gt;
            ocr = F_CPU / frequency / 2 / 256 - 1;&lt;br /&gt;
            prescalarbits = _timer == 0 ? 0b100 : 0b110;&lt;br /&gt;
            if (ocr &amp;gt; 255)&lt;br /&gt;
            {&lt;br /&gt;
              // can't do any better than /1024&lt;br /&gt;
              ocr = F_CPU / frequency / 2 / 1024 - 1;&lt;br /&gt;
              prescalarbits = _timer == 0 ? 0b101 : 0b111;&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
#if defined(TCCR0B)&lt;br /&gt;
      if (_timer == 0)&lt;br /&gt;
      {&lt;br /&gt;
        TCCR0B = prescalarbits;&lt;br /&gt;
      }&lt;br /&gt;
      else&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(TCCR2B)&lt;br /&gt;
      {&lt;br /&gt;
        TCCR2B = prescalarbits;&lt;br /&gt;
      }&lt;br /&gt;
#else&lt;br /&gt;
      {&lt;br /&gt;
        // dummy place holder to make the above ifdefs work&lt;br /&gt;
      }&lt;br /&gt;
#endif&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      // two choices for the 16 bit timers: ck/1 or ck/64&lt;br /&gt;
      ocr = F_CPU / frequency / 2 - 1;&lt;br /&gt;
&lt;br /&gt;
      prescalarbits = 0b001;&lt;br /&gt;
      if (ocr &amp;gt; 0xffff)&lt;br /&gt;
      {&lt;br /&gt;
        ocr = F_CPU / frequency / 2 / 64 - 1;&lt;br /&gt;
        prescalarbits = 0b011;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      if (_timer == 1)&lt;br /&gt;
      {&lt;br /&gt;
#if defined(TCCR1B)&lt;br /&gt;
        TCCR1B = (TCCR1B &amp;amp; 0b11111000) | prescalarbits;&lt;br /&gt;
#endif&lt;br /&gt;
      }&lt;br /&gt;
#if defined(TCCR3B)&lt;br /&gt;
      else if (_timer == 3)&lt;br /&gt;
        TCCR3B = (TCCR3B &amp;amp; 0b11111000) | prescalarbits;&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(TCCR4B)&lt;br /&gt;
      else if (_timer == 4)&lt;br /&gt;
        TCCR4B = (TCCR4B &amp;amp; 0b11111000) | prescalarbits;&lt;br /&gt;
#endif&lt;br /&gt;
#if defined(TCCR5B)&lt;br /&gt;
      else if (_timer == 5)&lt;br /&gt;
        TCCR5B = (TCCR5B &amp;amp; 0b11111000) | prescalarbits;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
    // Calculate the toggle count&lt;br /&gt;
    if (duration &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
      toggle_count = 2 * frequency * duration / 1000;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      toggle_count = -1;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Set the OCR for the given timer,&lt;br /&gt;
    // set the toggle count,&lt;br /&gt;
    // then turn on the interrupts&lt;br /&gt;
    switch (_timer)&lt;br /&gt;
    {&lt;br /&gt;
&lt;br /&gt;
#if defined(OCR0A) &amp;amp;&amp;amp; defined(TIMSK0) &amp;amp;&amp;amp; defined(OCIE0A)&lt;br /&gt;
      case 0:&lt;br /&gt;
        OCR0A = ocr;&lt;br /&gt;
        timer0_toggle_count = toggle_count;&lt;br /&gt;
        bitWrite(TIMSK0, OCIE0A, 1);&lt;br /&gt;
        break;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
      case 1:&lt;br /&gt;
#if defined(OCR1A) &amp;amp;&amp;amp; defined(TIMSK1) &amp;amp;&amp;amp; defined(OCIE1A)&lt;br /&gt;
        OCR1A = ocr;&lt;br /&gt;
        timer1_toggle_count = toggle_count;&lt;br /&gt;
        bitWrite(TIMSK1, OCIE1A, 1);&lt;br /&gt;
#elif defined(OCR1A) &amp;amp;&amp;amp; defined(TIMSK) &amp;amp;&amp;amp; defined(OCIE1A)&lt;br /&gt;
        // this combination is for at least the ATmega32&lt;br /&gt;
        OCR1A = ocr;&lt;br /&gt;
        timer1_toggle_count = toggle_count;&lt;br /&gt;
        bitWrite(TIMSK, OCIE1A, 1);&lt;br /&gt;
#endif&lt;br /&gt;
        break;&lt;br /&gt;
&lt;br /&gt;
#if defined(OCR2A) &amp;amp;&amp;amp; defined(TIMSK2) &amp;amp;&amp;amp; defined(OCIE2A)&lt;br /&gt;
      case 2:&lt;br /&gt;
        OCR2A = ocr;&lt;br /&gt;
        timer2_toggle_count = toggle_count;&lt;br /&gt;
        bitWrite(TIMSK2, OCIE2A, 1);&lt;br /&gt;
        break;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK3)&lt;br /&gt;
      case 3:&lt;br /&gt;
        OCR3A = ocr;&lt;br /&gt;
        timer3_toggle_count = toggle_count;&lt;br /&gt;
        bitWrite(TIMSK3, OCIE3A, 1);&lt;br /&gt;
        break;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK4)&lt;br /&gt;
      case 4:&lt;br /&gt;
        OCR4A = ocr;&lt;br /&gt;
        timer4_toggle_count = toggle_count;&lt;br /&gt;
        bitWrite(TIMSK4, OCIE4A, 1);&lt;br /&gt;
        break;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(OCR5A) &amp;amp;&amp;amp; defined(TIMSK5) &amp;amp;&amp;amp; defined(OCIE5A)&lt;br /&gt;
      case 5:&lt;br /&gt;
        OCR5A = ocr;&lt;br /&gt;
        timer5_toggle_count = toggle_count;&lt;br /&gt;
        bitWrite(TIMSK5, OCIE5A, 1);&lt;br /&gt;
        break;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// XXX: this function only works properly for timer 2 (the only one we use&lt;br /&gt;
// currently).  for the others, it should end the tone, but won't restore&lt;br /&gt;
// proper PWM functionality for the timer.&lt;br /&gt;
void disableTimer(uint8_t _timer)&lt;br /&gt;
{&lt;br /&gt;
  switch (_timer)&lt;br /&gt;
  {&lt;br /&gt;
    case 0:&lt;br /&gt;
      #if defined(TIMSK0)&lt;br /&gt;
        TIMSK0 = 0;&lt;br /&gt;
      #elif defined(TIMSK)&lt;br /&gt;
        TIMSK = 0; // atmega32&lt;br /&gt;
      #endif&lt;br /&gt;
      break;&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK1) &amp;amp;&amp;amp; defined(OCIE1A)&lt;br /&gt;
    case 1:&lt;br /&gt;
      bitWrite(TIMSK1, OCIE1A, 0);&lt;br /&gt;
      break;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    case 2:&lt;br /&gt;
      #if defined(TIMSK2) &amp;amp;&amp;amp; defined(OCIE2A)&lt;br /&gt;
        bitWrite(TIMSK2, OCIE2A, 0); // disable interrupt&lt;br /&gt;
      #endif&lt;br /&gt;
      #if defined(TCCR2A) &amp;amp;&amp;amp; defined(WGM20)&lt;br /&gt;
        TCCR2A = (1 &amp;lt;&amp;lt; WGM20);&lt;br /&gt;
      #endif&lt;br /&gt;
      #if defined(TCCR2B) &amp;amp;&amp;amp; defined(CS22)&lt;br /&gt;
        TCCR2B = (TCCR2B &amp;amp; 0b11111000) | (1 &amp;lt;&amp;lt; CS22);&lt;br /&gt;
      #endif&lt;br /&gt;
      #if defined(OCR2A)&lt;br /&gt;
        OCR2A = 0;&lt;br /&gt;
      #endif&lt;br /&gt;
      break;&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK3)&lt;br /&gt;
    case 3:&lt;br /&gt;
      TIMSK3 = 0;&lt;br /&gt;
      break;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK4)&lt;br /&gt;
    case 4:&lt;br /&gt;
      TIMSK4 = 0;&lt;br /&gt;
      break;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if defined(TIMSK5)&lt;br /&gt;
    case 5:&lt;br /&gt;
      TIMSK5 = 0;&lt;br /&gt;
      break;&lt;br /&gt;
#endif&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void noTone(uint8_t _pin)&lt;br /&gt;
{&lt;br /&gt;
  int8_t _timer = -1;&lt;br /&gt;
  &lt;br /&gt;
  for (int i = 0; i &amp;lt; AVAILABLE_TONE_PINS; i++) {&lt;br /&gt;
    if (tone_pins[i] == _pin) {&lt;br /&gt;
      _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);&lt;br /&gt;
      tone_pins[i] = 255;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  disableTimer(_timer);&lt;br /&gt;
&lt;br /&gt;
  digitalWrite(_pin, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#ifdef USE_TIMER0&lt;br /&gt;
ISR(TIMER0_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (timer0_toggle_count != 0)&lt;br /&gt;
  {&lt;br /&gt;
    // toggle the pin&lt;br /&gt;
    *timer0_pin_port ^= timer0_pin_mask;&lt;br /&gt;
&lt;br /&gt;
    if (timer0_toggle_count &amp;gt; 0)&lt;br /&gt;
      timer0_toggle_count--;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    disableTimer(0);&lt;br /&gt;
    *timer0_pin_port &amp;amp;= ~(timer0_pin_mask);  // keep pin low after stop&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#ifdef USE_TIMER1&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (timer1_toggle_count != 0)&lt;br /&gt;
  {&lt;br /&gt;
    // toggle the pin&lt;br /&gt;
    *timer1_pin_port ^= timer1_pin_mask;&lt;br /&gt;
&lt;br /&gt;
    if (timer1_toggle_count &amp;gt; 0)&lt;br /&gt;
      timer1_toggle_count--;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    disableTimer(1);&lt;br /&gt;
    *timer1_pin_port &amp;amp;= ~(timer1_pin_mask);  // keep pin low after stop&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#ifdef USE_TIMER2&lt;br /&gt;
ISR(TIMER2_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  if (timer2_toggle_count != 0)&lt;br /&gt;
  {&lt;br /&gt;
    // toggle the pin&lt;br /&gt;
    *timer2_pin_port ^= timer2_pin_mask;&lt;br /&gt;
&lt;br /&gt;
    if (timer2_toggle_count &amp;gt; 0)&lt;br /&gt;
      timer2_toggle_count--;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    // need to call noTone() so that the tone_pins[] entry is reset, so the&lt;br /&gt;
    // timer gets initialized next time we call tone().&lt;br /&gt;
    // XXX: this assumes timer 2 is always the first one used.&lt;br /&gt;
    noTone(tone_pins[0]);&lt;br /&gt;
//    disableTimer(2);&lt;br /&gt;
//    *timer2_pin_port &amp;amp;= ~(timer2_pin_mask);  // keep pin low after stop&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#ifdef USE_TIMER3&lt;br /&gt;
ISR(TIMER3_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (timer3_toggle_count != 0)&lt;br /&gt;
  {&lt;br /&gt;
    // toggle the pin&lt;br /&gt;
    *timer3_pin_port ^= timer3_pin_mask;&lt;br /&gt;
&lt;br /&gt;
    if (timer3_toggle_count &amp;gt; 0)&lt;br /&gt;
      timer3_toggle_count--;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    disableTimer(3);&lt;br /&gt;
    *timer3_pin_port &amp;amp;= ~(timer3_pin_mask);  // keep pin low after stop&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#ifdef USE_TIMER4&lt;br /&gt;
ISR(TIMER4_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (timer4_toggle_count != 0)&lt;br /&gt;
  {&lt;br /&gt;
    // toggle the pin&lt;br /&gt;
    *timer4_pin_port ^= timer4_pin_mask;&lt;br /&gt;
&lt;br /&gt;
    if (timer4_toggle_count &amp;gt; 0)&lt;br /&gt;
      timer4_toggle_count--;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    disableTimer(4);&lt;br /&gt;
    *timer4_pin_port &amp;amp;= ~(timer4_pin_mask);  // keep pin low after stop&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#ifdef USE_TIMER5&lt;br /&gt;
ISR(TIMER5_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (timer5_toggle_count != 0)&lt;br /&gt;
  {&lt;br /&gt;
    // toggle the pin&lt;br /&gt;
    *timer5_pin_port ^= timer5_pin_mask;&lt;br /&gt;
&lt;br /&gt;
    if (timer5_toggle_count &amp;gt; 0)&lt;br /&gt;
      timer5_toggle_count--;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    disableTimer(5);&lt;br /&gt;
    *timer5_pin_port &amp;amp;= ~(timer5_pin_mask);  // keep pin low after stop&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>YWrobot CYB</name></author>	</entry>

	</feed>