0
\$\begingroup\$

I need a 13 microseconds delay for transmitting IR at a 38 kHz carrier wave. My chip (ATtiny84) is running at 8 MHz. I cannot figure out what's the problem is in my code:

void send(long microsecs)
{
 TCCR0B |= (1 << CS00); // Enable Timer 0 - No prescale
 while (microsecs > 0)
 {
 // 38 kHz is about 13 microseconds high and 13 microseconds low
 PORTB |= (1 << PB2); // 3 μs
 TCNT0 = 0;
 while (TCNT0 < 104);
 PORTB &= ~(1 << PB2); // 3 μs
 TCNT0 = 0;
 while (TCNT0 < 104);
 // So 26 microseconds altogether
 microsecs -= 26;
 }
}

The delay (104 clock cycles) sums up to 13 microseconds @8 MHz and the while loop should hang up the code for the required time period, but it's not working.

But

When I replace this:

 TCNT0 = 0;
 while (TCNT0 < 104);

by this:

_delay_us(13);

everything works fine.

If I'm doing something wrong, please point out.

Peter Mortensen
1,6973 gold badges17 silver badges23 bronze badges
asked Sep 22, 2015 at 16:37
\$\endgroup\$
13
  • 2
    \$\begingroup\$ What exactly is the problem? The output is always high/low/tri-state? What? Also, these timing things are best done with timers. Google for "AVR timer tutorial" or similar. As it is far more accurate way than timing it with delays, and also ables you do execute any other code while timming. \$\endgroup\$ Commented Sep 22, 2015 at 16:57
  • \$\begingroup\$ It seems that the code is stuck at <while(TCNT0 < 104);> \$\endgroup\$ Commented Sep 22, 2015 at 17:06
  • \$\begingroup\$ Is the watchdog enabled???? \$\endgroup\$ Commented Sep 22, 2015 at 17:08
  • 1
    \$\begingroup\$ And, why do you think it stucks in the while(TCNT0 < 104);? Also, how do you decide/check if it is working properly or not? And how much frequency error is permitted? \$\endgroup\$ Commented Sep 22, 2015 at 22:22
  • 1
    \$\begingroup\$ @BenceKaulics, from the datasheet atmel.com/Images/doc8006.pdf page 32: "The device is shipped with the CKDIV8 Fuse programmed". It is mean that CLKPS bits are reset to "0011" ~ clock division factor is 8. If we desire the clock division factor 1, we need to set CLKPS to "0000" \$\endgroup\$ Commented Sep 23, 2015 at 8:52

1 Answer 1

1
\$\begingroup\$

You are not updating PB2, you set it high in the 1st delay and then you set it high again in the second delay, switch from PORTB |= (1 << PB2); to PORTB &= ~(1 << PB2); in one of the delays

answered Sep 22, 2015 at 16:47
\$\endgroup\$
1
  • \$\begingroup\$ Sorry, I edited the code. Just a problem while copying from the editor to here. I was using PORTB &= ~(1 << PB2); \$\endgroup\$ Commented Sep 22, 2015 at 16:50

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.