Programming the HC08 in C language Premek Fiala - Beta Control Jiri Gutman - Motorola
Praha 9. July 2002
Based on lecture by
[email protected]
Program Program: 9,00
Prezence účastníků a zahájení
9,30 – 10,30
Kontroléry HC08 ( zobecňující pohled z hlediska vyššího programovacího jazyka)
10,30 – 11,30
jazyk C (zběžně, pouze nejnutnější vlastnosti)
11,30 – 13,00
programování v C pro HC08 (včetně stylu programování pro řídicí aplikace)
13,00 – 14,00
Přestávka na oběd
14,00 – 16,00
C překladač uživatelsky (uživatelské prostředí, struktura překladu), příklady a diskuse
16,00
Ukončení semináře (zájemci obdrží překladač C pro HC08 zdarma) Based on lecture by
[email protected]
Co dostanete CodeWarrior Special Edition - HC08 Sada Special Edition pro HC08 je nyní zdarma ke stažení z internetových stránek společnosti Motorola nebo ji lze objednat tamtéž jako CDROM s označením CDCWSEHC08/D. Metrowerks současně nabízí možnost rozšíření sady na zcela neomezenou verzi za poplatek 495 USD, což znamená úsporu přes 2000 USD. Tato nabídka je časově omezena do 22.
července 2002. Více
informací naleznete na http://www.motorola.com/mcu
Based on lecture by
[email protected]
8-Bit MCU Roadmap
Based on lecture by
[email protected]
Na čem budeme předvádět The HC08 Low Cost Kits - targets 908GP32, 908JK3 and 908KX8 in 2001
Low Cost kit for HC08 beginners ( <99 USD) Consists of two modules – debug & target One debug module for all targets Standard “Instant” Peripherals Supported by free software The Self-educational CD ROM many examples in Assembly and C 300 produced from February 2001
2001
2002 The standard part of the CodeWarrior SE HC08 V 2.0 The Future New generation prepared for 2H 2002 Targets 908SR12, 908LJ12, GR8+RK2 and more The special “m4C” (micro for C) in cooperation with EBV as complement to CW SE Based on lecture by
[email protected]
Tutorial programs overview FLASH-LED-FAST.ASM This is HC08 introductory program, which have to help to HC08 familiarization. Program does some necessary initialization steps and starts flashing (switching on and off) with LEDs. Program can guide user through simulator, in circuit simulator and debugger. tutor 1 908GP32 Source
908KX8 Source
908JK3 Source
FLASH-LED-SLOW.ASM This program is similar to the last with one complication only. LED flashing is slowed down by simple delay loop. Program can run in real-time and LED flashing is visible. User can experiment with delay changing…
2002 Status Assembly Language – 74 programs Tutorial programs – 12 tutorials for 908GP32, KX8 and JK3 Targets (from very simple to complex, interrupt driven, all based on “instant peripherals”) Examples - oriented to some special feature (e.g. how to set ICG in KX8, how to program Flash memory etc.) C Language – 17 programs Several examples based on the “instant peripherals” again for 908GP32, KX8 and JK3 Targets. 12 for the Metrowerks CodeWarrior and 5 for ImageCraft ICC08 Based on lecture by
[email protected]
Target board Stabilized power supply MON08
MCU in socket
LCSK AUX
MCU pins mirror Power switch
SCI interface
Breadboard area Based on lecture by
[email protected]
LEDs Pushbuttons Temp. sensor
CPU
Based on lecture by
[email protected]
CPU08 Register Model 7
0 Accumulator (A)
15 16-bit
✦
16-bit
✦
16-bit
✦
H
X
Index Register (X) (HX) Stack Pointer (SP)
0 0 0 0 0 1 1 X X X X X
Program Counter (PC) 7
Easier Signed Arithmetic
✦
0
V 1 1 H I N Z C Condition Code Register (CCR) Carry/Borrow (MSB) Zero Negative (MSB = 1) Interrupt Mask Half-Carry (for BCD) Two’s Compliment Overflow
Based on lecture by
[email protected]
CPU08 Registers
The CPU08 has 5 registers which are not part of the memory map Accumulator
The accumulator is a general purpose 8-bit register. The CPU uses the accumulator to hold the operands and results of operations.
Index Register
The 16-bit index register is called H:X and is used by indexed addressing modes to determine the effective address of an operand. The index register can access a 64K byte address space in this mode. The lower byte X is used to hold the operand for the MUL and DIV instructions. H:X can also serve as a temporary data storage location.
Based on lecture by
[email protected]
CPU08 Registers
Stack Pointer
The 16-bit stack pointer is used to hold the address of the next available location on the stack. The CPU uses the contents of the stack pointer register as an index to access operands on the stack in stack pointer offset addressing modes. The stack can be located anywhere where there is RAM in the 64K byte address space. The SP can also be used as an index like HX
Based on lecture by
[email protected]
CPU08 Registers
Program Counter
Condition Code Register
The 16-bit program counter contains the address of the next instruction or operand to be fetched. The program counter can access a 64K byte address space.
The 8-bit condition code register contains the global interrupt mask bit and five flags that indicate the results of the instruction just executed. Bits 5 and 6 are permanently set to logic 1.
Based on lecture by
[email protected]
HC08 Addressing Modes
The CPU08 has 16 different addressing modes Inherent
Immediate
This instructions have no operand to fetch and require no operand address. Most are one byte long. The operand for immediate instructions is contained in the bytes immediately following the opcode. Immediate instructions therefore have constant operands.
Based on lecture by
[email protected]
HC08 Addressing Modes
Direct
Direct instructions are used to access operands in the direct page, i.e. in the address range $0000 to $00FF. The highorder byte of the address is not included in the instruction, thus saving one byte and one execution cycle compared to extended addressing.
Extended
Extended instructions can access operands at any address in a 64K byte memory map. All extended instructions are 3 bytes long.
Relative
All conditional branch instructions use relative addressing to evaluate the effective address. If the branch condition is true, the CPU evaluates the branch destination by adding the signed byte following the opcode to the program counter. The branch range is –128 to +127 bytes from the address after the branch instruction.
Based on lecture by
[email protected]
HC08 Addressing Modes
Indexed
Indexed instructions use the contents of the 16-bit index register HX to access operands with variable addresses, such as variables accessed through a pointer. There are five modes of indexed addressing: • No offset • 8-bit offset •16-bit offset • No offset w/ post increment • 8-bit offset w/ post increment
Based on lecture by
[email protected]
HC08 Addressing Modes
Stack pointer
Stack pointer instructions are similar to indexed instructions only they use the contents of the stack pointer as an address of the operand instead of the index register. There are two modes of stack pointer addressing: • 8-bit offset • 16-bit offset Stack pointer instructions require one extra byte and one extra execution cycle compared to the equivalent indexed instruction.
Based on lecture by
[email protected]
The Stack Pointer Importance
A Stack Pointer Register supports very key features of C: • Passing variables to subroutines • Allows the use of recursion • Is the base of Automatic variables
typedef struct { unsigned char unsigned short } ObjectType;
ID; Time;
void foo (unsigned char value) { volatile ObjectType instance; instance.ID = value; }
Assembly: foo: B00B B00D B010 B012
A7FB 9EE701 A707 81
Based on lecture by
[email protected]
AIS STA AIS RTS
#-3 1,SP #3
HC08 Addressing Modes
Memory to Memory
Memory to memory instructions copy data from one location to another. One of the locations is always in the direct page. There are four modes of memory to memory instructions: • Move immediate to direct • Move direct to direct • Move indexed to direct with post increment • Move direct to indexed with post increment
Based on lecture by
[email protected]
Is it sufficient for C? Not a bit, but we must live with it somehow... C language requires
• instruction set completness
at least:
• two 16-bit registers with arithmetic and pointer capability • a stack pointer and a stack frame pointer • continuous memory for code, data and stack
Solution?
Good code optimizer.
C language offers means for:
• placing constant data into ROM type memory • accessing volatile data (value changes outside of a program) • data initialization in RAM type memory Based on lecture by
[email protected]
Architecture
Based on lecture by
[email protected]
MC68HC908GP32
32,292 Bytes Flash
Flash
Single-Wire Development Interface
MON
Address-Match Hardware Breakpoints
BRK
Reset / Interrupt Priority Control
SIM
External Interrupt
IRQ
Watchdog
COP
TIM1
LVI
TIM2
Low-Voltage Inhibit 32kHz Clock Generator Module Time Base Module
ADC
CGMC TBM
SPI SCI
PORTA
RAM
8
PORTB
KBI
512 Bytes RAM
8
PORTC
CPU08
7
PORTD
Upward HC05 Object Code Compatible
8
PORTE
8 Keyboard Interrupts
2
8 Channel / 8-Bit Analog-to-Digital Converter 33 Bi-directional I/O All Ports Pins Rated for • 10mA Sink • 10mA Source Dual 2 Channel 16-Bit Timers • Input Capture • Output Compare • Pulse Width Modulation
Synchronous Serial Peripheral Interface Asynchronous Serial Communications Interface
DIP 40, QFP 44 Based on lecture by
[email protected]
HC08GP32 Memory Organization Memory-Mapped Registers & Peripherals! (No Special I/O Instructions!)
$0000 $003F $0040
Peripheral Registers
512B
Direct Bit Manipulation in Page 0 Memory (Fast and Code Space Efficient!)
RAM
RAM $023F $0240
Unimplemented
Program and Data Memory ALL Addressable from Same Memory Map! (Easy to Use!)
$7FFF $8000
ROM or 32K FLASH
No Special Memory Pages! (Easy to Use!)
FLASH
$FE00 $FE10 $FF80 $FFFF
Control Registers
Monitor ROM Vectors Based on lecture by
[email protected]
Can Perform Data Operations on Program Memory! (No Special I/O Instructions!)
The C language ready CPU
Based on lecture by
[email protected]
Introduction
The C Programming Language is a powerful, flexible and potentially portable high-level programming language. The C language may be used successfully to create a program for an 8-bit MCU, but to produce the most efficient machine code, the programmer must carefully construct the C Language program. The programmer must not only create an efficient high level design, but also pay attention to the detailed implementation.
Based on lecture by
[email protected]
C Language
Facts about the C language C is a HLL that deeply interacts with the underlaying computer hardware C is an easily understood language Is a programming language widely standardized Is very productive Allows code re-use and code borrowing Allows hardware abstraction maintainability Excellent programming tool for Microcontrollers
Based on lecture by
[email protected]
Assembly vs. C
A compiler is no more efficient than a good assembly programmer. It is much easier to write good code in C which can be converted in to efficient assembly code than it is to write efficient assembly code by hand. C is a means to an end and not an end itself.
Based on lecture by
[email protected]
ANSI C for 8-Bits MCUs
Pure ANSI C is not always convenient for embedded systems because: Embedded systems interact with hardware. ANSI C provides extremely crude tools for addressing registers at fixed memory locations. Almost all embedded systems use interrupts
One should use standard C as much as possible...
ANSI C has various type promotion rules that are absolute performance killers to an eight-bit machine.
However, when it interferes with solving the problem at hand, do not hesitate to bypass it.
Some microcontroller architectures don’t have hardware support for a C stack. Many microcontrollers have multiple memory spaces
Based on lecture by
[email protected]
- Nigel Jones
Embedded vs. Desktop Programming
Main characteristics of an Embedded progamming environment: • Limited RAM • Limited ROM • Limited stack space • Hardware oriented programming • Critical Timing (ISR, tasks, ...) • Many different pointer kinds (far/near/rom/uni/paged/...) • Special keywords/tokens (@, interrupt, tiny, ...) Based on lecture by
[email protected]
Compiler Requirements
.asm .asm .o .o .c.c .cpp .cpp
• • • • • •
Compiler +
listing listing
.h .h
ROM-able code Optimized code Re-entrant code Support for Different Member in CPU Family Support for different memory models Non Obvious optimization
Based on lecture by
[email protected]
Linker Requirements
.o .o .o .o
.s19 .s19 Linker .map .map
.o .o Target description
Merging segments of code Allocate target memory (RAM, ROM, stack, special areas) Produce files for debugging (symbols, line numbers...) Produce files for target (mirror of memory) Based on lecture by
[email protected]
Compiler’s little Details While choosing a compiler, you must remember that the Devil is in the details
Nice features that can make a huge difference: Inline Assembly Interrupt Functions Assembly Language Generation Standard Libraries Startup code
Based on lecture by
[email protected]
C Example for Embedded Systems The Hello World Application for the HC08 #include <stdio.h> void main(void){ printf (“Hello World!\n”); while(1); }
• Startup code • Standard libraries
- Startup code is an extra piece of software that executes prior to main(). - A standard set of function libraries. These include various routines like printf, memcpy, strcmp, scanf and so on.
Based on lecture by
[email protected]
Startup Routine The startup code is generally written in assembly language and linked with any executable that you build. It prepares the way for the execution of programs written in a high-level language. 1.
Disable interrupts
2.
Copy any initialized data from ROM to RAM
3.
Zero the uninitialized data area
4.
Allocate space for and initialize the stack
5.
Create and initialize the heap (if available)
6.
Enable interrupts
7.
Call main() (never returns) Based on lecture by
[email protected]
Standard Library
Performing Input/Output using the C library functions getchar gets printf putchar puts scanf sprintf sscanf.
#include <stdio.h> void main(void){ printf (“Hello World!\n”); while (1); }
All input/output performed by C library functions is supported by underlying calls to getchar and putchar. The C source code for these and all other C library functions are commonly included
Based on lecture by
[email protected]
C for Embedded Systems
Based on lecture by
[email protected]
Some natural Questions... After seeing the previous code, some natural questions may arise:
Where is my code? Where are my variables? How do I access I/O Registers? How do I handle interrupts?
Based on lecture by
[email protected]
Where is my code?
In the PRM file, you can define where you want to allocate each segments you have defined in your source code. In order to place a segment into a specific memory area; just add the segment name in the PLACEMENT block of your PRM file.
Based on lecture by
[email protected]
The Linker Parameter File (PRM)
Based on lecture by
[email protected]
Where are my variables?
The variables are placed into the Default_RAM PLACEMENT unless otherwise stated with a #pragma... It is important to define a segment into the Zero Page RAM (0x40 -0xFF) to place the most frequently used variables. This way, the compiler will optimize the code using direct addressing mode (8-bit address) instead of extended mode (16-bit address).
Based on lecture by
[email protected]
How to access I/O Registers?
Many I/O and control registers are located in the direct page and they should be declared as such, so the compiler can use the direct addressing mode where possible. One of the first questions that arises when programming embedded is:
How do I access I/O Registers?
The answer is as simple or complicated as you want...
Based on lecture by
[email protected]
Defining I/O Registers
One common and very useful form is: #define PortA ( * ( volatile unsigned char * ) 0x0000 )
An easier way to do this is: volatile unsigned char PortA
@0x0000;
A portable way is like this: #define BYTE_REG *(volatile unsigned char*) #define PortA BYTE_REG
0x0000
#define PortB BYTE_REG
0x0001
Based on lecture by
[email protected]
This makes PortA a variable of type char at address 0x0000
This is a compilerspecific syntax... It is more readable, but we pay the price loosing portability.
This is portable syntax... For better readability use typedef.
Defining I/O Registers (2) Most convenient way: /*****SCI CONTROL REGISTER 2*****/ volatile union { struct { unsigned char _SBK:1; unsigned char _RWU:1; unsigned char _RE:1; ............. } SCC2_BITS; unsigned char SCC2_BYTE; } SCC2_ @ 0x14; /*DEFINE REGISTER*/ #define SCC2 SCC2_.SCC2_BYTE /*DEFINE REGISTER BITS*/ #define SBK SCC2_.SCC2_BITS._SBK #define RWU SCC2_.SCC2_BITS._RWU #define RE SCC2_.SCC2_BITS._RE ................ Based on lecture by
[email protected]
This is a union placed over a byte at 0x14. Register bits can be acessed as an 8-bit entity (SCC2 = 0x04), or as individual bits (RE = 1).
How do I handle interrupts? The CodeWarrior compiler provides a non-ANSI compliant way to specify directly the interrupt vector number in the source: interrupt 17 void TBM_ISR (void){ /* Timebase Module Handler*/ } Vector Number
Vector Address
Vector Address Size
0
0xFFFE - 0xFFFF
2
1
0xFFFC – 0xFFFD
2
2
0xFFFA – 0xFFFB
2
...
...
...
n
0xFFFF – ( n*2 )
2
Based on lecture by
[email protected]
Introduction to CodeWarrior
Let’s see how to...
• Create empty project from stationary • Add and remove files from a project • Startup Code • Default.prm Settings • Use of file editor • Compiling (successful and unsuccessful) • Enable debugging and debugging a project • Setting a breakpoint • Viewing variables in debugger Example #1
Based on lecture by
[email protected]
Useful ANSI-C Standards
Based on lecture by
[email protected]
Data types Facts
• The greatest savings in code size and execution time can be made by choosing the most appropriate data type for variables. • The natural internal data size for 8-bit MCU is 8-bits (one byte), whereas the C preferred data type is ‘int’. • 8-bit machines can process 8-bit data types more efficiently than 16-bit types. • “int” and larger data types should only be used where required by the size of data to be represented. • Double precision and floating point operations are particularly inefficient and should be avoided wherever efficiency is important.
Based on lecture by
[email protected]
Scalar Types for the HC08 The ANSI standard does not precisely define the size of its native types, but CodeWarrior does...
0
255
All scalar types (except char) are signed by default Example: ‘int’ = ‘signed int’
Based on lecture by
[email protected]
Default CodeWarrior Data Types All basic types can be changed...
Based on lecture by
[email protected]
Data Type Selection
There are 3 Rules for Data Type Selection on 8-bit MCUs:
• Use the smallest possible type to get the job done. • Use unsigned type if posibble. • Use casts within expressions to reduce data types to the minimum required.
Based on lecture by
[email protected]
Modifiers
Three key words, together, allow us to write not only better code, but also tighter code:
static volatile const
Based on lecture by
[email protected]
Static Variables
When applied to variables, static has two primary fuctions:
• The variable doesn’t disappear between successive invocations of a function.
• When declared at the module level, it is accessible by all functions in all the module, but by no one else. Note: These variables won’t be stored in the Stack.
Based on lecture by
[email protected]
Static variable Example Before entering to MyFunction the first time, myVar = 0
FILE1.c #include
includes functions contained in file FILE2.c
FILE2.c void MyFunction (void){
void main (void){ MyFunction();
static char myVar = 0;
Definition of MyFunction in FILE2.C local variable declared static
included in FILE2.c myVar = myVar + 1;
MyFunction();
included in FILE2.c }
}
The static Variable keeps its value even though myVar is local
Before entering to MyFunction for the second time: myVar = 1
Based on lecture by [email protected]
Static Functions Features: • Only callable by other functions within its module. • Good structured programming practice. • Can result in smaller and/or faster code. Advantages: Since the compiler knows at compile time exactly what functions can call a given static function, it may strategically place the static function such that may be called using a short version of the call or jump instruction.
Based on lecture by [email protected]
Volatile Variables
A volatile variable is one whose value may be changed outside the normal program flow.
In embedded systems, there are two ways this can happen:
• Via an interrupt service routine • As a consequence of hardware action
Based on lecture by [email protected]
It is very good practice to declare volatile all Peripheral Registers in embedded devices.
Volatile variables are never Optimized
Access to variables defined as volatile are never optimized by the compiler !!! Without Volatile keyword volatile unsigned char PORTA @0x00; volatile unsigned char SCS1 @0x16; unsigned char value;
MOV LDA STA
void main(void){
With Volatile keyword
PORTA = 0x05; PORTA = 0x05; SCS1; value = 10;
/* PORTA = 00000101 */ /* PORTA = 00000101 */
}
Based on lecture by [email protected]
MOV MOV LDA LDX STX
#5,PORTA #10 @value
#5,PORTA #5,PORTA SCS1 #10 @value
Volatile variable Example
/* MC68HC908GP20/32
Official Peripheral Register Names */
volatile volatile volatile volatile volatile
unsigned unsigned unsigned unsigned unsigned
char char char char char
PORTA PORTB PORTC PORTD PORTE
@0x0000; /* Ports and data direction */ @0x0001; @0x0002; @0x0003; @0x0008;
volatile volatile volatile volatile volatile
unsigned unsigned unsigned unsigned unsigned
char char char char char
DDRA DDRB DDRC DDRD DDRE
@0x0004; /* Data Direction Registers */ @0x0005; @0x0006; @0x0007; @0x000C;
volatile unsigned char PTAPUE volatile unsigned char PTCPUE volatile unsigned char PTDPUE
@0x000D; /* Port pull-up enables */ @0x000E; @0x000F;
Based on lecture by [email protected]
Const variables
The Declaration const is applied to any variable, and it tells the compiler to store it in ROM code. The compiler keeps the program memory address of that location. Since it is in ROM, its value cannot be changed. An initialization value must be declared. Example: const double PI = 3.14159265;
Based on lecture by [email protected]
Const constrains
• Some compilers create a genuine variable in RAM to hold the const variable. On RAM-limited systems, this can be a significant penalty. • Some compilers, like CodeWarrior, store the variable in ROM. However, the “read only” variable is still treated as a variable and accessed as such, typically using some form of indexed addressing (16-bit). Compared to immediate addressing (8-bit), this method is normally much slower.
Based on lecture by [email protected]
Const volatile variables
Can a variable be both, const and volatile? Yes! This modifier form should be use on any memory location that can change unexpectedly (volatile) and that is read-only (const). The most obvious example of this is a hardware status register: /* SCI Status Register */ const volatile unsigned char SCS1
Based on lecture by [email protected]
@0x0016
Time Reference Program
Based on lecture by [email protected]
Time Reference Program
Let’s make a program to output a 1 Hz square signal through Port C of the 68HC908GP32 Assume: XTAL = 4.9152MHz
Example #2
Based on lecture by [email protected]
The TBM on the MC68HC908GP32 Time Base Module (TBM) The TBM will generate periodic interrupts at user selectable rates using a counter clocked by the external crystal clock. The TBM uses 15 divider stages, eight of which are user selectable. • User selectable oscillator clock source enable during stop mode to allow periodic wakeup from stop • The Time Base Module Only has One Register for Status and Control
Based on lecture by [email protected]
TBM Programming Sample Turn On the TBM TBON
÷2
÷2
÷2
÷2
÷ 128
÷ 64
Select Timebase Rate ( 8,192 for this example )
÷2
Based on lecture by [email protected]
0
TBR0
÷2
÷2
TBR1
÷2
÷ 2048
÷2
÷2
TBR2
÷2
÷ 32768
÷2
÷ 32
÷2
÷ 8192
÷2
÷8
÷2
÷ 16
CGMXCLK 32.768kHz
0 0 0 0 1 1 1 1
0 0 1 1 0 0 1 1
0 1 0 1 0 1 0 1
0
1
TBIF 250ms
Signal the event
Time Base Control Register (TBCR)
TACK— Timebase ACKnowledge TBON — Timebase Enabled TBIE — Timebase Interrupt Enabled TBIF — Timebase Interrupt Flag The TACK bit is a write-only bitTimebase and always reads as 0.offWriting a power —enables Timebase Rate This read/write bitTBR2:TBR0 enables the timebase. maySelection be turned to reduce This read/write bit the timebase This read-only flag bit is set when theinterrupt when the consumption its function is not The the counter be initialized by logic 1when to this bit clears TBIF, the timebase interrupt flag bit. Writing TBIF bittimebase becomes set. Reset clears bit. Test bitnecessary. should always 0 can counter has rolled over.beTBIE clearingaand then setting thishas bit. no Reset clears TBON bit. logic 0 to this bit effect. These read/write bits are the used to select the1rate ofinterrupt timebase interrupts. 1 = Timebase enabled = Timebase interrupt pending 1 = Timebase enabled 1 = Clear interrupt flag 0 = Timebase interrupt not pending = timebase Timebase disabled 0 = Timebase0disabled and theinterrupt counter initialized 0 = No effect Based on lecture by [email protected]
See Rate Selection Table
TBM Rate Selection
Time Base Control Register
Based on lecture by [email protected]
Building the TBM C module Defining the TBM Register Object: Definitions in “iogp20_32.h”
typedef unsigned char BYTE; volatile BYTE TBCR
#define TBCR
@0x1C;
Based on lecture by [email protected]
*((volatile BYTE *)0x1C)
Main Program #include "hidef.h" #include "iogp20_32.h" #define unsigned char
COUNT 75 cCounter=0x00;
void main(void) { CONFIG1 = 0x0B; CONFIG2 = 0x03;
/* Interrupts per sec */ /* Interrupt Events Counter */
/* COP dis, STOP En, LVI En @5v */ /* SCI using Int Clk, Osc En @STOP
*/
DDRC = 0xFF; PORTC = 0xFF;
/* Configure PortC as Output */ /* Initialize PortC */
TBCR
/* Configure TimeBase Status & Control Reg TBM OFF & interrupt enabled Select Timebase Rate (Div 2^15) @XTAL=4.9152MHz -> Freq=150Hz */
= 0x04;
cCounter = COUNT; EnableInterrupts;
/* Initialize the Counter */
TBCR |= TBON while(1);
/* Turn TBM on */
}/* END main() */ Based on lecture by [email protected]
Creating a Interrupt Service Routine MC68HC908GP20 Interrupt Vector Table
An ISR in CodeWarrior Time Base Module Vector Location in memory interrupt 17 void TBM_ISR (void){ TBCR |= TACK; // Acknowledge Int ... } B051 B052 B054 B055
PSHH BSET PULH RTI
3,0x1C
Note: The TBM has the lowest vector priority of all interrupts
Vector 17
Address $FFDC
Vector Time Base Module Vector
16
$FFDE
ADC Conversion Complete
15
$FFE0
Keyboard Vector
14
$FFE2
SCI Transmit Vector
13
$FFE4
SCI Receive Vector
12
$FFE6
SCI Error Vector
11
$FFE8
SPI Transmite Vector
10
$FFEA
SPI Receive Vector
9
$FFEC
Timer 2 Overflow Vector
8
$FFEE
Timer 2, Channel 1 Vector
7
$FFF0
Timer 2, Channel 0 Vector
6
$FFF2
Timer 1 Overflow Vector
5
$FFF4
Timer 1, Channel 1 Vector
4
$FFF6
Timer 1 Channel 0 Vector
3
$FFF8
PLL Vector
2
$FFFA
IRQ Vector
1
$FFFC
Software Interrupt Vector
-
$FFFE
Reset
Based on lecture by [email protected]
TBM Interrupt Subroutine
The TBM Interrupts subroutine looks like this...
interrupt 17 void TBM_ISR (void){ TBCR |= TACK;
/* TimeBase Interrupt Acknowledge */
if( !(--cCounter) ){ PORTC = ~PORTC; cCounter = COUNT; }
/* If Counter is ZERO then */ /* Toggle LED */ /* Reinitialize the Counter */
}/* END TBM_ISR() */
Based on lecture by [email protected]
ptejte se, odpovíme
Based on lecture by [email protected]