AVR atmega8 problem :(

Status
Not open for further replies.

seta45

New Member
Hi there,

I want to generate a square wave with certain frequency but the output frequency is smaller by a factor of 10 than what I expected.
To test it out I make this code. I use the internal 4Mhz clock (I also checked it with my 4 Mhz crystal). I expect to get a 1 Mhz wave out (since I counted to 3), but I only get 100 kHz.

#include <avr/io.h>
#define F_CPU 4000000UL
// initialize timer, interrupt and variable
void timer1_init()
{
TCCR1B |= (1 << WGM12)|(1 << CS10);
// initialize counter
TCNT1 = 0;
// initialize compare value
OCR1A = 3;
}
int main(void)
{
// connect led to pin PC0
DDRC |= (1 << 0);
timer1_init(); // initialize timer

while(1) // loop forever
{
if (TIFR & (1 << OCF1A))
{
PORTC ^= (1 << 0); // toggles the led
}
// clear flag bit by writing '1' to it (as per the datasheet)
TIFR |= (1 << OCF1A);
}
}

-----------------------------------------------------------------------------------------------------
I also made this code, hoping to get the 4 Mhz out, but only get 400 kHz.

#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 4000000UL
int main(void)
{
// connect led to pin PC0
DDRC |= (1 << 0);
while(1) // loop forever
{
PORTC ^= (1 << 0); // toggles the led
}
}

I use AVR studio 4 btw. I use a oscilloscope to measure the output wave. I also checked the code in Proteus.
I think I got the fuse bits right. When I use the second code with a 8 Mhz internal clock, I got 800 kHz out.
Please help me point out what I did wrong.
 
Last edited:
I'm not shure, but i guess the internal Clock only runs at 8Mhz.
When the CKDIV 8 Fuse is set the internal Clock was divided by 8 and the Controller runs at 1Mhz.
When you want to use other frequencies, you had to use an external Clock source ( R/C, Crystal, Ceramic ord Crystal Oszillator ) .
The maximum symetric output frequency at 8MHz is 4Mhz, because the Output toggels at every comparematch and that gives 4Mhz.
 
Thanks for the reply wkrug.
Even though I chose 8 Mhz, when I compile the second code, I only gets 800 kHz. Also, I tested it with a 4Mhz crystal and the output is 400 kHz. They seems to be scaled by 10 or something. I wonder if it has anything to do with the AVR studio or any invisible setting when I compile the program.
 
Why don't you use the Compare Output Mode with the timer? The C-compiler creates so much overhead that you have no chance getting close to 1 Mhz with software waveform generator. If you want to do that in software, use assembly.

EDIT: Sorry, I misread your code. Actually you are almost doing the right thing, but your settings are wrong. You are running the timer/counter in CTC mode, so OCR1A sets the TOP value and then you can use OCR1B as a compare value to generate the square wave. Take a look at page 97, table 39 in this datasheet: https://www.electro-tech-online.com/custompdfs/2012/05/doc2486.pdf
 
Last edited:
Hi misterT,
I am sorry but I still don't understand. As I understood, OCR1A set the top value, and the TCNT1 will be incremented until it is equal OCR1A. I don't know how to use OCR1B in this one. Sorry if I misunderstood something, as I am very new to AVR.
 

When you use CTC mode (Clear Timer on Compare Match, page 87 on the datasheet), OCR1A sets the frequency and OCR1B sets the duty cycle.. You should get the signal out from pin PB2. Take some time to read the datasheet (the part about timer/counter1 and its register description and modes of operation). I will help you more when I have more time. Now I'm on my way for beer an billiards
 
Last edited:
This code use CTC mode to generate a 2MHz pulse on PORTD.5
Code:
#include <avr/io.h>

int main(void) {
	DDRD	= (1 << 5);
	TCCR1A	= (1 << COM1A0);
//	OCR1A	= 0;
	TCCR1B	= (1 << WGM12) | (1 << CS10);	

	for(;;);
}
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…