0
\$\begingroup\$

I'm trying to get a Timer0 overflow with an overflow every 500us, but can't find a solution to get it so low.

I'm running the Attiny85 on its internal 1 MHz clock, so I know it is not gonna be the most precise thing. Right now the lowest overflow I can achieve is 2 ms.

In my setup, the Timer0 starts counting when a pin change happens on PCINT0 and stops after 4 counts. Timer0 is setup up to CTC and with the prescaler to 1024.

I set the value of OCR0A with SERIAL_BIT_TIME

The code I'm trying is here

#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


#define SERIAL_SEND PB1
#define SERIAL_RECEIVE PB0
#define SERIAL_RATE 9600

#define SERIAL_BIT_TIME 0x01

int main() {
    DDRB |= 1 << PB1;
    DDRB &= ~(1 << PB0);
    
    //PORTB |= 1 << PB1;
    
     TCCR0A |= 1 << WGM01; // clear on compare
     TCCR0B |= (1 << CS02) | (1 << CS00); // ( F_CPU/1024 = 976 Hz )

    GIMSK = 1 << PCIE; // general intertupt mask enable pin change int
    PCMSK |= 1 << PCINT0; // Pin change mask
    sei(); // set interrupt enabled
    while(1); // Do a heap of useful calculations
}
uint8_t position = 0;

ISR(TIM0_COMPA_vect) { // Timer interrupt
    PORTB ^= (1 << PB1);
    if (++position == 4) { // If at end of byte
        TIMSK &= ~(1 << OCIE0A); // Disable interrupt for compare register A (this interrupt)
        PCMSK |= 1 << SERIAL_RECEIVE; // Enable pin change interrupt to start next byte
        } else {
        OCR0A = SERIAL_BIT_TIME; // Set delay time equal to the length of a single bit
    }   
}

  ISR(PCINT0_vect) {
      TCNT0 = 0; // Set counter to 0
      OCR0A = SERIAL_BIT_TIME; // Call timer interrupt in middle of first bit
      position = 0; // Reset position and data
      TIMSK |= 1 << OCIE0A; // Enable interrupt for compare register A (timer interrupt)
      TIFR |= 1 << OCF0A; // Clear timer interrupt flag to prevent it jumping directly there
      PCMSK &= ~(1 << SERIAL_RECEIVE); // Disable pin change interrupt
  }

And the result measured with my Analog Discovery 2:

Analog Discovery result

The yellow line is the pin that toggles in the overflow and the blue line is the output of a signal generator, used to change state of the input pin.

Any help or explanation would be lovely

New image with no prescaler

New image with no prescaler

As per request from @G36 here is the result when the prescaler is set to 8 and OCR0A to 61.

result with 8 prescaler and OCR0A = 61

With the suggestions, I got what I want. Thanks a lot guys.

\$\endgroup\$
9
  • \$\begingroup\$ If you want 500uS? So why did you decide to use 1024 as a prescaler? \$\endgroup\$
    – G36
    Nov 20, 2021 at 13:42
  • \$\begingroup\$ I think maybe I misunderstood the prescaler and thought "the higher the prescaler, the faster the delay" \$\endgroup\$
    – jonas
    Nov 20, 2021 at 13:44
  • 1
    \$\begingroup\$ No, wrong, set the Prescaler to 2 So that Timer0 clock is 1MHz/2 = 500kHz = 2us and you want 500us thus, set OCR0a to--->(500 us/2 us -1) = 249 because counter will count from 0. \$\endgroup\$
    – G36
    Nov 20, 2021 at 13:49
  • 1
    \$\begingroup\$ I haven't looked into the datasheet but now I see that is a 8-bit timer. So to get 500us we need to use a Prescaler (clock divider). So if we set the Prescaler value to 8 the counter clock frequency is 1MHz/8 = 125kHz and we want to get 1/500us = 2kHz. So we need to divide by 125KHz/2kHz = 62. So the OCR0A value is 62 - 1 = 61 because as I said we start the counting cycle from 0. \$\endgroup\$
    – G36
    Nov 20, 2021 at 15:11
  • 1
    \$\begingroup\$ Can you show us the resulting timing when OCR0A is set to 61 and prescaler is 8? \$\endgroup\$
    – G36
    Nov 20, 2021 at 16:52

1 Answer 1

2
\$\begingroup\$

An interrupt every 500us is a rate of 2 kHz. As you have only a limites set of prescalers available and the resolution of the timer is only 8 bits, you can't use it without prescaler, and the next prescaler is 8.

As the MCU works at 1 MHz, the timer will run at 125 kHz. Divide by 62 and it is approximately 2 kHz.

\$\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.