ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine
{
digitalWrite(ledPin, digitalRead(ledPin) ^ 1); // toggle LED pin
}
void loop()
{
// your program here...
}
Basically is working, but after some periods register making false period, and again counting normal.
Maybe somebody has made the same? Maybe my code is wrong?
For one, there is no need to use interrupts. The timer can generate a continuous stream of pulses on an output pin, completely independent of what the processor is doing (e.g. PWM).
Since there are other interrupts (like Timer0) operating, one of those could delay your Timer1 ISR.
You are using just about the slowest possible way of toggling a pin. To toggle digital pin 13 on a Uno (PORTB, pin 5), use the single instruction
PINB ^= (1<<5); //yes, use PINB to toggle *output* pin PB5
As always, see the processor data sheet for the details and explanation.
The Timer1 section of the ATMega328 data sheet has the details. Carefully read the section on the control registers, in particular TCCR1A has bits that determine how the timer controls the OC1A and OC1B port pins.
In one setting, the timer will toggle the port pin when a compare match occurs. The pin must be set to output to see the result.
Just changed togling pin command to : PINB=(1<<5); but this not solve problem. Probably there is cause of interrupts. Interesting that pulse tremor is depended on prescaler. If prescaler is 1 tremor very big, more then one period, if prescaler is 64 ,tremor about 1/10 of period.
I will change toggling. But how to avoid others registers interrupting? Can you pass code for code generation without interrupts?
TIMSK0 = 0;
will turn off timer0 which is the only interrupts that are on by default on the Uno or Mega (unless
you use Serial). However turning off timer0 stops millis(), delay() and micros() from working...
Use a relevant output compare pin for the timer you are using to output directly for jitter-free signal.
May you explain "Use a relevant output compare pin for the timer you are using to output directly" ?
Im beginner in Arduino and for me is difficult to understand.
May you explain "Use a relevant output compare pin for the timer you are using to output directly" ?
Im beginner in Arduino and for me is difficult to understand.
Then you'll have to read the section in the datasheet about the timer in question under you understand,
because that's what I had to do when starting out on direct timer manipulation. But in short this
is how analogWrite() works. Each timer has several output-compare registers each attached to a given
pin which is compared with the timer count and determines if the pin should be high or low. This is all
configured by various fields in the timer registers.
Amazing! Problem partially solved. Have 2 frequency generator made on Timer 1, and Timer 2, without interrupts. No disturbing processor work.
Code :
void startGenerator()
{
TCCR2A = _BV(COM2A0) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(WGM22) | _BV(CS20)|_BV(CS21)|_BV(CS22);
OCR2A = 255; // 250, so timer2 counts from 0 to 250 (251 cycles at 16 MHz)
TCCR1A = _BV(COM1A0); //toggle OC1A on compare mach (connected to pin 9)
TCCR1B = _BV(WGM12) |_BV(CS12); //set prescaler to 256, and set timer 1 to CTC mode (clear timer on compare mach),
// Comparing with OCR1A
OCR1A = 62500;
}