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