?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{FILE START}

library

?curdirlinks? - Rev 6

?prevdifflink? - Blame - ?getfile?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Procyon AVRlib: pulse.c Source File</title>
<link href="dox.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.2 -->
<div class="qindex"><a class="qindex" href="main.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
<h1>pulse.c</h1><a href="pulse_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*! \file pulse.c \brief Pulse/frequency generation function library. */</span>
00002 <span class="comment">//*****************************************************************************</span>
00003 <span class="comment">//</span>
00004 <span class="comment">// File Name    : 'pulse.c'</span>
00005 <span class="comment">// Title        : Pulse/frequency generation function library</span>
00006 <span class="comment">// Author       : Pascal Stang - Copyright (C) 2000-2002</span>
00007 <span class="comment">// Created      : 2002-08-19</span>
00008 <span class="comment">// Revised      : 2003-05-29</span>
00009 <span class="comment">// Version      : 0.7</span>
00010 <span class="comment">// Target MCU   : Atmel AVR Series</span>
00011 <span class="comment">// Editor Tabs  : 4</span>
00012 <span class="comment">//</span>
00013 <span class="comment">// This code is distributed under the GNU Public License</span>
00014 <span class="comment">//      which can be found at http://www.gnu.org/licenses/gpl.txt</span>
00015 <span class="comment">//</span>
00016 <span class="comment">//*****************************************************************************</span>
00017 
00018 <span class="preprocessor">#include &lt;avr/io.h&gt;</span>
00019 <span class="preprocessor">#include &lt;avr/interrupt.h&gt;</span>
00020 <span class="preprocessor">#include &lt;avr/pgmspace.h&gt;</span>
00021 
00022 <span class="preprocessor">#include "<a class="code" href="global_8h.html">global.h</a>"</span>
00023 <span class="preprocessor">#include "<a class="code" href="timer_8h.html">timer.h</a>"</span>
00024 <span class="preprocessor">#include "<a class="code" href="pulse_8h.html">pulse.h</a>"</span>
00025 
00026 <span class="comment">// Global variables</span>
00027 <span class="comment">// pulse generation registers</span>
00028 <span class="keyword">volatile</span> <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>  PulseT1AMode;
00029 <span class="keyword">volatile</span> <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> PulseT1ACount;
00030 <span class="keyword">volatile</span> <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> PulseT1APeriodTics;
00031 <span class="keyword">volatile</span> <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>  PulseT1BMode;
00032 <span class="keyword">volatile</span> <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> PulseT1BCount;
00033 <span class="keyword">volatile</span> <span class="keyword">static</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> PulseT1BPeriodTics;
00034 
00035 <span class="comment">// pulse mode bit definitions</span>
00036 <span class="comment">// PULSE_MODE_COUNTED</span>
00037 <span class="comment">//      if true, the requested number of pulses are output, then output is turned off</span>
00038 <span class="comment">//      if false, pulses are output continuously</span>
00039 <span class="preprocessor">#define PULSE_MODE_CONTINUOUS   0x00</span>
00040 <span class="preprocessor"></span><span class="preprocessor">#define PULSE_MODE_COUNTED      0x01</span>
00041 <span class="preprocessor"></span>
00042 <span class="comment">// functions</span>
00043 
00044 <span class="keywordtype">void</span> pulseInit(<span class="keywordtype">void</span>)
00045 {
00046     <span class="comment">// initialize timer1 for pulse operation</span>
00047     pulseT1Init();
00048 }
00049 
00050 <span class="keywordtype">void</span> pulseT1Init(<span class="keywordtype">void</span>)
00051 {
00052     <span class="comment">// try to make sure that timer1 is in "normal" mode</span>
00053     <span class="comment">// most importantly, turn off PWM mode</span>
00054     <a class="code" href="group__timerpwm.html#ga2">timer1PWMOff</a>();
00055 
00056     <span class="comment">// set some reasonable initial values</span>
00057     <span class="comment">// in case the user forgets to</span>
00058     PulseT1AMode = 0;
00059     PulseT1BMode = 0;
00060     PulseT1ACount = 0;
00061     PulseT1BCount = 0;
00062     PulseT1APeriodTics = 0x8000;
00063     PulseT1BPeriodTics = 0x8000;
00064 
00065     <span class="comment">// attach the pulse service routines to</span>
00066     <span class="comment">// the timer 1 output compare A and B interrupts</span>
00067     <a class="code" href="group__timer.html#ga8">timerAttach</a>(TIMER1OUTCOMPAREA_INT,pulseT1AService);
00068     <a class="code" href="group__timer.html#ga8">timerAttach</a>(TIMER1OUTCOMPAREB_INT,pulseT1BService);
00069 }
00070 
00071 <span class="keywordtype">void</span> pulseT1Off(<span class="keywordtype">void</span>)
00072 {
00073     <span class="comment">// turns pulse outputs off immediately</span>
00074     
00075     <span class="comment">// set pulse counters to zero (finished)</span>
00076     PulseT1ACount = 0;
00077     PulseT1BCount = 0;
00078     <span class="comment">// disconnect OutputCompare action from OC1A pin</span>
00079     cbi(TCCR1A,COM1A1);
00080     cbi(TCCR1A,COM1A0);
00081     <span class="comment">// disconnect OutputCompare action from OC1B pin</span>
00082     cbi(TCCR1A,COM1B1);
00083     cbi(TCCR1A,COM1B0);
00084     <span class="comment">// detach the pulse service routines</span>
00085     <a class="code" href="group__timer.html#ga9">timerDetach</a>(TIMER1OUTCOMPAREA_INT);
00086     <a class="code" href="group__timer.html#ga9">timerDetach</a>(TIMER1OUTCOMPAREB_INT);
00087 }
00088 
00089 <span class="keywordtype">void</span> pulseT1ASetFreq(u16 freqHz)
00090 {
00091     <span class="comment">// set the frequency of the pulse output</span>
00092     <span class="comment">// we need to find the requested period/2 (in timer tics)</span>
00093     <span class="comment">// from the frequency (in hertz)</span>
00094 
00095     <span class="comment">// calculate how many tics in period/2</span>
00096     <span class="comment">// this is the (timer tic rate)/(2*requested freq)</span>
00097     PulseT1APeriodTics = ((u32)F_CPU/((u32)<a class="code" href="group__timer.html#ga7">timer1GetPrescaler</a>()*2*freqHz));
00098 }
00099 
00100 <span class="keywordtype">void</span> pulseT1BSetFreq(u16 freqHz)
00101 {
00102     <span class="comment">// set the frequency of the pulse output</span>
00103     <span class="comment">// we need to find the requested period/2 (in timer tics)</span>
00104     <span class="comment">// from the frequency (in hertz)</span>
00105 
00106     <span class="comment">// calculate how many tics in period/2</span>
00107     <span class="comment">// this is the (timer tic rate)/(2*requested freq)</span>
00108     PulseT1BPeriodTics = ((u32)F_CPU/((u32)<a class="code" href="group__timer.html#ga7">timer1GetPrescaler</a>()*2*freqHz));
00109 }
00110 
00111 <span class="keywordtype">void</span> pulseT1ARun(u16 nPulses)
00112 {
00113     <span class="comment">// set the number of pulses we want and the mode</span>
00114     <span class="keywordflow">if</span>(nPulses)
00115     {
00116         <span class="comment">// if the nPulses is non-zero, use "counted" mode</span>
00117         PulseT1AMode |= PULSE_MODE_COUNTED;
00118         PulseT1ACount = nPulses&lt;&lt;1;
00119     }
00120     <span class="keywordflow">else</span>
00121     {
00122         <span class="comment">// if nPulses is zero, run forever</span>
00123         PulseT1AMode &amp;= ~PULSE_MODE_COUNTED;
00124         PulseT1ACount = 1&lt;&lt;1;
00125     }
00126     <span class="comment">// set OutputCompare action to toggle OC1A pin</span>
00127     cbi(TCCR1A,COM1A1);
00128     sbi(TCCR1A,COM1A0);
00129 
00130     <span class="comment">// now the "enabling" stuff</span>
00131 
00132     <span class="comment">// set the output compare one pulse cycle ahead of current timer position </span>
00133     <span class="comment">// to make sure we don't have to wait until the timer overflows and comes</span>
00134     <span class="comment">// back to the current value</span>
00135     <span class="comment">// set future output compare time to TCNT1 + PulseT1APeriodTics</span>
00136     <span class="comment">//outw(OCR1A, inw(TCNT1) + PulseT1APeriodTics);</span>
00137     OCR1A += PulseT1APeriodTics;
00138 
00139     <span class="comment">// enable OutputCompare interrupt</span>
00140     sbi(TIMSK, OCIE1A);
00141 }
00142 
00143 <span class="keywordtype">void</span> pulseT1BRun(u16 nPulses)
00144 {
00145     <span class="comment">// set the number of pulses we want and the mode</span>
00146     <span class="keywordflow">if</span>(nPulses)
00147     {
00148         <span class="comment">// if the nPulses is non-zero, use "counted" mode</span>
00149         PulseT1BMode |= PULSE_MODE_COUNTED;
00150         PulseT1BCount = nPulses&lt;&lt;1;
00151     }
00152     <span class="keywordflow">else</span>
00153     {
00154         <span class="comment">// if nPulses is zero, run forever</span>
00155         PulseT1BMode &amp;= ~PULSE_MODE_COUNTED;
00156         PulseT1BCount = 1&lt;&lt;1;
00157     }
00158     <span class="comment">// set OutputCompare action to toggle OC1B pin</span>
00159     <span class="comment">// (note: with all the A's and B's flying around, TCCR1A is not a bug)</span>
00160     cbi(TCCR1A,COM1B1);
00161     sbi(TCCR1A,COM1B0);
00162 
00163     <span class="comment">// now the "enabling" stuff</span>
00164 
00165     <span class="comment">// set the output compare one pulse cycle ahead of current timer position </span>
00166     <span class="comment">// to make sure we don't have to wait until the timer overflows and comes</span>
00167     <span class="comment">// back to the current value</span>
00168     <span class="comment">// set future output compare time to TCNT1 + PulseT1APeriodTics</span>
00169     <span class="comment">//outw(OCR1B, inw(TCNT1) + PulseT1BPeriodTics);</span>
00170     OCR1B += PulseT1BPeriodTics;
00171 
00172     <span class="comment">// enable OutputCompare interrupt</span>
00173     sbi(TIMSK, OCIE1B);
00174 }
00175 
00176 <span class="keywordtype">void</span> pulseT1AStop(<span class="keywordtype">void</span>)
00177 {
00178     <span class="comment">// stop output regardless of remaining pulses or mode</span>
00179     <span class="comment">// go to "counted" mode</span>
00180     PulseT1AMode |= PULSE_MODE_COUNTED;
00181     <span class="comment">// set pulses to zero</span>
00182     PulseT1ACount = 0;
00183 }
00184 
00185 <span class="keywordtype">void</span> pulseT1BStop(<span class="keywordtype">void</span>)
00186 {
00187     <span class="comment">// stop output regardless of remaining pulses or mode</span>
00188     <span class="comment">// go to "counted" mode</span>
00189     PulseT1BMode |= PULSE_MODE_COUNTED;
00190     <span class="comment">// set pulses to zero</span>
00191     PulseT1BCount = 0;
00192 }
00193 
00194 u16 pulseT1ARemaining(<span class="keywordtype">void</span>)
00195 {
00196     <span class="comment">// return the number of pulses remaining for channel A</span>
00197     <span class="comment">// add 1 to make sure we round up, &gt;&gt;1 equivalent to /2</span>
00198     <span class="keywordflow">return</span> (PulseT1ACount+1)&gt;&gt;1;
00199 }
00200 
00201 u16 pulseT1BRemaining(<span class="keywordtype">void</span>)
00202 {
00203     <span class="comment">// return the number of pulses remaining for channel A</span>
00204     <span class="comment">// add 1 to make sure we round up, &gt;&gt;1 equivalent to /2</span>
00205     <span class="keywordflow">return</span> (PulseT1BCount+1)&gt;&gt;1;
00206 }
00207 
00208 <span class="keywordtype">void</span> pulseT1AService(<span class="keywordtype">void</span>)
00209 {
00210     <span class="comment">// check if TimerPulseACount is non-zero</span>
00211     <span class="comment">//      (i.e. pulses are still requested)</span>
00212     <span class="keywordflow">if</span>(PulseT1ACount)
00213     {
00214         <span class="comment">//u16 OCValue;</span>
00215         <span class="comment">// read in current value of output compare register OCR1A</span>
00216         <span class="comment">//OCValue =  inp(OCR1AL);       // read low byte of OCR1A</span>
00217         <span class="comment">//OCValue += inp(OCR1AH)&lt;&lt;8;    // read high byte of OCR1A</span>
00218         <span class="comment">// increment OCR1A value by PulseT1APeriodTics</span>
00219         <span class="comment">//OCValue += PulseT1APeriodTics;</span>
00220         <span class="comment">// set future output compare time to this new value</span>
00221         <span class="comment">//outp((OCValue&gt;&gt;8),        OCR1AH);    // write high byte</span>
00222         <span class="comment">//outp((OCValue &amp; 0x00FF),OCR1AL);  // write low byte</span>
00223 
00224         <span class="comment">// the following line should be identical in operation</span>
00225         <span class="comment">// to the lines above, but for the moment, I'm not convinced</span>
00226         <span class="comment">// this method is bug-free.  At least it's simpler!</span>
00227         <span class="comment">//outw(OCR1A, inw(OCR1A) + PulseT1APeriodTics);</span>
00228         <span class="comment">// change again</span>
00229         OCR1A += PulseT1APeriodTics;
00230                         
00231         <span class="comment">// decrement the number of pulses executed</span>
00232         <span class="keywordflow">if</span>(PulseT1AMode &amp; PULSE_MODE_COUNTED)
00233             PulseT1ACount--;
00234     }
00235     <span class="keywordflow">else</span>
00236     {
00237         <span class="comment">// pulse count has reached zero</span>
00238         <span class="comment">// disable the output compare's action on OC1A pin</span>
00239         cbi(TCCR1A,COM1A1);
00240         cbi(TCCR1A,COM1A0);
00241         <span class="comment">// and disable the output compare's interrupt to stop pulsing</span>
00242         cbi(TIMSK, OCIE1A);
00243     }
00244 }
00245 
00246 <span class="keywordtype">void</span> pulseT1BService(<span class="keywordtype">void</span>)
00247 {
00248     <span class="comment">// check if TimerPulseACount is non-zero</span>
00249     <span class="comment">//      (i.e. pulses are still requested)</span>
00250     <span class="keywordflow">if</span>(PulseT1BCount)
00251     {
00252         <span class="comment">//u16 OCValue;</span>
00253         <span class="comment">// read in current value of output compare register OCR1B</span>
00254         <span class="comment">//OCValue =  inp(OCR1BL);       // read low byte of OCR1B</span>
00255         <span class="comment">//OCValue += inp(OCR1BH)&lt;&lt;8;    // read high byte of OCR1B</span>
00256         <span class="comment">// increment OCR1B value by PulseT1BPeriodTics</span>
00257         <span class="comment">//OCValue += PulseT1BPeriodTics; </span>
00258         <span class="comment">// set future output compare time to this new value</span>
00259         <span class="comment">//outp((OCValue&gt;&gt;8),        OCR1BH);    // write high byte</span>
00260         <span class="comment">//outp((OCValue &amp; 0x00FF),OCR1BL);  // write low byte</span>
00261 
00262         <span class="comment">// the following line should be identical in operation</span>
00263         <span class="comment">// to the lines above, but for the moment, I'm not convinced</span>
00264         <span class="comment">// this method is bug-free.  At least it's simpler!</span>
00265         <span class="comment">//outw(OCR1B, inw(OCR1B) + PulseT1BPeriodTics);</span>
00266         <span class="comment">// change again</span>
00267         OCR1B += PulseT1BPeriodTics;
00268 
00269         
00270         <span class="comment">// decrement the number of pulses executed</span>
00271         <span class="keywordflow">if</span>(PulseT1BMode &amp; PULSE_MODE_COUNTED)
00272             PulseT1BCount--;
00273     }
00274     <span class="keywordflow">else</span>
00275     {
00276         <span class="comment">// pulse count has reached zero</span>
00277         <span class="comment">// disable the output compare's action on OC1B pin</span>
00278         cbi(TCCR1A,COM1B1);
00279         cbi(TCCR1A,COM1B0);
00280         <span class="comment">// and disable the output compare's interrupt to stop pulsing</span>
00281         cbi(TIMSK, OCIE1B);
00282     }
00283 }
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Oct 29 03:41:07 2006 for Procyon AVRlib by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.2 </small></address>
</body>
</html>
{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3