📄 chapter7.htm
字号:
</code></pre>
<h3>Other Features and Special Calling Procedures</h3>
<p> This component was developed for use with the baud rate measurement program.
The argument baud_value in the constructor is the divisor by which the clock rate is
divided to determine the baud rate of the serial port.
<h3>Coding Examples</h3>
<pre><code>
#include <serio1.h>
.
.
.
#define SERIO_BAUD_19200 19200 /* serial port parameters */
#define SERIO_INT_VECTOR 0x40
#define SERIO_IARB 10
#define SERIO_INT_LEVEL 3
.
.
.
/* function prototypes */
void printd(unsigned long);
WORD get_baud(BYTE number, Timer *t3);
.
.
.
Serial_io *sio;
io_command_block *oob1,ob1;
BYTE pszMessage[]="The selected baud rate is ";
BYTE pszMessage1[]=" bits per second\n\r";
WORD baud;
unsigned long baud_rate;
.
.
.
cli(); /* enable system interrupts */
baud=get_baud(1,t3);/* measure the baud rate */
.
.
.
/* set up the serial communications */
sio=serial1_io_(baud, /* value returned from get_baud() */
SERIO_INT_VECTOR, /* interrupt vector */
SERIO_IARB, /* iarb */
SERIO_INT_LEVEL); /* and interrupt level */
/* set up the io blocks */
oob1=&ob1; /* output block */
oob1->call_complete=TRUE; /* have no message going out */
oob1->io_command=OUTPUT; /* oob1 is always output */
oob1->buffer=pszMessage; /* select the message */
oob1->buffer_length= sizeof pszMessage;
serial_io(sio,oob1); /* message to the i/o object */
while(!oob1->call_complete)
; /* wait until transmission is done */
baud_rate=500000ul/baud;
printd(baud_rate); /* send baud rate to screen */
oob1->buffer=pszMessage1;
oob1->buffer_length= sizeof pszMessage1;
serial_io(sio,oob1); /* send out rest of message */
while(!oob1->call_complete)
;
</code></pre>
<h2><a name="timer_output_compare">Data Sheet -- Output Compare Timer Subsystem </a></h2>
<h3>Device Name and description</h3>
<h3>Timer</h3><p>--Timer is a component that implements the four Output Compare Subsystems
found in the General Purpose Timer. These timers can be used to create events in time.
<h3>Super Classes</h3>
<p>Timer inherits the features of the error handler. The error handler inherits the features
of the class object.
<h3>Attributes</h3>
<pre><code>
WORD who_am_I; /* output compare number */
WORD ms_tick; /* Timer clock cycles */
/* between interrupts */
void (*reset)(struct time *); /* see Methods below */
void *hook_object; /* external function argument */
void (*hook_method)(void*); /* see Methods below */
</code></pre>
<h3>Methods</h3>
<pre><code>
void error_hand(void *, int, int) /* from Error_handler */
arguments /* see Error_handler */
void exercise( Object * ) /* from Object */
arguments /* See Object */
void (*reset)(struct time *); /* reset specific timer */
void (*hook_method)(void*); /* external function to */
/* be executed during each */
/* Output Compare interrupt */
/* the argument of this */
/* function is the value */
/* pointed to by hook_object */
</code></pre>
<h4>Constructor</h4>
<pre><code>
Timer* timer_(Timer_parameters *); /* Timer_parameters is a */
/* timer parameter block */
/* described below in the */
/* Other Features and Special */
/* Calling Procedures section */
</code></pre>
<h4>Destructor</h4>
<pre><code>
void timer__(Timer*);
</code></pre>
<h4>Macro Methods</h4>
<pre><code>
#define attach_object(a,b) ((a)->hook_object=(b))
#define attach_method(a,b) ((a)->hook_method=(b))
</code></pre>
<p> Here the parameter a is a pointer to a properly instantiated Timer. The parameter
b in attach_method() is a pointer to a function that will be executed during the interrupt
service routine of the timer identified in the parameter a. In the attach_object() method,
the parameter b is a pointer to the argument of the function identified by hook_method().
<h3>Header File</h3>
<pre><code>
#ifndef TIMER_H
#define TIMER_H
#include "defines.h"
#include "error.h"
#ifndef GPT_IARB
#define GPT_IARB 12 /* iarb value of 12 for the GPT */
#define GPT_VBA 5 /* GPT vectors start at 0x50 */
#define GPT_LEVEL 6 /* use interrupt level 6 */
#endif
typedef enum BYTE
{
DISCONNECT,
TOGGLE,
CLEAR,
SET
}Output;
typedef struct
{
WORD number,
tick;
Output action;
BYTE OC1_connect,
connect_data;
Boolean interrupt;
} Timer_parameters;
#define TIMER_CLASS \
ERROR_HANDLER \
WORD who_am_I;\
WORD ms_tick; \
void (*reset)(struct time *); \
void *hook_object;\
void (*hook_method)(void*);
typedef struct time
{
TIMER_CLASS
}Timer;
#ifndef ATTACH
#define ATTACH
#define attach_object(a,b) ((a)->hook_object=(b))
#define attach_method(a,b) ((a)->hook_method=(b))
#endif
Timer* timer_(Timer_parameters *);
void timer__(Timer*);
#endif
</code></pre>
<h3>Other Features and Special Calling Procedures</h3>
<p>
Almost all of the operations involving Output Compare timers will require
interrupts. Timer interrupts can be quite important. Therefore, it was decided in the
design of the Timer component to "hard wire" the interrupt set-up in the constructor of
the class. Therefore, as it is done here, the programmer has no say in things like interrupt
level, etc. The specific values for these parameters are defined in the header file as
shown below.
<pre><code>
#define GPT_IARB 12 /* iarb value of 12 for the GPT */
#define GPT_VBA 5 /* GPT vectors start at 0x50 */
#define GPT_LEVEL 6 /* use interrupt level 6 */
</code></pre>
<p> The interrupt level of 6 is used because, the Timer interrupt service routines are
quick and the operations that must be executed during timer interrupts can be of very
high priority. The IARB, interrupt arbitration level, is used when two interrupts at the
same level request an interrupt at the same time. The IARB range is from 0 to 15 with 15
being the highest priroity. When two, or more, interrupts occur at the same time and at
the same level, the module with the largest IARB will be processed first. There is no
important reason, but it was decided to place all of the timer interrupt vectors in the
vector table starting at 0x50. These parameters can be changed by the programmer if it
needed.
<p> Six parameters are required to specify an Output Compare timer. These
parameters are gathered into a timer_parameters structure and a poiner to this structure is
passed to the timer constructor. A copy of this structure is shown below:
<pre><code>
typedef struct
{
WORD number,
tick;
Output action;
BYTE OC1_connect,
connect_data;
Boolean interrupt;
} Timer_parameters;
</code></pre>
<p> The parameter number is the specific output compare time being set-up. During
the execution of the interrupt service routine, the value tick is added to the specific TOCx
register. When the Timer Counter Register reaches this value later, the next event for
this output compare will occur. The paramete action contains one of the values found in
the typedef of Output. This value describes the action that will take place on the
specified output compare pin. The output compare number 1 can be coupled to any other
output compare. OC1_connect indicates that the output pin of this output compare will
be connected to OC1, and connect_data describes the output that will occur at the OCx
pin when OC1 occurs. Finally, the parameter interrupt can have values YES or NO to
indicate whether an interrupt service routine should be created for this timer and the
interrupt should be enabled.
<h3>Coding Examples</h3>
<pre><code>
#include <timer.h>
.
.
.
#define TIMECOUNT 4000
#define ONE_SECOND 1000
.
.
.
/* function prototype */
void count_ticks(WORD *);
.
.
.
Timer_parameters tp; /* timer parameter block */
WORD seconds,minutes,....;
WORD count;
Timer *t3;
.
.
.
main()
{
.
.
.
/* set up the timer parameter structure */
tp.number=3; /* use output compare number 3 */
tp.tick=TIMECOUNT; /* 1 ms interrupts */
tp.action=0; /* no output action */
tp.OC1_connect=0; /* OC1 not connected to another OC */
tp.connect_data=0;
tp.interrupt=YES; /* need an interrupt here */
t3=timer_(&tp); /* instantiate the timer */
attach_object(t3,&count); /* attach object and method to timer*/
attach_method(t3,count_ticks);
.
.
.
count=0; /* initialize count */
cli(); /* enable the system interrupts */
.
.
.
/* applications portion of the program */
FOREVER
{
if(count>=ONE_SECOND) /* count is incremented in the isr */
{
count=0;
if(++seconds>=60)
{
seconds=0;
if(++minutes>=60)
{
.
.
.
/* function to be executed in the isr */
void count_ticks(WORD *a)
{
++*a;
}
</code></pre>
<h2><a name="timer1_input_capture">Data Sheet -- Input Capture Timer Subsystem </a></h2>
<h3>Device Name and description</h3>
<h3>Timer1</h3><p>--Timer1 implements the three Input Capture subsystems found in the General
Purpose Timer. These devices are able to measure the time between events.
<h3>Super Classes</h3>
<p>Timer1 inherits the features of the error handler. The error handler inherits the features
of the class object.
<h3>Attributes</h3>
<pre><code>
WORD who_am_I; /* number of the Input Capture 1-3 */
Edges edge; /* definition of input event See
typedef of Edges in the header file*/
void (*hook_method)(void*); /* function to be executed by isr */
void *hook_object; /* argument of function executed by isr */
</code></pre>
<h3>Methods</h3>
<pre><code>
void error_hand(void *, int, int) /* from Error_handler */
arguments /* see Error_handler */
void exercise( Object * ) /* from Object */
arguments /* See Object */
WORD capture_time(Timer1 *);
void set_edge(BYTE number, Edges edge); /* sets a new event to a
specific numbered timer */
void new_edge(Timer1 *,Edges ); /* sets a new event to a specific
instantiated Timer1 */
Boolean get_status(Timer1 *); /* returns the state of the
input capture interrupt flag */
</code></pre>
<h4>Constructor</h4>
<pre><code>
Timer1* timer1_(BYTE number, /* Input Capture number */
Edges edge, /* definition of edge event */
Boolean interrupt); /* interrupt?-- YES or NO */
</code></pre>
<h4>Destructor</h4>
<pre><codeP
void timer1__(Timer1 *);
</code></pre>
<h4>Macro Methods</h4>
<pre><code>
#define attach_object(a,b) ((a)->hook_object=(b))
#define attach_method(a,b) ((a)->hook_method=(b))
</code></pre>
<p> Here the parameter a is a pointer to a properly instantiated Timer1. The
parameter b in attach_method() is a pointer to a function that will be executed during the
interrupt service routine of the timer identified in the parameter a. In the attach_object()
method, the parameter b is a pointer to the argument of the function identified by
hook_method().
<h3>Header File</h3>
<pre><code>
#ifndef TIMER1_H
#define TIMER1_H
#include "defines.h"
#include "error.h"
#ifndef GPT_IARB
#define GPT_IARB 12 /* iarb value of 12 for the GPT */
#define GPT_VBA 5 /* GPT vectors start at 0x50 */
#define GPT_LEVEL 6 /* use interrupt level 6 */
#endif
typedef enum BYTE
{
DISABLE,
RISING,
FALLING,
ANY
}Edges;
#define TIMER1_CLASS \
ERROR_HANDLER \
WORD who_am_I; \
Edges edge; \
void *hook_object;\
void (*hook_method)(void*);
typedef struct
{
TIMER1_CLASS
}Timer1;
#ifndef ATTACH
#define ATTACH
#define attach_object(a,b) ((a)->hook_object=(b))
#define attach_method(a,b) ((a)->hook_method=(b))
#endif
WORD capture_time(Timer1 *);
void set_edge(BYTE number, Edges edge);
void new_edge(Timer1 *,Edges );
Boolean get_status(Timer1 *);
Timer1* timer1_(BYTE number, Edges edge, Boolean interrupt);
void timer1__(Timer1 *);
#endif
</code></pre>
<h3>Other Features and Special Calling Procedures</h3>
<p>
This component is set-up by execution of the constructor. There is no need to
prepare a parameter block to operate this function. There are four methods that give
insight into the operation of the input captures. One, set_edge() will set the event for any
timer without regard to whether it is a part of an instantiated Timer1 or not. This method
should not be used externally. The function capture_time() returns the last value
captured by the specified input capture subsystem. The method new_edge() changes the
event edge event definition for the specified Timer1, and get_status() returns the
specified input capture interrupt flag, whether an interrupt is requested or not.
<h3>Coding Examples</h3>
<pre><code>
#include <timer.h>
#include <timer1.h>
#include <delay.h>
#include <semaphor.h>
.
.
.
/* function to measure the time of 1 serial character to determine its baud
rate */
WORD get_baud(BYTE number, Timer *t3)
{
WORD start_time;
Semaphore *s;
Timer1 *t;
Delay *d;
s=semaphore_(); /* create semaphore */
t=timer1_(number,FALLING,NO); /* build an Input Capture timer */
/* number is Input Capture number, */
/* event is FALLING edge and NO interrupt */
while(!get_status(t))
; /* wait until an event occurs */
start_time=capture_time(t); /* get time immediately */
new_edge(t,RISING); /* set the event to a rising edge */
d=delay_(t3,s,11); /* t3 must be 1 ms timer to delay 11 ms */
wait_for_semaphore(s); /* wait out the delay */
start_time=capture_time(t)-start_time /* character time */
timer1__(t); /* get rid of this timer */
semaphore__(s); /* don't need semaphore any more */
/* delay destroyes itself */
return start_time/80;
}
</code></pre>
<hr>
<p>
<a href="copyrite.htm#copyright">Copyright</a>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -