|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Did you know...
|
Serial Wombat Timer Based Input/OutputThe 18F4620 microcontroller used by the Serial Wombat has many different hardware features which enable enhanced functionality. The Wombat design balances versatility against performance in deciding how to use these hardware resources. One of the resources available in the 18F4620 is a timer capable of generating an interrupt at a specified frequency. The Serial Wombat firmware uses this timer to allow synchronous reads and writes from pins 33 to 40. When the host enables the Timer Interrupt, a high priority interrupt is enabled inside the Wombat. Each time the timer expires, a small amount of interrupt code will be executed at a higher priority than other tasks in the system. This code stores the value of pins 33 to 40 as an 8 bit value into a table stored at address 0x0000 in user ram. If output is enabled, the interrupt code writes a value from a table stored at address 0x0100 to pins between 33 and 40 which are configured as outputs. The code which services this interrupt is very efficient and small. Therefore, it is possible for the timer to be set to increments as small as 20uS (causing 50,000 samples per second). This allows fast waveforms to be generated, or input pins to be sampled quickly. For instance, a reliable UART receive algorithm requires sampling the input line at 3 times the bit rate. Using only the normal pin-servicing schedule, it would be possible to receive data at up to about 2400 baud on one pin, but this would consume nearly all of the Wombat's processing power. Using the High priority interrupt, it is possible to run UART receive on 8 different pins at 9600 baud, while still doing some other things. In order to achieve this high performance, it was necessary to give up some flexibility with regard to how the interrupt uses Wombat resources. First, the data read from the pins is put into a table located at address 0x0000 in User Ram. This table cannot be moved to another address. Its size, however, can be set to between 1 and 256 bytes. Most pin processing routines (such as UART receive mode and Remote Control mode) require the full size of 256 bytes to be allocated. Second, the output function must use a table starting at User Ram address 0x0100. The size of this table must be the same size as the input table. Third, if the output function is enabled, then all pins between 33 and 40 which are configured as outputs will be affected. This prevents many pin modes from running on pins between 33 and 40 when the interrupt is enabled. These restricitions only apply when the interrupt is enabled. The period of the timer is based on the clock speed of the Wombat. If the internal clock is used, this value is 8,000,000Hz. If an external crystal is used, then the value is the speed of that crystal. The Timer Update value used in the command below is calculated using the following formula: Update Value = 65536 - (Crystal Speed / Timer Frequency) + 6 For example, assume the 8MHz internal clock, and that 10,000 samples are requested per second (suggested rate for the Remote Control mode). The update value would be: 65536 - ( 8,000,000 / 10,000) + 6 = 64742 A bit of background and insight on how the Wombat works internally: Most pin processing routines which use the Interrupt treat it as a stream of incoming bits on a particular pin. The pin mode can see the next byte in the table to be written. By keeping track of this value between services (every 1ms by default), the pin mode can determine which bits have been captured since the last service, and process them. In order for this to work, the service time must be frequent enough that the interrupt cannot overwrite the entire table between services. For instance, when using a 1ms frame time, it is permissible to have updates at 20,000Hz. This results in a relatively small 20 samples per frame. However, if the frame time was 100ms, this would result in 2000 samples per frame--many more than the 256 available in the maximum table size. Message format:The Timer interrupt is configured using the Set System Parameter command.
Example:It is desired to create a waveform which simulates the teeth of a camshaft and crankshaft on an engine. The Crankshaft has 24 teeth, of which 2 are missing to indicate position, and the camshaft has 6 teeth, of which 1 is missing to indicate position. The Crankshaft rotates twice for each revolution of the Camshaft. The presence or absence of a tooth is indicated by a magnetic sensor, which provides a logic high when a tooth is present. This sort of sensing is common in engine applications. The Waveforms look like this:
Missing Crank Tooth Missing Crank Tooth
| |
CRANKSHAFT: -_-_-_-_-_-_-_-_-_-_-_-___-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-___-_-_-_-_-_-_-_-_-_-_-_
CAMSHAFT: ________--------________--------________--------________--------________________________--------
|
Missing Cam Tooth
Implementing such a waveform will require 120 entries in the
table:
These values can be placed into memory as follows. Note that it is possible to send multiple bytes per message, but one byte per message is set in this example for clarity. 146 0x0100 1 0x02 0x55 0x55 0x55 146 0x0101 1 0x00 0x55 0x55 0x55 146 0x0102 1 0x02 0x55 0x55 0x55 146 0x0103 1 0x00 0x55 0x55 0x55 146 0x0104 1 0x02 0x55 0x55 0x55 146 0x0105 1 0x00 0x55 0x55 0x55 146 0x0106 1 0x02 0x55 0x55 0x55 146 0x0107 1 0x00 0x55 0x55 0x55 146 0x0108 1 0x03 0x55 0x55 0x55 146 0x0109 1 0x01 0x55 0x55 0x55 146 0x010A 1 0x03 0x55 0x55 0x55 146 0x010B 1 0x01 0x55 0x55 0x55 146 0x010C 1 0x03 0x55 0x55 0x55 146 0x010D 1 0x01 0x55 0x55 0x55 146 0x010E 1 0x03 0x55 0x55 0x55 146 0x010F 1 0x01 0x55 0x55 0x55 146 0x0110 1 0x02 0x55 0x55 0x55 146 0x0111 1 0x00 0x55 0x55 0x55 146 0x0112 1 0x02 0x55 0x55 0x55 146 0x0113 1 0x00 0x55 0x55 0x55 146 0x0114 1 0x02 0x55 0x55 0x55 146 0x0115 1 0x00 0x55 0x55 0x55 146 0x0116 1 0x02 0x55 0x55 0x55 146 0x0117 1 0x00 0x55 0x55 0x55 146 0x0118 1 0x01 0x55 0x55 0x55 ;(missing tooth) 146 0x0119 1 0x01 0x55 0x55 0x55 146 0x011A 1 0x03 0x55 0x55 0x55 146 0x011B 1 0x01 0x55 0x55 0x55 146 0x011C 1 0x03 0x55 0x55 0x55 146 0x011D 1 0x01 0x55 0x55 0x55 146 0x011E 1 0x03 0x55 0x55 0x55 146 0x011F 1 0x01 0x55 0x55 0x55 146 0x0120 1 0x02 0x55 0x55 0x55 146 0x0121 1 0x00 0x55 0x55 0x55 146 0x0122 1 0x02 0x55 0x55 0x55 146 0x0123 1 0x00 0x55 0x55 0x55 146 0x0124 1 0x02 0x55 0x55 0x55 146 0x0125 1 0x00 0x55 0x55 0x55 146 0x0126 1 0x02 0x55 0x55 0x55 146 0x0127 1 0x00 0x55 0x55 0x55 146 0x0128 1 0x03 0x55 0x55 0x55 146 0x0129 1 0x01 0x55 0x55 0x55 146 0x012A 1 0x03 0x55 0x55 0x55 146 0x012B 1 0x01 0x55 0x55 0x55 146 0x012C 1 0x03 0x55 0x55 0x55 146 0x012D 1 0x01 0x55 0x55 0x55 146 0x012E 1 0x03 0x55 0x55 0x55 146 0x012F 1 0x01 0x55 0x55 0x55 146 0x0130 1 0x02 0x55 0x55 0x55 146 0x0131 1 0x00 0x55 0x55 0x55 146 0x0132 1 0x02 0x55 0x55 0x55 146 0x0133 1 0x00 0x55 0x55 0x55 146 0x0134 1 0x02 0x55 0x55 0x55 146 0x0135 1 0x00 0x55 0x55 0x55 146 0x0136 1 0x02 0x55 0x55 0x55 146 0x0137 1 0x00 0x55 0x55 0x55 146 0x0138 1 0x03 0x55 0x55 0x55 146 0x0139 1 0x01 0x55 0x55 0x55 146 0x013A 1 0x03 0x55 0x55 0x55 146 0x013B 1 0x01 0x55 0x55 0x55 146 0x013C 1 0x03 0x55 0x55 0x55 146 0x013D 1 0x01 0x55 0x55 0x55 146 0x013E 1 0x03 0x55 0x55 0x55 146 0x013F 1 0x01 0x55 0x55 0x55 146 0x0140 1 0x02 0x55 0x55 0x55 146 0x0141 1 0x00 0x55 0x55 0x55 146 0x0142 1 0x02 0x55 0x55 0x55 146 0x0143 1 0x00 0x55 0x55 0x55 146 0x0144 1 0x02 0x55 0x55 0x55 146 0x0145 1 0x00 0x55 0x55 0x55 146 0x0146 1 0x02 0x55 0x55 0x55 146 0x0147 1 0x00 0x55 0x55 0x55 146 0x0148 1 0x00 0x55 0x55 0x55 ;(missing teeth) 146 0x0149 1 0x00 0x55 0x55 0x55 ;(missing tooth) 146 0x014A 1 0x02 0x55 0x55 0x55 ;(missing tooth) 146 0x014B 1 0x00 0x55 0x55 0x55 ;(missing tooth) 146 0x014C 1 0x02 0x55 0x55 0x55 ;(missing tooth) 146 0x014D 1 0x00 0x55 0x55 0x55 ;(missing tooth) 146 0x014E 1 0x02 0x55 0x55 0x55 ;(missing tooth) 146 0x014F 1 0x00 0x55 0x55 0x55 ;(missing tooth) 146 0x0150 1 0x02 0x55 0x55 0x55 146 0x0151 1 0x00 0x55 0x55 0x55 146 0x0152 1 0x02 0x55 0x55 0x55 146 0x0153 1 0x00 0x55 0x55 0x55 146 0x0154 1 0x02 0x55 0x55 0x55 146 0x0155 1 0x00 0x55 0x55 0x55 146 0x0156 1 0x02 0x55 0x55 0x55 146 0x0157 1 0x00 0x55 0x55 0x55 146 0x0158 1 0x03 0x55 0x55 0x55 146 0x0159 1 0x01 0x55 0x55 0x55 146 0x015A 1 0x03 0x55 0x55 0x55 146 0x015B 1 0x01 0x55 0x55 0x55 146 0x015C 1 0x03 0x55 0x55 0x55 146 0x015D 1 0x01 0x55 0x55 0x55 146 0x015E 1 0x03 0x55 0x55 0x55 146 0x015F 1 0x01 0x55 0x55 0x55 Next, we'll set pins 33 and 34 to output. We'll start with low, but that won't really matter once the timer interrupt is enabled: "P330UUUU" "P340UUUU" Finally, we'll enable the interrupt. Let's suppose we want to simulate an engine speed of 1500 RPMs. This corresponds to 1200 interrupts per second (1500 Crankshaft revs per minute / 60 seconds per minute * 48 samples per crankshaft revolution). Therefore, for the timer update value (assuming the 8Mhz internal oscillator): 65536 - (8000000 / 1200 ) + 6 = 58875 = 0xE5FB So we'll set up the interrupt: 97 25 1 0xE5FB 95 1 0x55 ;Setting Timer
;Interrupt Enable True, 1200 per second, Output Enable: True,
;Memory Usage: 96
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Copyright Wombat Interface Products, 2005-2008. All Rights Reserved.