<!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 Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Data Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related 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 <avr/io.h></span>
00019 <span class="preprocessor">#include <avr/interrupt.h></span>
00020 <span class="preprocessor">#include <avr/pgmspace.h></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<<1;
00119 }
00120 <span class="keywordflow">else</span>
00121 {
00122 <span class="comment">// if nPulses is zero, run forever</span>
00123 PulseT1AMode &= ~PULSE_MODE_COUNTED;
00124 PulseT1ACount = 1<<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<<1;
00151 }
00152 <span class="keywordflow">else</span>
00153 {
00154 <span class="comment">// if nPulses is zero, run forever</span>
00155 PulseT1BMode &= ~PULSE_MODE_COUNTED;
00156 PulseT1BCount = 1<<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, >>1 equivalent to /2</span>
00198 <span class="keywordflow">return</span> (PulseT1ACount+1)>>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, >>1 equivalent to /2</span>
00205 <span class="keywordflow">return</span> (PulseT1BCount+1)>>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)<<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>>8), OCR1AH); // write high byte</span>
00222 <span class="comment">//outp((OCValue & 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 & 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)<<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>>8), OCR1BH); // write high byte</span>
00260 <span class="comment">//outp((OCValue & 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 & 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
<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>
|