Counting Pulses
The accuracy of the speed measurement using this method will depend on the number of slots counted, because the error is always ± 1 slot. If the rev count were made over a period of 1 s at 10 pps, the precision would be 10% and the speed could only be corrected once per second. This response time is too slow for most practical purposes, so this option will be rejected. It would be viable if the encoder had more slots per revolution or the motor was running at high speed.
Measuring Pulse Period
At 10 pps, the target speed, the pulse period will be 100 ms. This can be measured using a 100 ms timer, which can be set up using the 8-bit TMR0 hardware counter/timer (see Chapter 6). The counter is driven by the instruction clock (1/4 of the MCU oscillator frequency). The timer prescaler allows this to be divided by 2, 4, 8, 16, 32, 64, 128 or 256, by setting a 3-bit code in the option register. If the MCU clock is set to 1 MHz, the timer clock rate is 250 kHz, with period 4 ms, with the maximum prescaler setting of 256, the longest period measurable will be 256 x 256 x 4 ¼ 26 2144 ms ¼ 262 ms. The count required, as a proportion of this maximum value, will be 100/262 x 256 ¼ 98 (to the nearest whole number). Recall that the timer counts up to FF then 00, when the overflow flag is set, so the timer must be preloaded with the complement of this value, 256 – 98 ¼ 158.
PWM Motor Control
The speed of the motor is controlled using PWM, which switches the motor current on and off over a fixed period cycle. The ratio of the on/off periods controls the average current, and hence the speed. A software delay loop will be used to generate a PWM drive signal to the motor, while running a hardware timer to generate a timing reference to compare with the sensor feedback each time round the motor delay loop. The mark/space ratio (MSR) is adjusted to control the speed. The target speed is set using the switch inputs to generate the timer preload value.
The process is illustrated in the timing diagram (Figure 11.5). The timing cycle starts at the rising edge of the sensor pulse when the timer is started. The program waits for the falling edge of the sensor pulse, then starts checking if the next pulse has arrived, or if the timer has timed out, once per motor cycle. If the speed is too low, the timer times out first, before the pulse arrives, so the speed must be increased for the next timing cycle. If the slot arrives before the timer has timed out, it means that the motor is running too fast, so the speed must be decremented for the next cycle. User flags have been defined, one to record the fact that the falling edge has been detected and acted upon (‘slot’ flag) and another to record the fact that the timer has been restarted (‘done’ flag), to make the program wait for the next slot to restart the timer. When the speed is correct, the speed correction will alternate between incrementing and decrementing.
Figure 11.6 shows the top-level flow chart for the program. This initializes the program and switches the motor on and off. ‘Speed’ is a user register that holds the value for the PWM ‘on’ time. The ‘off’ time is derived by complementing this value. The total count for each motor drive cycle is then 256, which means the frequency will remain constant. At the start of the main loop, on the rising edge of the sensor pulse, Timer0 is loaded with the 8-bit value read
from the switch bank. A low value will give a longer remaining count in Timer0, and a longer target cycle time, corresponding to a low speed. A high value will give a high target speed.
The main subroutine checks the input and timeout flag in a polling loop. If the timer times out before the next slot arrives, as is the case when starting up, the motor is going too slowly, so the PWM ‘on’ time is increased. When the motor is eventually going too quickly, the slot arrives before the timer has finished, so the ‘on’ time is reduced. The speed must be stopped from rolling over from FF (maximum) to 00 (minimum), so the speed value is tested for zero after incrementing or decrementing and set back to FF or 1, respectively.
When the motor is running at the correct speed, the sensor period should match the timer period. In practice, the motor will hunt around the target value owing to limited resolution in the measurements, program delays, motor imperfections and mechanical inertia. The source code is listed as CLS2.ASM in Program 11.3.