1
\$\begingroup\$

I am using AVR128A for a project. It comes with two 16-bit timers (Timer 1 and Timer 3) and two 8-bit timers (Timer 0 and 2). Timer 1 has two channels whereas Timer 3 has three.

I have all the timers in use as of now:

  • Timer 1 (channel A) is used to count for the ultrasonic sensor.
  • Timer 3 (channel A) is used with the servo.
  • Timer 1 is used for the buzzer.
  • Timer 0 is being used to make a delay of around 3 seconds for the delay between the servo.

As my main has quite some interrupts, both external and timer overflow, I needed to make another delay of around 30 microseconds. Using the _delay_us(30) is making the servo and other interrupt based components to not react properly. I also wanted to create another delay of 500 milliseconds using Timer 3 channel B. I tried doing this but configuring timer of one channel is affecting another.

So my question is, can I use, let's say Timer 1 channel B to make a delay of 30 microseconds despite Timer 1 already being in use through channel A? Can I do the same with channel 3?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Usually a timer has one counter register. If you use it as a timer and not as a pulse counter, the counter will count from 0 to the maximum value you set. If you set it to repeat, this sets the period.

However it has several compare registers so one timer can generate several different PWM signals as long as the period is the same.

Even if you use some channels for PWM, you can still use the others for more stuff.

Timer 3(channel A) is used with the servo.

Since your servo probably uses low frequency PWM like 50-200Hz, this means it has an overflow interrupt at the same frequency which you can use to keep track of time by incrementing a "milliclock" variable. Therefore you don't need Timer0 to make the 3 second delay, all you have to do is either check the counter in a loop, or check it at the end of the timer interrupt that increments it.

I also wanted to create another delay of 500 milliseconds using Timer 3 channel B.

If this timer resets at the servo PWM frequency, say 50Hz, it has a period of 20ms. So you could use it to make a delay of less than 20ms, by taking the current counter value, calculating what the counter value will be at the end of the delay (accounting for wraparound), and then set the compare register on channel B to trigger an interrupt when the counter reaches this value. Or just read the timer value in a loop.

But you can't use it directly for a delay longer than the timer period.

500ms or 3s delay doesn't need to be accurate, so you can just use the clock counter mentioned above.

can I use, let's say Timer 1 channel B to make a delay of 30 microseconds despite Timer 1 already being in use through channel A?

Yes, you can use any available compare unit in any timer to make a delay as long as it is shorter than the period of that timer. Also since your timer is in use you can't change the clock frequency, and that sets the granularity of your delay. Suppose your timer has a 20ms period (50Hz) and it's 16 bit, you're probably going to have a clock around 3 MHz so the full period of 20ms corresponds to near the maximum of a 16 bit counter. That clock is fast enough for a 30µs delay.

However if some interrupts trigger while your code is waiting for that delay to expire, then it will have to wait until the interrupt returns, so the delay may be longer than 30µs, potentially up to 30µs + the longest interrupts that can execute.

Using the _delay_us(30) is making the servo and other interrupt based components to not react properly.

There's no reason why that should happen: delay_us just executes instructions in a loop and does nothing to interrupts, unless you disabled them. If you put a delay in an interrupt, that's usually a bad idea.

If you're out of timers there are other ways to trigger an interrupt after a delay, for example using one of the UARTs to send some data and raising an interrupt when it's done. You can set the delay with baud rate and number of bytes in the FIFO...

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.