ATtiny13A Fast PWM

I am a complete newbie to Arduino and AVR programming (please don’t groan).

I have working code but do not understand the ATiny13A datasheet page 79 table 11-8 Waveform Generation Mode Bit Description.

I am using Fast PWM with the ORCA value to control the pulse width. From the table it looks like I should be selecting mode 7 but if I set WGM02, WGM01, WGM00, I get no waveform from the pin. If I clear WGM02 and set WGM01 and WGM00, (mode 3), I get the waveform at the pin. But this looks like the TOP value is 0xFF rather than the OCRA I am using.

Please could you explain how I have misunderstood the data sheet.

Best regards

When WGM02, WGM01, WGM00 is set, the TOP value of the timer is controlled by OCRA.
That is, the timer count increments from 0 to the value of OCR2A and returns to 0.
This allows you to control the frequency, but OCRB must be used for waveform output.
The OCRB value must be between 0 and OCRA.
Because it is the PWM duty.

Thanks, I’ll have a play (sounds a bit like Phase Correct but I know it must be different).

Space is a bit tight in there - I’m at 94% but that’s still with the boot loader in place - working out how to circumvent this will certainly pass the hours!! Time to build a 3v hardware harness and see just how effective my power saving attempts were.

Did you remember that WGM00 and WGM01 are in TCCR0A but WGM02 is in TCCR0B? That one has bitten me before.

Hi Chris
I think the penny is dropping. Are you saying that with PWM mode 7 (WGM02, WGM01, WGM00 set), I can user OCR0A to define TOP to control the counter timer frequency (I can only get to 150Hz or 37Hz with pre-scalers) and then use OCR0B to control the duty cycle for a PWM signal on PB1 (MISO/AIN1/OC0B/INT0/PCINT1)?
If this is the case may I also define PB0 (MOSI/AIN0/OC0A/PCINT0) as a digital input pin?
If all this stacks up, it’s time for me to move away from my ATtiny dev board as that has a button on PB1 and an LED (currently my PWM signal) on PB0.

Many thanks for your help.

BTW the MOSFET servo harness worked a treat - I even have an emergency power feed that holds down reset for a brief moment when it is jacked in.

Solved - thanks guys - getting the wheel to move in the first place is the hardest.
Yes the OCR0A can control the frequency while the OCR0B controls the PWM duty but comes out of PINB1-MISO/AIN1/OC0B/INTO/PCINT1 and I can still define PINB0-MOSI/AIN0/OC0A/PCINT0 as an input pin.

Some code snippets here if anyone is interested…
#define F_CPU 9600000 // 9.6MHz is the default - needed by compiler to make <avr/delay.h> work - but I’m not using this
#define OCR0B_value1 18 // OCR0B TOP value for PWM lock rotation 2ms
#define OCR0B_value2 9 // OCR0B TOP value for PWM unlock rotation 1ms
#define OCR0A_value 190 // in fast PWM mode 7, the counter counts to this as TOP in place of &FF (Max is 255)
.
.
.

DDRB |= (1<<PINB0)|(1<<PINB1)|(1<<PINB3);	// set output pins in Port B Data Direction Register
PORTB |= (1<<PINB2)|(1<<PINB4)|(1<<PINB5);  // set internal pull up on input pins in Port B Data Register
PORTB |= (1<<PINB1);						// set servo pin initially HIGH as we are going for inverted

TCCR0A |= ((1<<WGM01)|(1<<WGM00)); // set fast PWM mode 7 - page 79 - uses OCR0A for TOP, PWM signal comes out on OCR0B
TCCR0B |= (1<<WGM02); // to use TOP as OCR0A rather than 0xFF
TCCR0A |= (1<<COM0B1)|(1<<COM0B0); // define inverted

OCR0A = OCR0A_value;							// set TOP for PWM frequency
OCR0B = OCR0B_value1;							// controls the PWM

TCCR0B = (TCCR0B & ~((1<<CS02)|(1<<CS01)|(1<<CS00))) | 5; // mask out the bits and then OR in the required values from table below
// CS02 CS01 CS00 Value Effect
// 0 0 0 0 Time stopped (no PWM output)
// 0 0 1 1 No prescaling
// 0 1 0 2 divide by 8
// 0 1 1 3 divide by 16
// 1 0 0 4 divide by 64 << 150Hz - too fast
// 1 0 1 5 divide by 128 << 37Hz - 27ms period - but I can use OCR0A to cut this short

On my quest for a solution, I did try hooking into the counter timer interrupt and counting these so as to disable the PWM on all but 1 in N interrupts based on a prescaler counter time of 150Hz. It sort of worked but using a scope I could see occasional spikes on servo output between desired drive pulses at about the time the PWM drive signal would have triggered if I was not skipping interrupts. My hunch is that the PWM output probably starts at about the same time as my disabling it and it would occasionally glitch. I managed to mask this out by slugging the output with a small capacitor but that was inelegant. I also tried to disable PWM at several other code locations but each time it glitched. I think the timer hardware on the PWM would beat my disable code by a cycle or so and hence glitch an output. I’m glad I got it to work cleanly as previous post and I managed to hit 50Hz with between 1ms and 2ms drive pulse (inverted as saves a MOSFET in my servo harness). Happy days.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.