📄 appendxb.htm
字号:
<head>
<title>Appendix B</title>
</head>
<body>
<h1><a name="appendix_b">Appendix B Header Files</a></h1>
<p> This appendix contains listings of the important header files used to control the
operation of the InterModual Bus peripherals. The IMB is an internal bus structure that
Motorola employs on the larger of their microcontrollers, the M68HC16 and the
M683XX families. Both of these chips comprise a core computer named either the
CPU16 or the CPU32. The remainder of the components in the controllers are all IMB
peripherals. In general, the programming language C takes care of essentially all aspects
of the core computers. The only place where C fails its job here has to do with direct
access to registers contained within the CPU components. These registers are not
available to the language and it is necessary to work around the set-up of the registers
that control the system interrupts. These interrupts are a feature of the CPU and not the
peripheral components. We will see how control within these registers can be handled in
macros written in the appropriate chip header files.
<p> The header files shown here establish access to the several registers and bit fields
within these registers. Control of these registers control the several peripherals. There
are many ways that these header files can be created. Two specifically come to mind.
The technique used here where each register is forced to a specific address in the
computer memory map and a scheme where all of the registers are placed into a single
structure and this structure is forced to the proper address. Both schemes work well. The
approach used here has the disadvantage that it requires a little more typing when
creating the file, but the structure approach has one serious drawback that makes it less
attractive. If an offset error is made in the creation of the structure, all entries in the
structure from the error on will be in error. Such an error can cause many errors in a
program, and it is very difficult to find the error source. On the other hand, if each
register is forced to its own address, and an error is made, the error will affect only the
one register, and any error diagnostic completed by the compiler will point to the exact
location in memory where the error occurred.
<p> In each of the module header files, you will fine a compiler control sequence as
follows:
<pre><code>
#ifdef _PAGE0
#define _MEM @indir
#else
#ifdef _PAGEF
#define _MEM
#else
#define _MEM @far
#endif
#endif
</code></pre>
<p>This control sequence establishes a value for the consant _MEM that depends on certain
command line options entered when the program is compiled. There are three possible
situations that can happen. If the -dpage0 option is entered, the @indir modifier must be
used with the address of each module control register. This definition causes all accesses
to the I/O page to be done as direct negative addresses. As such, the value of the EK
register must be zero. With the -dpagef option, all accesses to this page will be indirect
through one of the index registers on the chip, and with neither option, the @far modifier
will be used. In this case, all accesses to the I/O page will be direct positive addresses,
and the EK register must contain a value 0xf.
<p> Also, the final header file named defines.h is included in this section. This file,
shown below, is not a header that is chip related. It is very desirable to have a header file
that defines all of the constants that your programs might use. Inclusion of this file will
eliminate many "magic numbers" that are found in many programs. These numbers make
it very difficult to determine what is going on within any program.
<h4><a name="defines">defines.h</a></h4>
<p> The defines.h file contains many of the important definitions needed
throughout any code that might be generated. This file can be safely included
anywhere to generate these defined constants and enumerations.
<pre><code>
#ifndef DEFINES_H
#define DEFINES_H
#ifndef NULL
#define NULL (void *)0
#endif
#define EOM NULL
#define FOREVER while(TRUE)
typedef int Boolean;
typedef unsigned int WORD;
typedef unsigned char BYTE;
enum {FALSE,TRUE};
enum {OFF,ON};
enum {NO,YES};
enum {FAST,SLOW};
enum {OUTPUT, INPUT};
enum errors
{
SEMAPHORE,
SERIAL,
TIMER,
DELAY,
PWM,
PWMI
};
enum output_compares
{
OC1=1,OC2,OC3,OC4
};
enum input_captures
{
IC1=1,IC2,IC3
};
enum edges
{
DISABLE,
RISING,
FALLING,
ANY
};
enum output
{
DISCONNECT,
TOGGLE,
CLEAR,
SET
};
#endif
</code></pre>
<h4><a name="hc16y1_h">M68HC16Y1 Header file</a></h4>
<p> The header files hc16y1.h and hc16.h are core CPU headers for different parts in the
M68HC16 family. The first is for the M68HC16Y1, which is used exclusively in this
text and the second is for the M68HC16Z1. The only difference you will notice between
these two files is the peripheral addresses found near the middle of the file. The
peripherals are somewhat different on these two parts.
<pre><code>
#ifndef HC16Y1_H
#define HC16Y1_H
typedef struct
{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned bit4 : 1;
unsigned bit5 : 1;
unsigned bit6 : 1;
unsigned bit7 : 1;
unsigned bit8 : 1;
unsigned bit9 : 1;
unsigned bit10: 1;
unsigned bit11: 1;
unsigned bit12: 1;
unsigned bit13: 1;
unsigned bit14: 1;
unsigned bit15: 1;
} Register;
typedef struct
{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned bit4 : 1;
unsigned bit5 : 1;
unsigned bit6 : 1;
unsigned bit7 : 1;
} Char_Register;
typedef struct
{
unsigned IARB : 4;
unsigned bit4 : 1;
unsigned bit5 : 1;
unsigned bit6 : 1;
unsigned bit7 : 1;
unsigned bit8 : 1;
unsigned bit9 : 1;
unsigned bit10: 1;
unsigned bit11: 1;
unsigned bit12: 1;
unsigned bit13: 1;
unsigned bit14: 1;
unsigned bit15: 1;
} MCR_Register;
#define ADC_Register 0xff700
#define MRM_Register 0xff820
#define GPT_Register 0xff900
#define SCIM_Register 0xffa00
#define TPURAM_Register 0xffb00
#define MCCI_Register 0xffc00
#define TPU_Register 0xffe00
/* Macros and function to permit interrupt service
routine programming from C.
To use the vector call, do vector(isr, vector_address)
where isr is a pointer to the interrupt service
routine, and vector_address is the vector address where
the isr pointer must be stored. The usualform for vector is
#define vector(a,b) (*(void**)(b)=(a)
has been changed to that below to allow the calculated isr
address to be sixteen bits rather than twenty for the HC16 */
#define vector(isr,vector_address) (*(@far int)vector_address)=(int)(isr))
#define cli() _asm("andp #0FF1FH\n") /* enable interrupts */
#define sei() _asm("orp #000E0H\n") /* disable maskable interrupts */
#define wait() _asm("wai\n")
#endif
</code></pre>
<h4><a name="hc16_h">M68HC16 Header file</a></h4>
<p> The header files hc16y1.h and hc16.h are core CPU headers for different parts in the
M68HC16 family. The first is for the M68HC16Y1, which is used exclusively in this
text and the second is for the M68HC16Z1. The only difference you will notice between
these two files is the peripheral addresses found near the middle of the file. The
peripherals are somewhat different on these two parts.
<pre><code>
#ifndef HC16
#define HC16
typedef struct
{
unsigned bit0 : 1;
unsigned bit1 : 1;
unsigned bit2 : 1;
unsigned bit3 : 1;
unsigned bit4 : 1;
unsigned bit5 : 1;
unsigned bit6 : 1;
unsigned bit7 : 1;
unsigned bit8 : 1;
unsigned bit9 : 1;
unsigned bit10: 1;
unsigned bit11: 1;
unsigned bit12: 1;
unsigned bit13: 1;
unsigned bit14: 1;
unsigned bit15: 1;
} Register;
typedef struct
{
unsigned IARB : 4;
unsigned bit4 : 1;
unsigned bit5 : 1;
unsigned bit6 : 1;
unsigned bit7 : 1;
unsigned bit8 : 1;
unsigned bit9 : 1;
unsigned bit10: 1;
unsigned bit11: 1;
unsigned bit12: 1;
unsigned bit13: 1;
unsigned bit14: 1;
unsigned bit15: 1;
} MCR_Register;
#define ADC_Register 0xff700
#define GPT_Register 0xff900
#define SIM_Register 0xffa00
#define SRAM_Register 0xffb00
#define QSM_Register 0xffc00
/* Macros and function to permit interrupt service
routine programming from C.
To use the vector call, do vector(isr, vector_address)
where isr is a pointer to the interrupt service
routine, and vector_address is the vector address where
the isr pointer must be stored. The program must use
the return_int() function fro each return from an
interrupt or exception. */
#define vector(isr,vector_address) (*(void *)(vector_address)=(int)(isr))
#define cli() _asm("andp #0FF1FH\n") /* enable interrupts */
#define sei() _asm("orp #000e0H\n") /* disable maskable interrupts */
#endif
</code></pre>
<h4><a name="gpt_h">General Purpose Timer--GPT</a></h4>
<p> The General Purpose Timer is used on both of the varities of the M68HC16
discussed above. The header file for this peripheral system is shown below.
<pre><code>
#ifndef GPT_H
#define GPT_H
#ifdef _PAGE0
#define _MEM @indir
#else
#ifdef _PAGEF
#define _MEM
#else
#define _MEM @far
#endif
#endif
<a name="icrreg"> typedef struct</a>
{
unsigned Null : 4;
unsigned VBA : 4;
unsigned IRL : 3;
unsigned Nul : 1;
unsigned PAB : 4;
}ICRreg ;
<a name="tctl2reg"> typedef struct</a>
{
unsigned EDGE1 : 2;
unsigned EDGE2 : 2;
unsigned EDGE3 : 2;
unsigned EDGE4 : 2;
} Tctl2;
<a name="tctl1reg"> typedef struct</a>
{
unsigned GPT_NULL0 :8;
unsigned OML2 : 2;
unsigned OML3 : 2;
unsigned OML4 : 2;
unsigned OML5 : 2;
}Tctl1;
typedef struct
{
unsigned PWB : 8;
unsigned PWA : 8;
} Bytes;
/* define the lenght of an interrupt vector */
#define VAL 2
#define GPT_MCR (*(_MEM MCR_Register*)(GPT_Register+0))
<a name="icr"> #define ICR (*(_MEM ICRreg*)(GPT_Register+4))</a>
#define PDDR (*(_MEM Register*)(GPT_Register+6))
#define OC1M (*(_MEM Register*)(GPT_Register+8))
#define OC1D OC1M
<a name="tcnt"> #define TCNT (*(_MEM unsigned volatile int*)(GPT_Register+0xa))</a>
#define PACTL (*(_MEM Register*)(GPT_Register+0xc))
#define PACNT (*(_MEM unsigned volatile char*)(GPT_Register+0xd))
#define TIC1 (*(_MEM unsigned int*)(GPT_Register+0xe))
#define TIC2 (*(_MEM unsigned int*)(GPT_Register+0x10))
#define TIC3 (*(_MEM unsigned int*)(GPT_Register+0x12))
<a name="ocrs"> #define TOC1 (*(_MEM unsigned int*)(GPT_Register+0x14))</a>
#define TOC2 (*(_MEM unsigned int*)(GPT_Register+0x16))
#define TOC3 (*(_MEM unsigned int*)(GPT_Register+0x18))
#define TOC4 (*(_MEM unsigned int*)(GPT_Register+0x1a))
#define TI4O5 (*(_MEM unsigned int*)(GPT_Register+0x1c))
<a name="tctl1"> #define TCTL1 (*(_MEM Tctl1*)(GPT_Register+0x1e))</a>
<a name="tctl2"> #define TCTL2 (*(_MEM Tctl2*)(GPT_Register+0x1e))</a>
#define OMLREG TCTL1
<a name="tmsk1"> #define TMSK1 (*(_MEM Register*)(GPT_Register+0x20))</a>
#define TMSK2 TMSK1
<a name="tflg1"> #define TFLG1 (*(_MEM Register*)(GPT_Register+0x22))</a>
#define TFLG2 TFLG1
<a name="pwmc"> #define CFORC (*(_MEM Register*)(GPT_Register+0x24))</a>
#define PWMC CFORC
#define PWMA (*(_MEM Bytes*)(GPT_Register+0x26))
#define PWMB PWMA
#define PWMCNT (*(_MEM unsigned int*)(GPT_Register+0x28))
#define PWMABUF (*(_MEM Bytes*)(GPT_Register+0x2a))
#define PWMBBUF PWMABUF
#define PRESCALER (*(_MEM unsigned int*)(GPT_Register+0x2c))
/* MCR bit definitions 0x0 */
#define STOP bit15
#define FRZ1 bit14
#define FRZ0 bit13
#define STOPP bit12
#define INCP bit11
#define SUPV bit7
/* PDDR bit definitions 0x6 */
#define DDRI4O5 bit15
#define DDRO4 bit14
#define DDRO3 bit13
#define DDRO2 bit12
#define DDRO1 bit11
#define DDRI3 bit10
#define DDRI2 bit9
#define DDRI1 bit8
/* PDR bit definitions 0x6 */
#define IC4OC5 bit7
#define OC4 bit6
#define OC3 bit5
#define OC2 bit4
#define OC1 bit3
#define IC3 bit2
#define IC2 bit1
#define IC1 bit0
/* OC1M bit definitions 0x8*/
#define OC1M7 bit15
#define OC1M6 bit14
#define OC1M5 bit13
#define OC1M4 bit12
#define OC1M3 bit11
/* OC1D bit definitions 0x8*/
#define OC1D7 bit7
#define OC1D6 bit6
#define OC1D5 bit5
#define OC1D4 bit4
#define OC1D3 bit3
/* PACTL bit definitions 0x0c */
#define PAIS bit15
#define PAEN bit14
#define PAMOD bit13
#define PEDGE bit12
#define PCLKS bit11
#define I4O5 bit10
#define PACLK1 bit9
#define PACLK0 bit8
<a name="omlreg"> /* TCTL1 bit definition 0x1E*/</a>
#define OL2 bit8
#define OM2 bit9
#define OL3 bit10
#define OM3 bit11
#define OL4 bit12
#define OM4 bit13
#define OL5 bit14
#define OM5 bit15
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -