From the ATtiny85 Datasheet:
The mode of operation, i.e., the behavior of the Timer/Counter and the
Output Compare pins, is defined by the combination of the Waveform
Generation mode (WGM0[2:0]) and Compare Output mode (COM0x[1:0]) bits.
The Compare Output mode bits do not affect the counting sequence,
while the Waveform Generation mode bits do. The COM0x[1:0] bits
control whether the PWM output generated should be inverted or not
(inverted or non-inverted PWM).
Table 11-5 shows how to set the Mode.
Mode WGM WGM WGM Timer/Counter Mode TOP Update of TOV Flag
c0 02 01 00 of Operation OCRx at Set on
==========================================================================
0 0 0 0 Normal 0xFF Immediate MAX(1)
1 0 0 1 PWM, Phase Correct 0xFF TOP BOTTOM
2 0 1 0 CTC OCRA Immediate MAX
3 0 1 1 Fast PWM 0xFF BOTTOM MAX
4 1 0 0 Reserved – – –
5 1 0 1 PWM, Phase Correct OCRA TOP BOTTOM
6 1 1 0 Reserved – – –
7 1 1 1 Fast PWM OCRA BOTTOM TOP
You want a Fast PWM mode (so either mode 3 or mode 7). If you want to vary the duty cycle, and it sounds like you do, you want mode 7 and vary duty cycle by setting OCRA.
Table 11-3 shows how to set the compare output mode for Fast PWM mode.
COM0A1/ COM0A0/
COM0B1 COM0B0 Description
===============================================================================
0 0 Normal port operation, OC0A/OC0B disconnected.
0 1 Reserved
1 0 Clear OC0A/OC0B on Compare Match, set OC0A/OC0B at BOTTOM
(non-inverting mode)
1 1 Set OC0A/OC0B on Compare Match, clear OC0A/OC0B at BOTTOM
(inverting mode)
That is to say, you can set the OC0A output to go low when the Timer value == OCR0A and high when the Timer value == 0x00 by setting COM0A1:COM0A0 = 0b10. Or vise versa by setting COM0A1:COM0A0 = 0b11. And likewise for OC0B, OCR0B, COM0B0, COM0B1.
The PWM frequency is determined by the I/O Clock (8MHz it sounds like for you) and your timer prescaler setting. And the equation is given as f_clk_IO / (N * 256) for Fast PWM mode.
So you can use OC0A for "normal" polarity and OC0B for "inverted" polarity by setting OCR0A and OCR0B to the same value and setting COM0A1:COM0A0 = 0b10 and COM0B1:COM0B0 to 0b11.
UPDATE
Given you want to toggle the output as fast as possible and you are using the Mega328 operating at 16MHz, the CTC operating mode will allow you to obtain a switching frequency of:
f_OCnA = f_clk_IO / (2 * N * [1 + OCRnA) = 16e6 / (2 * 1 * [1 + 1]) = 4MHz
The Fast PWM mode will let you toggle the pin at:
f_OCnxPWM = f_clk_IO / (N * [1 + TOP]) = 16e6 / (1 * [1 + 1]) = 8MHz
So I still think you want Fast PWM mode. Specifically Mode 3 with OCR0A = OCR0B = 0x80 for 50% duty cycle. And set COM0A bits to 0x3 and COM0B bits to 0x2 to make the two waveforms on OC0A and OC0B inversions of one another.
Update #2
More the Mega328 Try this Arduino code:
#define tick 9
#define tock 10
void setup(){
pinMode(tick, OUTPUT);
pinMode(tock, OUTPUT);
// Setup Waveform Generation Mode 15
// OC1A Compare Output Mode = inverting mode
// OC1B Compare Output Mode = non-inverting mode
// Timer Prescaler = 1
// TOP = OCR1A = 1
//COM1A[1:0] = 0b11, COM1B[1:0] = 0b10, WGM1[1:0] = 0b11
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(WGM11) | _BV(WGM10);
//WGM1[3:2] = 0b11, CS1[2:0] = 0b001
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
OCR1A = 0x0001;
OCR1B = 0x0001;
}
void loop(){
}
The slope is related to the number of steps it takes your motor to make 1 revolution.
For example, common steppers I've worked with take 200 steps per revolution.
If you want to rotate at 100 RPM, then you have to give (100 * 200) steps every minute, or 333.33 steps per second.
If you want 50 RPM, then its (50 * 200)/60 = 166.7 steps per second.
The number of steps per second is controlled by your [wait] time. The longer you wait, the fewer steps per second you get.
I'm not sure why you got the offset value you did. That implies that if your wait was infinite, (0 steps per second) your stepper would still be turning 17 RPM. That clearly can't be true. I suspect some measurement error.
I recommend looking at the data sheet for your stepper driver. It should specify minimum and maximum pulse widths and dwell time for the step signal. With the tight loop you have, there's a chance you're violating those specs and the behavior of the driver is unpredictable.
Best Answer
By "inner" clock, you mean the internal RC oscillator that comes with the device from the factory. It is inside the chip, and is not very accurate over temperature range, which means it will not actually be the frequency that you assume it is, and indeed it may have a lot of "jitter" which means the clock generated from the internal oscillator will not have very "precise" timing, one clock pulse might be +-10->15% different to the one before it, and the one after it. This is bad for cycle-by-cycle timing.
The use of external crystals allows you to have faster clock speeds than that possible with the internal source available in your given example (Atmel ATMEGA328P which is on the Arduino Uno), and these provide (usually! Quality and material are relevant here) very good accuracy and cycle-by-cycle precision of the clock signal.
The system clock is generated from these different possible sources, so if you use a bad accuracy/quality source and expect high speed and timing, you will have problems. Use a good crystal, and you can very nicely time things, such as a very precise/accurate digital signal at a set frequency (given the limitations of timers mentioned below).
The registers that you mention are the perhaps those which allow you to change the CLKDIV options, which allows you to divide an input clock source frequency and make the system clock slower which uses less power, and may give better timing characteristics. The output of the system clock signal may sometimes be selected for one of the microcontroller pins, to clock external devices with a nice clean digital clock - for example, a Camera IC, or a reference clock input for synchronous devices.
The timers inside the microcontrollers use the main clock source, and often have dividers you can set for them separately. From the resulting timer speed, you can then set "output compare" registers, which allows you to choose (based on the resolution!) a certain point where the timer will reset - you may have this essentially act as a digital pulse generator, of reasonably good control of the frequency up to a certain point. 8 Bit timers will allow you to choose an output in steps of 1-255, and 16 bit timers allow you to set a step size of 1->65536. Using a 16 bit timer and a very good quality clock source input would yield the "best" output.
The Atmega328P on the Arduino Uno has multiple timers, so you could make the output compare channels produce more than one custom/adjustable frequency pulse signal.