SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By speakstrange
#33117
Hi need some help I am trying to get PWM working using fast PWM on the ATMEGA128. I have had so many problems!! I have got to the point where I can generate a 1ms pulse but it will only pulse once. It appears to reset the timer at the TOP ICRn and the pulse is the same as what is in the OCR1A register however when the counter resets the pin does not go high again. Any ideas?????
Code: Select all
# include <avr/io.h>
#include <avr/interrupt.h>

void init_servo(void) 
{ 

/* Reset Control Register*/ 
	TCCR1B = 0x00;

/* Set Output Register*/
	DDRB=0xFF;

/*Reset Counter*/
	TCNT1H = 0;
	TCNT1L = 0;

/*Set TOP to 40000 for 20ms period*/
	ICR1H = 40000U >> 8;
	ICR1L = 40000U & 0xff;

/*	
	Enable 2 PWM ports */

	TCCR1A = 0x52; 


/*	Prescaler of 8
  	ICR1 = overflow value
	Fast PWM,mode 14(WGM13 & WGM12 HIGH) */	

	TCCR1B = 0x1A;//start timer

}

void set_servo_A(unsigned value)
{
  OCR1AH = value >> 8;
  OCR1AL = value & 0xff;

}


void main(void) 
{ 
	init_servo(); 
	set_servo_A(2000); //-90 degrees
	for(;;)
	{
	}
} 
By wiml
#33232
Are you setting the COM bits correctly? It looks like for WGM=14, then COMnn=(0,1) doesn't do anything useful. Probably you want COMnn=(1,0) or (1,1) — try setting TCCR1A to 0xA2 or 0xF2?
By speakstrange
#33234
Hi,
Since the previous post I had changed the value of TCCR1A to 0xa2. From my understanding this should give me a high pulse for 1ms(as I have set it) and low for the remainder, loop at the top and go high when it reaches the bottom.

It does not go high when first started , I can set the port to high and it will go low when it reaches the compare value (OCRn) but when it loops at TOP it stays low. Ive tried so many combinations to get this to work, im at a loss!
By Lajon
#33260
It works for me with
Code: Select all
   TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
(same as TCCR1A = 0xA2);
How do you test this?

Also, with avr-gcc you do not need to write the 16-bit registers like so:
Code: Select all
  OCR1AH = value >> 8; 
  OCR1AL = value & 0xff; 
just use
Code: Select all
  OCR1A = value; 
/Lars
By speakstrange
#33290
I tested this using AVR studio. The only thing I can think of is that it is an error with the simulator.

I noticed that with the ATMEGA128 the adressing bits were the same as other I/O ports. When I contacted atmel seems they had a error with the file for that chip. Anyway they released the temp fix and I installed that but still no change.

It just seems odd to me that it would do one pulse but never any more..... This is proving quite challlenging for me.. I only started programming three weeks ago and I have run into so many problems!
By Lajon
#33421
I would not trust the simulator for testing this, look at the known issues:
16-bit Timer/Counters on all devices have several problems with PWM, prescaler and output compare. Output compare registers are not buffered properly.
The "known issues" list is available in the AVR Studio help.
/Lars
By mlu
#33435
Try:
TCCR1A = 0xA2;
By speakstrange
#33440
Yeah thanks - have already tried tcr1a = 0xA2; .. i will attempt to find a cro to test the pulse on the board!

thanks for the help, ill let you know what happens!
By speakstrange
#33461
Yes it worked! Last time I trust the simulator ! Thanks guys