Thanks for helping, i will work on the ouput compare, however i am wondering if i am going about my initial problem the wrong way.
If i am repeatedly timing gaps between interupts should i be using the main timer, itself? Are the pulse accumulators timers?
Sorry i have no books on freescale MC's yet
Hi
The pulse accumulator is a bit like a timer since it is clocked and counts upwards, overflowing with an interrupt after it has reached 0xffff.
However the pulse accumulator is used to either count events (edges on an external pin) or intervals (gated by a signal on an external pin).
For example, you have an external clock source and you want to measure its frequency - you connect it to the pulse accumulator in event mode and enable the accumulator and wait to see how long it takes for the pulse accumulator to overflow (using another timer to measuse the time of course) - or wait a certain amount of time and see how high the pulse accumulator has counted. The frequency can be derived from the number of pulses and the time it took to count then. If it is not a frequency but a sporadic event (like counting how many times a door is opening and closed in a day) this is also counted using the event mode.
In the gated mode the pulse accumulator counts an internal clock (usually the bus clock divided by a certain ration) when a certain signal is on the gate input (and shuts off the internal clock when the gate signal in in the inactive state). This enables pulse widths to be measured, where the maximum resolution is determined by the internal clock rate. Longer pulse widths can be measured by counting in addition how many times the pulse accumulator overflowed.
To be noted is that in the gated mode the internal count clock is prescaled somewhere in the main timer and if the main timer is not enabled it will not be able to count - it thus forces also the use of the main timer.
External event counting requires no internal clock and works also when the main timer is not used - logically.
Unfortunately I didn't understand the first question - can you explain a little bit more?
About books: I think that the data sheet to the device you are using should be basically adequate to get a first understanding of the operation. Then nothing beats experimenting - even the best data sheets don't always allow you to understand exactly how to use the device. Get a debugger on your board and an oscilloscope on the outputs and play around with the registers. Attempt setups as you have understood them and note the effects of the various changes to them. Afterwards go back to the data sheet - usually the results of experimenting puts the data sheet text in to context and you can then get the most out of the device's capabilities.
Cheers
Mark
www.mjbc.ch
A little follow up:
I have a NE64 based design running on-line using the timers to control the contrast of an LCD, LED intensities, its background light intensity and a buzzer.
See the device at http://212.254.22.36:8080 (web cam) and control it via web browser at http://212.254.22.36:8081 (login using nser name "anon" and password "anon").
The initialisation of the timers looks like this and the intensities are varied simply by changing the value in between 0..0xff (min..max).
Code:
DDRT = 0x80; // ensure buzzer output defined when not in use TIOS = (IOS7 | IOS6 | IOS5 | IOS4); // enable output compare on all channels OC7M = (OC7M6 | OC7M5 | OC7M4); // 3 channels as output (channel 7 (buzzer) not yet) OC7D = (OC7D6 | OC7D5 | OC7D4); // transfer on channel 7 match (for PWM) TSCR1 = TEN; // enable timer TCTL1 = 0x15; // toggle output for 3 channels CONTRAST_CONTROL = (unsigned short)ucContrastSetting; // set default contrast setting TC5_HI = 0x00ff; // set max LED intensity TC4_HI = 0x0000; // set min backlight intensity (off) TC7_HI = 0x00ff; // basic frequency is 3kHz TSCR2 = 0x0c; // enable timer div = 32
ucContrastSetting is a parameter from FLASH which is set to suit the LCD type used.
Regards
Mark
www.mjbc.ch
(Alban highlighted code SRC for tag to appear)
Message Edited by Alban on 05-16-2006 01:39 PM
Hi
I assume you are working with an HC12. My answers may be rather general, I hope they are relevent to the device you are using.
Reseting main timer:
The main timer is a bit special since it can only be written to in special mode, therefore can not generally be set to zero by writing a zero to it. It can be zeroed however when a channel 7 match occurs.
Reseting can be performed by doing the following (for example):
TSCR1 = 0; // freeze the timer
TIOS = (IOS7); // enable output compare
TC7_HI = TCNT_HI; // cause match to reset counter
I have used this for certain applications so whether it is wise or not probably depends on what it is used for - since the main timer is used for all channels it may disturb something which is relaying on a normal free-running main timer....
The output compare is used to match the main timer value with a reference. Only a timer 7 match can be used to reset the timer and so channel 7 compare can be programmed with a value determining a specific frequency when its output is programmed to toggle on each match.
By using two channels a PWM signal can be generated:
EG:
Set channel 7 match to cause the main timer to be reset and toggle its output at 0x8000.
Set channel 4 to match at 0x2000 and toggle its output on match
The channel 7 will be a square wave and the channel 4 output will be a pulse of mark-space 25%.
Channels can be mixed to produce more complicated waveforms.
If you want to produce a fixed duration pulse, the pulse duration is limited by the 16 bit timer's maximum count value and the input clock frequency and will have a maximum pulse length of generally a few hundred ms. A match can toggle, set or clear an output so an accurate pulse can be generated without the processor having to be involved. However an interrupt is usually also used to stop the timer after the event has taken place.
I hope this helps. It is always best to use a debugger and experiment since the timers are rather difficult to understand but can be used quite flexibly - you just have to experiment.
If you have a more specific question I can try to give a more detailed answer.
Regards
Mark Butcher
www.mjbc.ch
hi:
resetting the main timer should not be done in any application. the code below initializes the timer and below that is an isr
bset tim0_tios,%00010000 ;timer0 ch 4 is output compare
bset tim0_tscr1,%10010000 ;d7 =timer enable,d6.d5 wait and freeze operation,d4 fast flag clear
bset tim0_tie,%00010000 ;ch4 enabled to interrupt bus
bset tim0_tscr2,%00000001 ;prescale to clock over 2 or 10 mhz 100 ns
ldd tim0_tcnt ;fetch the current counter
addd #1500 ;add the timer period
std tim0_tc4 ;schedule the next interrupt/clear the flag
cli ;interrupt mask cleared
svc_tim0_ch04 equ * ;timer0 channel 4
ldd tim0_tcnt ;fetch the current timer count
addd #10000 ;add the timer period for 1 ms
std tim0_tc4 ;update the compare register/clear the flag
insert your code here
rti
this will cause the interrupt to occur on a timed basis. as you see, you add the current main timer to a variable to schedule the next interrupt. if you only want a "one-shot" simply clear the interrupt mask bit before exiting the isr.
hope this helps,
ed