Catégories
Liens
Arduino UNO :
Arduino MEGA :
Sur une Mega, chaque Tone simultané utilisera les timers dans cet ordre : 2, 3, 4, 5, 1, 0 (source)
Arduino Leonardo (no Timer 2!) : http://provideyourown.com/2012/arduino-leonardo-versus-uno-whats-new/ The Leonardo has 7 PWM pins instead of 6. ATmega32U4 also has a new timer, timer4 which has 10 bits and uses a PLL to count at 64MHz. Their mappings are different as well:
Tone et Leonardo problem :https://code.google.com/p/rogue-code/issues/detail?id=13
TCCR0B = TCCR0B & 0b11111000 | <setting>; //Timer 0 (PWM pins 5 & 6) TCCR1B = TCCR1B & 0b11111000 | <setting>; //Timer 1 (PWM pins 9 & 10) TCCR2B = TCCR2B & 0b11111000 | <setting>; //Timer 2 (PWM pins 3 & 11)
setting | 5 & 6 | 3,11 & 9,10 |
0x01 | 62500 | 31250 |
0x02 | 7812 | 3906 |
0x03 | 976 | 488 |
0x04 | 244 | 122 |
0x05 | 61 | 30 |
When you use analogOut() to create pulsewidth modulation (PWM) on an output pin, you can change the on-off ratio of the output (also known as the duty cycle) but not the frequency. If you have a speaker connected to an output pin running analogOut(), you'll get a changing loudness, but a constant tone. To change the tone, you need to change the frequency. The tone() command does this for you.
tone() function uses at least timer2. You can’t use PWM on Pin 3,11 when you use the tone() function an Arduino and Pin 9,10 on Arduino Mega.
If you used a 16 bit timer (e.g. timer 1, or timers 3,4,5 on '1280), you could generate “tones” down to 1/8 Hz (one cycle every 8 seconds), although the library only accepts integers for frequency.
After all is said and done, because play() only accepts unsigned integers for frequency, the maximum frequency that can be produced is 65535 Hz - which, after rounding, results in a 65573.77 Hz “tone” on a 16 MHz part. Even if play accepted larger values for frequency, you couldn't achieve better than around 80KHz with the Tone library because the pin toggling is done in software. Each toggle, in software, requires AT LEAST 50+ cycles.
Chaque Timer controle deux sorties PWM.
Since all PWM channels, via the same timer, share the same waveform generator then the only thing that dfferentiates each channel is the 'comparator' value. All timers have associated with them three registers, TOP, BOTTOM and MAX
Par exemple, : analogWrite(pin, 128); Outputs a square wave
is compared against the value in an 8-bit counter. When the counter is less than the PWM value, the pin outputs a HIGH; when the counter is greater than the PWM value, the pin outputs a LOW. In the example above, a square wave is generate because the pin is HIGH from counts 0 to 127, and LOW from counts 128 to 255, so it is HIGH for the same amount of time it is LOW.
C'est pourquoi on ne peut dépasser 255 !
This is useful in many power regulating circuits, or in circuits where small inductive or capacitive components are used. Atmega328 microcontroller is able to generate two types of fast PWM. In one mode Counter counts from 0 to 255 and in second mode counter counts from 0 to value stored in OCR0A.
The Timer/Counter Control Registers hold several bit groups. These are:
system clock is 16MHz Il s’agit en fait de diviser l’horloge du timer : il s’agit de l’horloge des entrées/sorties (ou I/O clock) et pas de l’horloge système qui est à la fréquence du quartz, soit 16 MHz.
For pins 6 and 5 (OC0A and OC0B): For pins 9, 10, 11 and 3 (OC1A, OC1B, OC2A, OC2B):
TCCR2B = TCCR2B & 0b11111000 | 0x01 ;
Période minimale : 1 / 16 000 000 = 0,000000062 = 6,2 ns
Target Timer Count = (Input Frequency / (Prescaler * Target Frequency)) - 1
Target Timer Count = (16000000 / 1) -1
Those familiar with C will know that an unsigned eight bit value can store a value from 0 to 28 − 1, or 255, before running out of bits to use and becoming zero again. Similarly, an unsigned 16 bit value may store a value from 0 to 216 − 1, or 65535 before doing the same.
// Réglage de la fréquence PWM du Timer 1 // vu sur : https://github.com/pololu/zumo-shield/blob/master/ZumoMotors/ZumoMotors.cpp int mypwm = 200; // réglage de test avec max = 400 ici void setup() { // PWM frequency calculation // 16MHz / 1 (prescaler) / 2 (phase-correct) / 400 (top) = 20kHz TCCR1A = 0b10100000; TCCR1B = 0b00010001; ICR1 = 400; // max } void loop() { OCR1B = mypwm; // 0-400 }
The program running on a controller is normally running sequentially instruction by instruction. An interrupt is an external event that interrupts the running program and runs a special interrupt service routine (ISR). After the ISR has been finished, the running program is continued with the next instruction. Instruction means a single machine instruction, not a line of C or C++ code.
Before a pending interrupt will be able to call a ISR the following conditions must be true:
Interrupts must be generally enabled the according Interrupt mask must be enabled
Interrupts can generally (globally) enabled / disabled with the function interrupts() / noInterrupts(). By default in the Arduino firmware interrupts are enabled. Interrupt masks are enabled / disabled by setting / clearing bits in the Interrupt mask register (TIMSKx).
When an interrupt occurs, a flag in the interrupt flag register (TIFRx) is been set. This interrupt will be automatically cleared when entering the ISR or by manually clearing the bit in the interrupt flag register.
The Arduino functions attachInterrupt() and detachInterrupt() can only be used for external interrupt pins. These are different interrupt sources, not discussed here.