Go Down

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

johnamon

Hi Guys,

I am not experienced in the under-the-hood details of microcontrollers and I wondered if anyone could help me?  I have settled on a nice RC filter arrangement to produce a 'true analogue' voltage, with the RC calcs based on 32kHz PWM frequency.

I would like to set my 8MHz ATtiny45's PWM frequency to approximately 32kHz, but I'm not sure if a guide that I have found is quite correct....

Reading the guide below, the author suggests that he has achieved 32kHz PWM with the following like

http://nicknorton.net/?q=node/7

TCCR0B = TCCR0B & 0b11111000 | 0b001

That all looks great, but the post here suggests that the line above will only result in a PWM frequency of 15.6kHz...  Unfortunately I don't have access to an oscilloscope to perform my own confirmation  :(

I also don't understand why there is a 'b' at the end of the Timer set line (my lack of understanding showing through).  By looking at the datasheet I'd have thought that the Timer select line should read something like:

TCCR0B = TCCR0B & 0b11111000 | 1001

Does anyone have a definative answer?

Thanks in advance

John

Coding Badly

Hi,

I also don't understand why there is a 'b' at the end of the Timer set line (my lack of understanding showing through).


The "b" informs the compiler that the constant is to be treated as a binary value (as opposed to decimal or hexadecimal).

Quote
By looking at the datasheet I'd have thought that the Timer select line should read something like:
TCCR0B = TCCR0B & 0b11111000 | 1001


"1001" is one-thousand and one in decimal.  "0b1001" is nine in decimal.

Coding Badly


johnamon

#3
Jan 26, 2013, 12:58 pm Last Edit: Jan 26, 2013, 05:26 pm by johnamon Reason: 1
Hi Coding Badly,

I am using (what I believe is your) own arduino-tiny core, and your knock-bang debugging too - I am in your debt already!  :smiley-roll:

Thank you for the replies :)

dc42

Here is the code I use for setting a given frequency on the ATtiny45. I developed it originally for IR remote control at a variable frequency.

Code: [Select]

// Set the frequency that we will get on pin OCR1A but don't turn it on
void setFrequency(uint16_t freq)
{
 uint32_t requiredDivisor = (F_CPU/2)/(uint32_t)freq;

 uint16_t prescalerVal = 1;
 uint8_t prescalerBits = 1;
 while ((requiredDivisor + prescalerVal/2)/prescalerVal > 256)
 {
   ++prescalerBits;
   prescalerVal <<= 1;
 }
 
 uint8_t top = ((requiredDivisor + (prescalerVal/2))/prescalerVal) - 1;
 TCCR1 = (1 << CTC1) | prescalerBits;
 GTCCR = 0;
 OCR1C = top;
}

// Turn the frequency on
void on()
{
 TCNT1 = 0;
 TCCR1 |= (1 << COM1A0);
}

// Turn the frequency off and turn off the IR LED.
// We let the counter continue running, we just turn off the OCR1A pin.
void off()
{
 TCCR1 &= ~(1 << COM1A0);
}
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.

Go Up