Frequency generation

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

I need to generate a frequency output that is adjustable between 380khz, 390khz, 400khz, and 410khz. I am using an ATTiny84 on an STK600 with a 16.384Mhz crystal and Atmel Studio 6 and WinAVR(I just upgraded from AS4 a few days ago).
I am using TIMER0 in normal mode with an overlow interupt in which I set my output pin and reload the TCNT0 register and a compare match interrupt in which I clear the pin. The interrupts are in a seperate asm file. I expected that I could step the frequency in 10k steps for each increment of the value loaded into TCNT0 but find that I need to change my reload value by 2 to see a change and that change is 20khz. Measuring the pin on the scope I get the following values. I'm hoping that someone can explain what I'm not seeing.

TCNT0 Freq
0xDE 371k
0xDF 371k
0xE0 390k
0xE1 390k
0xE2 410k
0xE3 410k

Here is my code

void port_init(void)
{
	//set output ports
	DDRA = (1<<PA5));
}

void timer_init (void)
{

	//TIMSK0 =(1<<TOIE0)|(1<<OCIE0A);
	TIMSK0 =(1<<TOIE0)|(1<<OCIE0A);
	TCCR0B = (1<<CS10);
	OCR0A = 0xf0;
}
int main(void)
{
	port_init();
	timer_init();
	sei();

    while(1)
    {
			
			
	}
	return 0;		
}
	

my asm file looks like this

 .global TIM0_OVF_vect

	TIM0_OVF_vect:
		sbi	_SFR_IO_ADDR(PORTA),5
		ldi	r25, 0xe3 
		out	0x32, r25	
                reti	

 .global TIM0_COMPA_vect

	TIM0_COMPA_vect:;
		cbi  _SFR_IO_ADDR(PORTA), 5
		reti

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

Why would you not use CTC mode with output toggle on compare? No interrupts needed.

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

I tried that initially but I couldn't get the required 10k frequency step size. Theoretically with this scheme values of TOP-38 through TOP-41 should give me the required frequencies. Since CTC toggles each time it matches I need to set the compare value in the range of 19-21 and as the period gets smaller the frequency steps increase.

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

With the response time of the interrupts, there is a minimum of about 10 clocks before the new start value for TCNT0 will be set, so your frequencies will be significantly off.

Why not use PWM mode?

OCR0A = top;
OCR0B = top/2;
TCCR0A = (1<<COM0B1) | (1<<WGM01) | (1<<WGM00);
TCCR0B = (1<<WGM02) | (1<<CS00);

Setting "top" to 42, 41, 40 or 39 will get you your 380, 390, 400 or 410kHz. Again, no interrupts required.

Regards,
Steve A.

The Board helps those that help themselves.

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

Steve,
Thanks, that works perfectly.