<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>shapeshifter.se &#187; microcontroller</title>
	<atom:link href="http://www.shapeshifter.se/tag/microcontroller/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.shapeshifter.se</link>
	<description>Mostly miscellaneous technical mumbo-jumbo.</description>
	<lastBuildDate>Sat, 12 Dec 2009 12:00:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>AVR System Timer</title>
		<link>http://www.shapeshifter.se/2009/06/02/avr-system-timer/</link>
		<comments>http://www.shapeshifter.se/2009/06/02/avr-system-timer/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 10:17:41 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[microcontroller]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=546</guid>
		<description><![CDATA[Handy system clock for AVR 8-bit microcontrollers suitable for measuring elapsed time or for use with timers. This provides
a monotonic time since system startup (like the POSIX CLOCK_MONOTONIC).
The system clock is based around a 32kHz clock crystal and one of the 8-bit timers provided by the AVR, it is possible to use the CPU frequency [...]]]></description>
			<content:encoded><![CDATA[<p>Handy system clock for AVR 8-bit microcontrollers suitable for measuring elapsed time or for use with timers. This provides<br />
a monotonic time since system startup (like the POSIX CLOCK_MONOTONIC).</p>
<p>The system clock is based around a 32kHz clock crystal and one of the 8-bit timers provided by the AVR, it is possible to use the CPU frequency as a timer base as  long as it&#8217;s a nice, dividable, frequency.<br />
To be able to provide a stable 1 Hz clock but still have sub-second precision we divide 1 second into an arbitrary number of<br />
system ticks. To minimize CPU usage the tick counter should be increased at each interrupt, this means that the number of<br />
ticks per second we we choose determines our interrupt frequency and timer resolution.<br />
How to choose number of ticks? It all depends on your required resolution, if you only want a 1 second resolution a tick and a second becomes equal.</p>
<p>The AVR timer is a 8-bit register that simply counts at the rate of its clock source. The clock source can be either the CPU<br />
clock or an external oscillator, the clock source is also subject to a prescaler to further decrease the frequency.<br />
The timer then generates an interrupt on overflow and/or when it hits a pre-configured value.<br />
Since its a 8-bit timer, we have a maximum of 256 cycles before an interrupt is generated, a smaller interval can be achieved by using the comparator match to generate an interrupt at a specific value.</p>
<p>This example is creating a 1/32 second resolution timer (32 ticks per second) using an external 32768 Hz watch crystal.<br />
<em>comp</em> is the comparator value, to avoid re-arming it with different values it should be limited to 128 or 256, otherwise it has to be changed at each interrupt.</p>
<img src='http://s.wordpress.com/latex.php?latex=F_%7Btimer%7D%20%3D%2032768&#038;bg=FAFAFA&#038;fg=000000&#038;s=1' alt='F_{timer} = 32768' title='F_{timer} = 32768' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=ticks%20%3D%2032&#038;bg=FAFAFA&#038;fg=000000&#038;s=1' alt='ticks = 32' title='ticks = 32' class='latex' />
<p>The following to equations can be used to calculate either <em>comp</em> or the <em>prescale</em> value.<br />
<em>prescale</em> is limited by the target device, but common values are powers of 2 (8,32,64,128,256,1024).</p>
<p style="text-align: center;"><img src='http://s.wordpress.com/latex.php?latex=comp%20%3D%20%5Cfrac%7B%5Cfrac%7BF_%7Btimer%7D%7D%7Bprescale%7D%7D%7Bticks%7D&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='comp = \frac{\frac{F_{timer}}{prescale}}{ticks}' title='comp = \frac{\frac{F_{timer}}{prescale}}{ticks}' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=prescale%20%3D%20%5Cfrac%7BF_%7Btimer%7D%7D%7Bcomp%20%5Ctimes%20ticks%7D&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='prescale = \frac{F_{timer}}{comp \times ticks}' title='prescale = \frac{F_{timer}}{comp \times ticks}' class='latex' /></p>
<p>Using 128 as the <em>comp</em> value and inserting the other values into equation 2 yields the following prescaler</p>
<p style="text-align: center;">
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B32768%7D%7B128%20%5Ctimes%2032%7D%20%3D%208&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='\frac{32768}{128 \times 32} = 8' title='\frac{32768}{128 \times 32} = 8' class='latex' />
</p>
<p>So, a prescaler of 8 gives us two interrupts per 256 cycles, one at 128 and one at 256 (overflow). Using 256 as <em>comp</em> would yield a perscaler of 4 but the target device I used didn&#8217;t have a TS/4 prescaler.</p>
<p>Complete source code for a 1/32 (or 31.25ms) second resolution timer for the ATmegaxx4 using Timer 2 and a 32kHz watch crystal connected to the pins TOSC1 and TOSC2.<br />
Requires <a href="http://www.nongnu.org/avr-libc/">AVR libc</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;avr/io.h&gt;</span>
<span style="color: #339933;">#include &lt;avr/interrupt.h&gt;</span>
&nbsp;
<span style="color: #993333;">typedef</span> uint32_t clock_time_t<span style="color: #339933;">;</span>
<span style="color: #993333;">static</span> clock_time_t global_system_ticks <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* ISR for the timer overflow */</span>
ISR<span style="color: #009900;">&#40;</span>TIMER2_OVF_vect<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    global_system_ticks<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* ISR for the comparator */</span>
ISR<span style="color: #009900;">&#40;</span>TIMER2_COMPA_vect<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    global_system_ticks<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Return number of elapsed ticks */</span>
clock_time_t clock_time<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>global_system_ticks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Return number of elapsed seconds */</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> clock_seconds<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    uint32_t tmp<span style="color: #339933;">;</span>
&nbsp;
    TIMSK2 <span style="color: #339933;">&amp;=</span> ~<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    tmp <span style="color: #339933;">=</span> global_system_ticks <span style="color: #339933;">/</span> <span style="color: #0000dd;">32</span><span style="color: #339933;">;</span>
    TIMSK2 <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>tmp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> clock_init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Enable external oscillator (32 kHz crystal) connected to TOSC{1,2} */</span>
    ASSR <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> AS2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Reset timer */</span>
    TCNT2 <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Set TS/8 prescaler, results in a 4096Hz clock */</span>
    TCCR2B <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> CS21<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Compare at half counter value */</span>
    OCR2A <span style="color: #339933;">=</span> <span style="color: #0000dd;">128</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/*
     * Enable overflow and compare interrupt.
     * Triggers each 1/32 secs
     */</span>
    TIMSK2 <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/06/02/avr-system-timer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
