Linear frequency control
Posted: Fri Feb 26, 2010 11:05 am
It is relatively easy to provide linear control of the duration of a timed event using most microcontrollers. A simple variable can be used to control the number of cycles of a timing loop, or can be loaded into the compare registers provided by some of the more advanced timer modules. In either case the timed period, t, will be proportional to the value of the variable.
Linear control of frequency, f, can be more complicated unless more specialized hardware is available. As t=1/f, the obvious solution would seem to be to perform the division calculation to derive the required time period from the supplied frequency value. Flowcode V4 can support the floating-point calculations that would usually be required by this method, but there is a much quicker and simpler approach that can be used in many applications.
Phase accumulator:
The phase accumulator method uses the control variable to represent a phase increment value. The phase increments are continuously added to the phase accumulator (a larger variable used to hold a running total) at fixed time periods. Small values cause the accumulator value to increment slowly, large values cause it to increment proportionally faster, causing certain events to occur at a linearly controlled frequency.
The accumulator value can be used in a number of ways to generate an output.
1. Compare
On each increment, the value in the accumulator can be compared with a target value. When the target value is matched, or exceeded, the required operation is performed, and the accumulator value decremented by the target value to initialize the next cycle.
2. Address generation
The most significant bits of the accumulator are used directly as the index value for an array containing waveform data. On each accumulator increment, the indexed array data is accessed and used to generate almost any arbitrary audio waveform, control sequence, etc., with the required linear frequency control.
Example:
The example program linked to this article uses the phase accumulator technique to allow linear, analog, control of the speed of a stepper motor. The program is written in Flowcode AVR V3 to allow compatibility with all Flowcode V3/4 options. The V4 stepper component is not used and is replaced with a simple array of phase pattern data. The program can be loaded or imported directly into other V3 or V4 versions of Flowcode (PIC, AVR, ARM). Some adjustment of interrupt configuration might be required when importing to the alternative device types.
Note: The 'SampleADC' macro will be ignored in Flowcode V4 and can be removed.
The analog input is read as an 8-bit conversion, which is reduced to 7-bits to provide the 1% full scale resolution required by this application. Analog sampling and phase accumulator updates are triggered by a Timer0 overflow interrupt.
The phase accumulator is an int variable. This 16-bit, signed variable has been limited to 14-bit values to prevent problems with negative number representations.
The three most significant active bits of the phase accumulator are used as the index to an array of eight stepper motor phase output values (half-step mode) that are written to the selected port each time the phase accumulator is updated. In most cases the same value will be written for several successive updates until the relevant bits of the phase accumulator change.
Calculations:
The timer interrupt frequency is based on: 20MHz Xtal; 1:8 prescaler; 256 timer overflow count:
Timer interrupt frequency = 20000000Hz / 8 / 256 = 9765.625Hz
At the maximum input value (maximum frequency) the phase accumulator will be incremented by 255 on each interrupt. The phase accumulator will overflow after 129 interrupts
Maximum accumulator overflow frequency = 9765.625Hz / 129 = 75.7Hz
Due to the stepper phase patterns generated by the array, eight half-steps (four full-steps) will have been generated in this period.
The maximum stepper speed is 75.7Hz x 4 = 302.8 full-steps per second.
Alternative crystal frequencies, timer configurations, and sizes of variables, can allow alternative frequency ranges and adjustment resolutions to be achieved.
Other advantages of the phase accumulator method are:
Its ability to generate a zero frequency output without having to represent infinite time.
The filtering effect of the accumulator on noisy control signals.
Linear control of frequency, f, can be more complicated unless more specialized hardware is available. As t=1/f, the obvious solution would seem to be to perform the division calculation to derive the required time period from the supplied frequency value. Flowcode V4 can support the floating-point calculations that would usually be required by this method, but there is a much quicker and simpler approach that can be used in many applications.
Phase accumulator:
The phase accumulator method uses the control variable to represent a phase increment value. The phase increments are continuously added to the phase accumulator (a larger variable used to hold a running total) at fixed time periods. Small values cause the accumulator value to increment slowly, large values cause it to increment proportionally faster, causing certain events to occur at a linearly controlled frequency.
The accumulator value can be used in a number of ways to generate an output.
1. Compare
On each increment, the value in the accumulator can be compared with a target value. When the target value is matched, or exceeded, the required operation is performed, and the accumulator value decremented by the target value to initialize the next cycle.
2. Address generation
The most significant bits of the accumulator are used directly as the index value for an array containing waveform data. On each accumulator increment, the indexed array data is accessed and used to generate almost any arbitrary audio waveform, control sequence, etc., with the required linear frequency control.
Example:
The example program linked to this article uses the phase accumulator technique to allow linear, analog, control of the speed of a stepper motor. The program is written in Flowcode AVR V3 to allow compatibility with all Flowcode V3/4 options. The V4 stepper component is not used and is replaced with a simple array of phase pattern data. The program can be loaded or imported directly into other V3 or V4 versions of Flowcode (PIC, AVR, ARM). Some adjustment of interrupt configuration might be required when importing to the alternative device types.
Note: The 'SampleADC' macro will be ignored in Flowcode V4 and can be removed.
The analog input is read as an 8-bit conversion, which is reduced to 7-bits to provide the 1% full scale resolution required by this application. Analog sampling and phase accumulator updates are triggered by a Timer0 overflow interrupt.
The phase accumulator is an int variable. This 16-bit, signed variable has been limited to 14-bit values to prevent problems with negative number representations.
The three most significant active bits of the phase accumulator are used as the index to an array of eight stepper motor phase output values (half-step mode) that are written to the selected port each time the phase accumulator is updated. In most cases the same value will be written for several successive updates until the relevant bits of the phase accumulator change.
Calculations:
The timer interrupt frequency is based on: 20MHz Xtal; 1:8 prescaler; 256 timer overflow count:
Timer interrupt frequency = 20000000Hz / 8 / 256 = 9765.625Hz
At the maximum input value (maximum frequency) the phase accumulator will be incremented by 255 on each interrupt. The phase accumulator will overflow after 129 interrupts
Maximum accumulator overflow frequency = 9765.625Hz / 129 = 75.7Hz
Due to the stepper phase patterns generated by the array, eight half-steps (four full-steps) will have been generated in this period.
The maximum stepper speed is 75.7Hz x 4 = 302.8 full-steps per second.
Alternative crystal frequencies, timer configurations, and sizes of variables, can allow alternative frequency ranges and adjustment resolutions to be achieved.
Other advantages of the phase accumulator method are:
Its ability to generate a zero frequency output without having to represent infinite time.
The filtering effect of the accumulator on noisy control signals.