22 of 307
ZBasic System Library 12 ZX Microcontroller Family processors running at 14.7456MHz), some of the routines effectively divide the timer frequency by 2 so that the time units associated with parameters or return values is preserved. If you change the timer speed setting, the scale factor is still applied. TimerSpeed Pre-Scaler Values TimerSpeed Value Divisor Timer Clock Freq. Timer Clock Period 0 n/a 0 Hz - 1 1 14.7456 MHz 67.8nS 2 8 1.8432 MHz 542nS 3 64 230.4 KHz 4.34µS 4 256 57.6 KHz 17.4µS 5 1024 14.4 KHz 69.4µS 6 n/a External – T1 falling edge - 7 n/a External – T1 rising edge - Note that setting the value of either of the timer speed registers other than by direct assignment using an assignment statement will produce undefined results. Also note that on the ZX-24 series devices, the T1 input signal is common with Port C, bit 7. If you wish to use an external clock source you’ll have to configure pin 5 to be an input so as not to interfere with that signal. Of course, transitions on Port C bit 7 can be used to clock the timer when the T1 input signal is selected. There are several important facts to keep in mind if you modify either of the timer speed values. Firstly, the timer speed values are initialized by the system when it begins running and they are never modified by the system thereafter. If you change a timer speed value, that value will be used by all of the related System Library routines until you change it again. Secondly, values returned by some of the System Library routines are scaled based on the default timer speed values. If you change the timer speed, you’ll have to apply an additional scale factor in order to get the correct results. For example, if you set Register.TimerSpeed2 to 3 and then call the subroutine PulseIn(), a pulse having a width of 100µS will return the value of approximately 12.5µS since the clock speed that you specified is 1/8 that of the default. In order to get the correct pulse width, in seconds, you will have to multiply the value returned by 8. Those return values that are not scaled to seconds represent a number of periods of the timer frequency. So, for example, if you change Register.TimerSpeed1 to 2, the values returned by InputCapture() represent units of 542nS instead of the default 67.8nS. The other Register value related to the I/O Timer is the “timer busy” flag, e.g. Register.Timer1Busy. Whenever a System Library routine that requires the I/O Timer prepares to execute, it first checks the value of this Boolean flag to see if the timer is already in use. If the flag is True, the routine will not execute; usually returning without doing anything (but see the descriptions of the various routines for specific details). If the flag is False, the routine sets it to True and then goes about using the timer. When it has finished its function, it sets the flag back to False. Your code can use the timer busy flag as the parameter to the Semaphore() function in order to get exclusive access to the timer. Of course, you must set timer busy flag to False when your code is finished with the timer to indicate that the timer is no longer in use. Likewise, you may want to acquire a semaphore on a timer busy flag for the I/O Timer before calling a System Library routine that uses I/O Timer. If you succeed in setting the semaphore you’ll know that the timer is not already in use. An example of code for this purpose (for ZX devices that use Timer1 for the I/O Timer) is shown below. ' wait until the timer is available Do While (Not Semaphore(Register.Timer1Busy)) Call Sleep(0.5) Loop ' use the timer Call LockTask() Register.Timer1Busy = False Call ShiftOut(12, 13, 8, &H55) Call UnlockTask()