Strange Timer1 problem

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

I'm using a knock-off ATMega2560 and I've got a real head scratcher.
I believe what I'm trying to do is correct but I've been working on it a couple of hours and it's not doing what I think it should maybe I'm missing something. Below is a portion of a very simple program to drive a Dagu motor control board where there is a pin for direction and one for pwm.

What it's doing is when I think it should be stopping the timer I'm still getting the PWM at the output. Unless I manipulate the value in OCR1A the PWM port outputs a frequency of 1KHz no matter what I do to the prescale value.

Any help appreciated

int main(void)
{
InitPWM();
	
    while(1)
    {
		Start();
        PORTB |= _BV(CH1_DIR);
		_delay_ms(1000);
		Stop();
		_delay_ms(5000);
		Start();
		PORTB &= ~_BV(CH1_DIR);
		_delay_ms(1000); 
		Stop();
		_delay_ms(5000);
    }
}

void InitPWM()
{
	DDRB = _BV(CH1_DIR) | _BV(CH1_PWM);
	
	TCNT1 = 0;
	TCCR1A = _BV(COM1A1);
	TCCR1B = _BV(WGM13);
	ICR1 = 1000;
	OCR1A = 500;
}

void Start()
{
//	TCCR1B |= _BV(CS11);
        //By resetting it puts it back to 50% duty
	OCR1A = 500;
}

void Stop()
{
        //This shuts down the PWM 
	OCR1A = 0;
        //Setting the prescaler to 0 doesn't work
//	TCCR1B &= ~_BV(CS11);
	PORTB &= ~_BV(CH1_PWM);	
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to shut down the clock to the timer not just reset the compare register. ie clear all 3 bits to be sure CS12 CS11 CS10

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:
You need to shut down the clock to the timer not just reset the compare register. ie clear all 3 bits to be sure CS12 CS11 CS10

Thanks for the response, I also tried that with same results.
I'm sure I've done this before but using a different board, I believe an ATMega1280 but should be the same?

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

This is from a project using the 1280, should be the same for the 2560

void local_pwm1_on ()
{
	Local_PWM1_DDR |= (1<<Local_PWM1_pin);		//Make pin output
	TCCR1A=(1<<COM1A1 | 1<<COM1A0 | 1<<WGM11 | 1<<WGM10);	//PWM, Phase Correct, 10-bit
	TCCR1B=(1<<CS10);							//enable Timer 1 with no prescaler
	local_pwm1_flag=1;
	OCR1A = brightness_PWM1;					//OCR1A for pb1
}

void local_pwm1_off ()
{
	Local_PWM1_port |= (1<<Local_PWM1_pin);	
	TCCR1A=0;
	TCCR1B=0;
	local_pwm1_flag=0;
}

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js,

Thanks so much for your help, I'm really embarrassed I found what was wrong but I have to do a little further investigation to find out why it was doing it.

I have a Extech meter that has a frequency meter built in that I was using for testing the frequency.
I pulled your code in line for line and it still did the same thing, tried different timers and modes with no luck. So I changed the code back to what I started with and pulled out my DSO and looked and sure enough it is doing as I thought it should all along but it's inverted so all I have to do is set the compare mode correctly and I'm set. But I don't know why my meter was showing there was frequency when it was actually a high?

Anyway tickled to get it figured out...much obliged!