Tiny13 interrupt routine question

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello.
I am using the Tiny13 with the internal 4.8MHz oscillator. What I need is a 10mSec interrupt where I can check the state of an input pin.

I downloaded AVR Calc and I entered a timer for 10 msec and entered 4.8MHz as the oscillator. First, the registers I set for interrupts in the AVR are...

    /*****************************************
          Timer/Counter 0 initialization
    *****************************************/
    TCCR0A=0x00; // Clock source: System Clock
    TCCR0B=0x01; // Mode: Normal top=FFh
    TCNT0=0x00;  // Clock value: 4800.000 kHz
    OCR0A=0x00;  // OC0A output: Disconnected
    OCR0B=0x00;  // OC0B output: Disconnected

AVR Calc tells me to set the following registers:

OCR1AL = 0x80;
OCR1AH = 0xbb;

So I am assuming that I substitute TCCR0x registers? Or do I set OCR0A to 0x80 and OCR0B to 0xbb? I just need my ISR to be executed every 10mSec and I was hoping I am going about this the right way.

Thanks for any help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Timer 0 is an 8-bit timer for ATTiny13. Your compare value will need to be less than 256. So, increase your prescaler. If you use a prescaler of 256, then a compare value of 0xBC will be 10.023mSec (error -0.26%) according to kavrcalc

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cnewbie wrote:
So I am assuming that I substitute TCCR0x registers?
Oh my goodness, no. Please read the Tiny13 datasheet at look at the bit fields in TCCR0x that you need to correctly set for your timer to work correctly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

AVR Calc tells me to set the following registers:
Code:

OCR1AL = 0x80;
OCR1AH = 0xbb;

So I am assuming that I substitute TCCR0x registers? Or do I set OCR0A to 0x80 and OCR0B to 0xbb? I just need my ISR to be executed every 10mSec and I was hoping I am going about this the right way.

Not exactly, but a good start.

AVRCalc is giving the 16-bit values as would be used by a "timer1" in most AVR models. As the high byte is not 0, you cannot reach 10ms. with an 8-bit timer at that clock rate. Think about it--each clock tick is 208ns, and the 8-bit timer has up to 256 ticks, so the most it can count to is 53us.

But, you aren't lost yet. You use the timer prescaler to bring the value into range. with a /256 prescaler an OCR value less than 256 can be found to give a period of 10.026ms. -- probably close enough as the 4.8MHz isn't going to be any closer, anyway.

Now, AVRCalc gives an answer of 0xBB for this. You need to use one less: 0xBA since in the mode that you are going to use both 0 and the TOP value are counted.

Plugging that into the CodeVisionAVR Wizard, here is a fragment of the generated program. [it was easier just to post the whole program]

#include 

// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
// Place your code here

}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 18.750 kHz
// Mode: CTC top=OCR0A
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x02;
TCCR0B=0x04;
TCNT0=0x00;
OCR0A=0xBA;
OCR0B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x04;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here

      }
}

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the post, Lee. I see that I left out the correct calculation for CTC mode in kavrcalc. Also, I see that avrcalc rounds differently than kavrcalc. For the actual OCR value of 186.5, avrcalc rounds down and kavrcalc rounds up. Thanks for the off-by-1 correction and sparking the good idea for addition.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow. Thanks Lee. That is a lot to absorb, yet you explain things well and clear. I appreciate it! I hope this works.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Thanks for the post, Lee. I see that I left out the correct calculation for CTC mode in kavrcalc. Also, I see that avrcalc rounds differently than kavrcalc. For the actual OCR value of 186.5, avrcalc rounds down and kavrcalc rounds up. Thanks for the off-by-1 correction and sparking the good idea for addition.

After I read this, it gnawed at me a bit. Yes, AVRCalc is a simple tool. Yes, when using CTC you must subtract one from the value. When I reflected on this when I discovered the situation, I came to my [personal] conclusion is that it is not AVRCalc's "fault"/"bug", as there are different modes where the counter does not "double count". So you just have to realize when to make an adjustment.

Now, on to the rounding up/rounding down thing. There is something rotten here, as AVRCalc says that 0xBB gives a time of about 10.02xxx ms. No rounding involved. AFAIK AVRCalc has never given me a rotten number, and gives the timer count that gives the closest possible error to the given specs.

But you say that kavrcalc recommends 0xBC, with the same time period. Both of them cannot be correct. Running the numbers through the calculator it seems that AVRCalc is "off" on the displayed times when not exact, and then I see what you mean about the "rounding"--taking the solution on the other side of the ideal.

I hope that AVRCalc is giving me the corrent numbers for the "exact" matches! ;) [I believe that it is, as I've checked enough apps on the 'scope.]

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was looking more at the datasheet: fOCnx = fclk_IO / 2⋅N⋅(1 + OCRnx)
As best as I can tell, this is the same frequency for both the PWM output and the timer interrupt using the CTC mode. Do you agree or am I missing something.

kavrcalc, thus, has an off-by-one bug where I don't take in account the increment-by-one in the above formula. With that change, kavrcalc will report a value of 0xBB (187 decimal) which is a round-up from the precise value of 186.5. (kavrcalc uses Common Lisp's round function which is specified to round up for >= 0.5 fractions). For a value of 0xBB, the true period should be 9.9733ms. I'm not sure why avrcalc reports 10.02xxms for 0xBB unless there is some different mode where the timer count differs by 1.

Thanks for your help with this, Lee.