Go Down

Topic: ATtiny45 PWM Frequency Selection (Read 4549 times) previous topic - next topic

Coding Badly

So to be clear, I should change Prescale_Value_1 in your code below to 255 (255+1 = 256)?


No.  The "1" is the prescaler in the formula...

Frequency is F_CPU / ( 1 * (0xFF+1))

"(0xFF+1)" is the point the timer overflows (8 bit value).

Coding Badly

#16
Jan 27, 2013, 01:07 am Last Edit: Jan 27, 2013, 01:10 am by Coding Badly Reason: 1
How does the timer change affect the pin mapping?


Open the datasheet...
http://www.atmel.com/devices/attiny85.aspx?tab=documents

Navigate to the 1. Pin Configurations section.

Pins marked with OC (oh-see) are Output Compare (PWM capable) pins.  The number after OC is the timer.

If there is a line above the marking the output is inverted.  The Tiny Core does not make any use of inverted outputs.


If you're using timer 0, OC0A and OC0B are candidates (PB0 and PB1).  If you're using timer 1, OC1A and OC1B are candidates (PB1 and PB4).


This compile-time switch...

http://code.google.com/p/arduino-tiny/source/browse/trunk/hardware/tiny/cores/tiny/core_build_options.h#113

...determines which output (OC0B versus OC1A) the Tiny Core uses for PB1....

http://code.google.com/p/arduino-tiny/source/browse/trunk/hardware/tiny/cores/tiny/core_pins.h#184

If[font=Courier New] FAVOR_PHASE_CORRECT_PWM [/font]is[font=Courier New] 1 [/font]then OC0B is used (timer 0 controls PB1).  If[font=Courier New] FAVOR_PHASE_CORRECT_PWM [/font]is[font=Courier New] 0 [/font]then OC1A is used (timer 1 controls PB1).


Decide which timer you want to use for PWM.  Pick which of the two pins you want to use.  Set the two compile-time switches to match.


Quote
...making it not clear to my inexperienced eyes as to which PWM timers are mapped to which pins? 


Pins are numbered by the bit: PB0 = digital pin 0, PB1 = digital pin 1, PB2 = digital pin 2, etcetera.

johnamon

#17
Jan 27, 2013, 01:19 am Last Edit: Jan 27, 2013, 01:23 am by johnamon Reason: 1
Thank you again, your depth of knowledge, and ability to communicate what you know is humbling!  

I don't know why - but I thought you were in Australia....  It's past midnight here and I need to go to sleep!  Anyway I have realised that you are donationware - I'll get on that right away!  :smiley-red:

Thank you again for 'babysitting' me through this.

What I need to do now is document all this, as I can see a lot of this information has already been posted and I think we've stitched a lot of it together here.. :)

Coding Badly

Thank you again...


You are welcome.

Quote
I don't know why - but I thought you were in Australia....


By the hours I keep and the dog I own, I should be.

Quote
Anyway I have realised that you are donationware - I'll get on that right away!


Thank you!

johnamon

#19
Jan 27, 2013, 09:25 pm Last Edit: Jan 28, 2013, 12:26 am by johnamon Reason: 1
Thank you dc42 and Coding Badly.  Due to the amount of information presented in the previous posts I thought I would summarise what I plan to do - if you guys let me know that the steps below are correct, then I will edit the first post in this thread to explain clearly how we got 32kHz frequency PWM from my ATtiny45.


Summary:

I would like the PWM output from an ATtiny45 to produce a variable voltage of 0v to 5v, via a RC low pass filter.  I have calculated that a 32kHz PWM frequency would be ideal, the high frequency allows low ripply and relatively fast 'settle' time.

To achieve 32kHz, I need to divide the system 8MHz clock by 256 (prescaler of 1 in Fast Mode PWM).  However the mills() and delay() programming functions utilise Timer1 - so to maintain programming functionality we will assign Timer0 to mills and delay (assigning Timer1 to PWM is dealt with later in the thread):

Execution:


  • Locate core_build_options.h in the Tiny Core directory

  • Open it in your favourite text editor (I like Visual StudioTextEdit.app  :*)

  • Navigate to line 107...

http://code.google.com/p/arduino-tiny/source/browse/trunk/hardware/tiny/cores/tiny/core_build_options.h#107
  • Change TIMER_TO_USE_FOR_MILLIS to zero...

#define TIMER_TO_USE_FOR_MILLIS                   0
  • Save and close the file



Because my analogue voltage requirement is best served by 'Fast PWM', I perform the modification to core_build_options.h:


  • Locate core_build_options.h in the Tiny Core directory

  • Open it in your favourite text editor (I like Visual StudioTextEdit.app  :*)

  • Navigate to line 119...

http://code.google.com/p/arduino-tiny/source/browse/trunk/hardware/tiny/cores/tiny/core_build_options.h#119
  • Change FAVOR_PHASE_CORRECT_PWM to zero...

#define FAVOR_PHASE_CORRECT_PWM                   0
  • Save and close the file



Because we have favoured FAST PWM, OC1A is used to control PB1, and also PB0 - so Physical Pins 5 and 6 may be used to generate the PWM signal that is required.



As-yet Timer1 has not had it's frequency set to 32kHz - so in this step we do that...

Code: [Select]
#include <UserTimer.h>

void setup( void )
{
 UserTimer_SetToPowerup();
 UserTimer_SetWaveformGenerationMode( UserTimer_(Fast_PWM_FF) );
 UserTimer_ClockSelect( UserTimer_(Prescale_Value_1) );
 // Frequency is F_CPU / (1 * (0xFF+1))
 // (8 megahertz) / 256 = 31.25 kilohertz
}

void loop( void )
{
analogWrite(PB0,255); //Gives 5V analogue output
}



Thanks again

John

dc42


To achieve 32kHz, I need to divide the system 8MHz clock by 256 (prescaler of 256).


No, you don't need to a prescaler of 256, you need a prescaler of 1. If you use one of the 8-bit counter/timers with its maximum TOP value of 255 (as is usual when using it to generate a PWM signal), then the counter is already dividing by either 256 or 512 (depending on the mode you select), giving you a frequency close to 32KHz or 16kHz.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

johnamon

oK - I can see from Page 76 of the datasheet that in Fast Mode PWM the frequency pre-scaler should be 1 as the system clock is already divided by 256.....

Thank you again dc42 - this is a fair bit more complicated than I expected when I was ordering bits on the Farnell website, I couldn't have got here without you guys!

Go Up