Pages: 1 [2]   Go Down
Author Topic: ATtiny45 PWM Frequency Selection  (Read 3314 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12744
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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).
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12744
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 FAVOR_PHASE_CORRECT_PWM is 1 then OC0B is used (timer 0 controls PB1).  If FAVOR_PHASE_CORRECT_PWM is 0 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.
« Last Edit: January 26, 2013, 07:10:33 pm by Coding Badly » Logged

Aberdeen, United Kingdom
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.. smiley
« Last Edit: January 26, 2013, 07:23:13 pm by johnamon » Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12744
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Aberdeen, United Kingdom
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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  smiley-kiss)
  • 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  smiley-kiss)
  • 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:
#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
« Last Edit: January 27, 2013, 06:26:50 pm by johnamon » Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 223
Posts: 6593
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

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.

Aberdeen, United Kingdom
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Pages: 1 [2]   Go Up
Jump to: