[RESOLVED] - ATtiny85 - error in PLL for high speed PWM

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

Hello :D

I am doing a small dc-dc booster for bike white leds. I am using ATtiny85 for that. Actualy I can't make PWM working. I did read the AVR131-Using_the_AVRs_High_-_speed_PWM.pdf and the datasheet of the ATtiny85... I can't figure out what I am doing wrong... but I saw on osciloscope the MCU stoping from working, maybe stoping oscilating his main clock, I don't know. What I am doing wrong... thank you.

/* Configure PWM  -- feq. 125KHz */
	PLLCSR |= ((1<<PLLE) | (1<<LSM)); /* Enable PLL and Low Speed Mode peripheral clock -> 32MHz */
       {
			unsigned char counter;
			/* Wait at least 100 us for PLL to stabilize */
			for(counter = 0; counter < 250; counter++)
			{
				asm("nop"); /* Each NOP should take 500 ns -- MCU Clock at 2MHz */
			}
		}
	while(bit_is_set(PLLCSR,PLOCK)) ; /* Wait for PLL to lock (approx. 100ms) */
	PLLCSR |= (1<<PCKE); /* Set PLL as PWM clock source */
	TCCR1 |= ((1<<COM1A0) | (1<<PWM1A)); /* Set PWM mode: toggle OC1A on compare */
	TCCR1 |= ((1<<CS10) | (1<<CTC1)); /* Clear Timer/Counter on Compare Match and */
	/* select Timer/Counter1 Prescale of PCK -> 32MHz */

JPCasainho,
www.Casainho.net
.Portugal

Last Edited: Tue. Feb 26, 2008 - 02:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

unsigned char counter;
/* Wait at least 100 us for PLL to stabilize */
for(counter = 0; counter < 250; counter++)
{
    asm("nop"); /* Each NOP should take 500 ns -- MCU Clock at 2MHz */
}

Better use _delay_us (100); instead. See avr-libc-manual for details.

Quote:

while(bit_is_set(PLLCSR,PLOCK)) ; /* Wait for PLL to lock (approx. 100ms) */

Shouldn't this be while(bit_is_clear(PLLCSR,PLOCK));?

Regards
Sebastian

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

S-Sohn wrote:
Quote:

unsigned char counter;
/* Wait at least 100 us for PLL to stabilize */
for(counter = 0; counter < 250; counter++)
{
    asm("nop"); /* Each NOP should take 500 ns -- MCU Clock at 2MHz */
}

Better use _delay_us (100); instead. See avr-libc-manual for details.

Quote:

while(bit_is_set(PLLCSR,PLOCK)) ; /* Wait for PLL to lock (approx. 100ms) */

Shouldn't this be while(bit_is_clear(PLLCSR,PLOCK));

Regards
Sebastian

Thank you :)

1st: I prefer to use NOP instructions, I remember to program that way in assembly. I think _delay_us depends on optimization on compilation time, so, I prefer to do the way I know that It will work :) - I will share this work so I would like to have a code that is not much dependent on others variables, like that switches on compilation.

2nd: You are right :) - my mistake.
PLOCK: PLL Lock Detector
When the PLOCK bit is set, the PLL is locked to the reference clock. The PLOCK bit should be
ignored during initial PLL lock-in sequence when PLL frequency overshoots and undershoots,
before reaching steady state. The steady state is obtained within 100 μs. After PLL lock-in it is
recommended to check the PLOCK bit before enabling PCK for Timer/Counter1.

However It still dos not work. If I comment this last 2 lines:

	TCCR1 |= ((1<<COM1A0) | (1<<PWM1A)); /* Set PWM mode: toggle OC1A on compare */
//	TCCR1 |= ((1<<CS10) | (1<<CTC1)); /* Clear Timer/Counter on Compare Match and */

It works but when I uncomment that 1st line, It will not work...

But I can see clock signal output at pin PB4, as programed in fuses.

JPCasainho,
www.Casainho.net
.Portugal

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

Quote:
I prefer to use NOP instructions, I remember to program that way in assembly. I think _delay_us depends on optimization on compilation time, so, I prefer to do the way I know that It will work
True, the delay functions only work with optimization swiched on. But why would anyone completely switch off optimization? Btw. your code is optimization dependant, too. And it is always much longer than your aimed 100µs. Is that really so much better?
Edit: Or even much shorter because the optimizer might optimize your optimal code away.

I never used an ATtiny85 for PWM generation but it looks like you need to set the data direction register to output for the OC1A pin. in addition OCR1C is used as top value and OCR1A is used to define the duty cycle of the PWm signal. I can't see that you have initialized these registers. I'm not sure if you need to set the CTC1 bit if PWM1A is set, too.

Regards
Sebastian

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

HAPPY, happy, most part of my DC-DC already works ;-)

I was configuring wrong the PWM, here is the code that is working:

	/* Configure PWM  -- feq. 125KHz */
	PLLCSR |= ((1<<PLLE) | (1<<LSM)); /* Enable PLL and Low Speed Mode peripheral clock -> 32MHz */
    {
		unsigned char counter;
		
		/* Wait at least 100 us for PLL to stabilize */
		for(counter = 0; counter < 250; counter++)
		{
			asm("nop"); /* Each NOP should take 500 ns -- MCU Clock at 2MHz */
		}
	}
	while(bit_is_clear(PLLCSR,PLOCK)) ; /* Wait for PLL to lock (approx. 100ms) */
	PLLCSR |= (1<<PCKE); /* Set PLL as PWM clock source */
	OCR1C = 255; /* TOP value -- PWM with 256 bits of resolution */
	TCCR1 |= ((1<<PWM1A) | (1<<COM1A1) | (1<<CS10)); /* PWM1A: Pulse Width Modulator A Enable */
		/* OC1x cleared on compare match. Set when TCNT1 = $00. OC1x not connected and */
		/* Asynchronous Clocking Mode - PCK */
/******************************************************************************/
/* Set the desired value of the duty_cycle on the PWM signal.                 */
/* duty_cycle_value with 255 equals to 100%.                                  */
/******************************************************************************/
void set_duty_cycle_value(unsigned char duty_cycle_value)
{
	/* Limit duty_cycle_value for safe function of the system */
	if(duty_cycle_value >= ((255*MAX_DUTY_CYCLE_VALUE)/100))
	{
		duty_cycle_value = ((255*MAX_DUTY_CYCLE_VALUE)/100);
	}

	/* Output the duty_cycle_value to the respective control register */
	OCR1A = duty_cycle_value;
}

Thank you for help, many thanks S-Sohn :-) :-) :-).

JPCasainho,
www.Casainho.net
.Portugal

Last Edited: Tue. Feb 26, 2008 - 02:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

255 bits of resolution? :D 256 values==8 bits ;)

Great that it works now... I made a four output flyback converter with a tiny25 ;)

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

jayjay1974 wrote:
255 bits of resolution? :D 256 values==8 bits ;)

Great that it works now... I made a four output flyback converter with a tiny25 ;)

I will rectify, edit that code!! Thank you :D

JPCasainho,
www.Casainho.net
.Portugal