Programming Examples - Renesas Electronics

Application Note
Programming Examples
For K0 and K0S Microcontrollers
Document No. U13218EU1V0AN00
April 1998
©1998 NEC Electronics Inc. Printed in U.S.A.
1.
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-1
Program Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using the Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Associated Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
“Include” File for C Language Programs in Chapters 2–13 . . . . . . . . . . . . . . . . . . . . .
2.
Sine Wave Generation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-1
Applicable K0 Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Registers to Output a Sine Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Assembly Language Program: Example of D/A Conversion . . . . . . . . . . . . . . . . . . . .
3.
4-1
4-1
4-1
4-2
Asynchronous Serial Interface (UART) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-1
Applicable K0 Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Baud Rate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Control Register Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.
3-1
3-1
3-2
3-2
3-2
3-Wire Serial I/O (SPI) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-1
Applicable K0 Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.
2-1
2-1
2-4
2-5
A/D Converter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-1
Applicable K0 Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A/D Converter Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Software Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Input Voltage and Conversion Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.
1-1
1-1
1-2
1-2
5-1
5-1
5-1
5-2
5-3
Software UART. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
Applicable Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
Setting Baud Rate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-1
Usage Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2
C Language Program: Example of Software UART Implementation . . . . . . . . . . . . . 6-12
7.
Interval Timer Operation with 8-Bit Timer 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1
Applicable Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1
Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-1
8.
DTMF Tone Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1
Applicable Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-1
Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2
i
9.
I2C Bus Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-1
Applicable Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-1
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-1
EEPROM Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-3
10. LCD Controller/Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-1
Applicable Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LCD Display Data Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LCD Display Mode Register (LCDM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LCD Display Control Register (LCDC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LCD Controller/Driver Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Common Signals and Segment Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
LCD Drive Voltages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example LCD Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10-1
10-1
10-2
10-2
10-3
10-4
10-4
10-4
10-4
11. Keyboard Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1
Applicable K0 Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-1
Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-2
12. Watch Timer Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-1
Applicable K0 Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-1
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-1
Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-2
13. Standby Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-1
Applicable Devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
HALT Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
STOP Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Standby Function Control Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Application Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13-1
13-1
13-1
13-2
13-3
13-3
14. Software for the LCD Demo Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1
Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1
Edit the Time-of-Day . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1
Power-Saving Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-1
Assembly Language Program: DEMO_CLK.ASM . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-3
Assembly Language Program: DEMO_LCD.ASM . . . . . . . . . . . . . . . . . . . . . . . . . . 14-10
Assembly Language Program: DEM_TOD.ASM . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-22
Assembly Language Program: DEMO_KEY.ASM. . . . . . . . . . . . . . . . . . . . . . . . . . . 14-27
C Language Program: DEMO.H . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-33
C Language Program: DEMO_CLK.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-35
Language Program: DEMO_LCD.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-40
C Language Program: DEMO_TOD.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-48
C Language Program: DEMO_KEY.C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-52
ii
1
Introduction
This application note contains program examples illustrating basic functions of the K0 and K0S
8-bit microcontroller families in ways that can shorten development time and improve time to
market. Each chapter in this application note includes the following:
•
Brief description of the software routine
•
Specification of the application software program with supporting diagrams
•
Program flowchart
•
Listings of code in Assembly language and C language
Program Examples
In the following table, chapter numbers and titles are cross-referenced with the applicable K0
and K0S devices. With minor modifications, the programs also could be used with other
microcontrollers in the K Series® product line.
Chapter →
Devices
↓
2
Sine
Wave
3
A/D
µPD7808x
Y
µPD7801xF
µPD7801xH
Y
4
3-Wire
I/O
5
6
UART
Software
UART
Y
Y
Y
Y
µPD78002x
µPD78003x
7
8-Bit
Timer
8
9
10
11
12
13
14
2
DTMF
I C
LCD
Keyboard Watch
LCD
Standby
Interface Control
Input
Timer
Demo
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
µPD7805x
µPD7805xF
µPD78005x
Y
Y
Y
Y
Y
Y
µPD7807x
µPD78070A
Y
Y
Y
Y
Y
Y
µPD7806x
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
µPD78030x
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
µPD7804xH
µPD7804xF
Y
Y
Y
Y
Y
Y
µPD78020x
Y
Y
Y
Y
Y
Y
µPD78092x
µPD78096x
Y
µPD78901x
Y
µPD78902x
Y
Y
Using the Programs
The best way to use the programs is to run the appropriate code either with the SM78K0
software simulator or the DDB-K0070A evaluation board, both of which can be obtained by
contacting your local NEC representative. The software simulator with virtual hardware support
provides the best low-cost option, because it is common to other development tools and allows
you to become familiar with a standard development environment. The program examples were
developed by NEC Electronics Inc. for demonstration purposes only. Modifications may be
necessary for use in real applications.
1-1
Introduction
Associated Documentation
This document should be used in conjunction with the appropriate hardware and software
manuals and data sheets, which can be obtained by calling 1-800-366-9782 or faxing your
request to 1-800-729-9288.
Document Name
Document Number
K Series® Selection Guide
U10930EJAV0SG00
K0 Family Selection Guide
U11126EJ6V0SG00
K0 Family (Instructions)
U12326EJ3V0UM00
K0 Family Basics (II)
U10121EJ2V0AN0
K0 Family Fundamentals (III)
U10182EJ1V1AN0
K0 Integrated Design Microcontroller
U11987EU1V0BR00
K0S Instruction Set
U11047EJ2V0UM00
“Include” File for C Language Programs
Be sure to use the following code in your “include file” when using any of the program examples
in chapters 2 - 13.
/******************************************************************
*
File name: define.h
*
Date:
7/18/97
*Include file for definition
******************************************************************/
#define TRUE1
#define FALSE0
//
//extended functions
//
#pragma sfr// SFR
#pragma asm// ASM
#pragma opc// DATA INSERTION
#ifdef K0S
#pragma realregister // using in K0S compiler
#endif
#pragma
#pragma
#pragma
#pragma
#pragma
halt
stop
nop
di
ei
#pragma access// PEEK, POKE
#define CR13
#define LF10
//
//for only DDB-K0070A
//
#define DDB
******************************************************************
1-2
Sine Wave Generation
2
Applicable K0 Devices
•
•
•
•
•
µPD7805x
µPD7805xF
µPD78005x
µPD7807x
µPD78070A
Description
Sine wave output applications using a D/A converter are widely used in the industry. The D/A
converter converts a digital input into an analog value. The D/A converter in the K0 family
consists of two channels with 8-bit resolution and uses the R-2R resistor ladder method of
conversion.
There are two modes of operation: normal and real-time. Normal operation generates the
analog voltage output signal immediately after the D/A conversion. Real-time operation
generates the analog voltage output signal, which is gated by an output trigger, after the D/A
conversion is complete. This mode is common in modem applications such as cordless
telephone sets.
Because the converter voltage changes in steps, the output is usually connected to a low-pass
filter. Figure 2-1 shows the digital and analog output waveforms. Figure 2-2 is the flowchart for
the conversion program.
2-1
Sine Wave Generation
Figure 2-1. Analog Output in Real-TIme Output Mode
Writing Output Data
667 µs
D1
D2
D3
D1
D2
D/A Output Waveform
Voltage
48
72
96
120
144 168
216
264
312
Degrees
97YL-0307C (12/97)
2-2
Sine Wave Generation
Figure 2-2. Flowchart of a Sine Wave Program
Sine wave output by
D/A converter
(real-time mode)
8-bit timer interrupt
service routine entry
Load D/A value to D/A
value set register 0
(DACS0).
Initialization:
• Set port mode
registers, D/A register,
8-bit timer and registers.
• Set D/A conversion
value to 0x80 (0 deg).
• Enable 8-bit timer
interrupt.
• Reset Step-Counter
to 0.
Increment
Step-Counter.
Yes
Wait here.
Step-Counter > 30?
No
Reset Step-Counter
to 0.
Return from Interrupt.
97YL-0308C (12/97)
2-3
Sine Wave Generation
Registers to Output a Sine Wave
•
D/A converter mode (DAM) register (Figure 2-3)
•
D/A conversion value set registers (DASC0, DASC1)
Figure 2-3. D/A Converter Mode Register (DAM)
7
6
5
4
3
2
1
0
0
0
DAM5
DAM4
0
0
DACC1
DACE0
Bit
Name
Description
0
DACE0
D/A conversion channel 0
0 = Stop
1 = Enable
1
DACE1
D/A conversion channel 1
0 = Stop
1 = Enable
4
DAM4
Operation mode channel 0
0 = Normal
1 = Real-time output
5
DAM5
Operation mode channel 1
0 = Normal
1 = Real-time output
Output voltage = AVREF1 x DACSn / 256
Where:
–
–
AVREF1 = reference voltage
DACSn (n = 0 or 1) = D/A counter register
Software Specifications
2-4
Specification
Description
Output frequency
50 Hz
D/A channel number
0
Voltage output type
Real-time output
Number of steps
30 steps in the output voltage cycle
Interval time of timer
1/(50 Hz x 30 steps) = 667 µs
AVref1
5 volts
Sine Wave Generation
Assembly Language Program: Example of D/A Conversion
;***********************************************************************
;
File name: sine.asm
;
Date: 12/8/96
;***********************************************************************
; This sample program demonstrates the use of a D/A converter channel with an
; 8-bit resolution. The D/A can be used in two modes: normal mode and
; real-time mode. In the normal mode, the output trigger writes
; data to the D/A conversion value setting registers 0 and 1 (DACS0 and DACS1).
; In the real-time mode, the output is triggered by interrupt
; requests (INTTM1 and INTTM2), which are asserted by 8-bit timer/event counters 1 and 2.
; In this mode, data is set into DACS0 and DACS1 after an output trigger has
; been generated or until the next output trigger is generated.
;
;
Sine wave output:
;
================
;
;
The sine wave output example has a frequency of 50 Hz and is implemented by using
;
the 8-bit real-time output mode of D/A converter channel 0. Each
;
8-bit real-time interrupt, DACS0 is output and the next output
;
data is set into DACS0.
;
The interval time of the 8-bit timer/event counter 1 is set to
;
667 µs (30 steps if a 50-Hz frequency is chosen).
;
;
1 MHz
;
Step Timer value = ------------------ = 667 µs
;
50 Hz x 30 (steps)
;
;
D/A Output:
;
AVref1 x DACS0
;
ANO0 pin output voltage = ----------------;
256
;
;***********************************************************************
;
Sample program specification
;=======================================================================
;***********************************************************************
;
Restrictions if using the DDB-K0070A Development Board:
;
. Always leave bit 1 of register MK0L equal to 0 (INTP0).
;
. Do not use the software break (BRK). The monitor uses it.
;
. Do not use the 32-kHz subsystem clock because of the UART.
;
. Do not use the STANDBY mode either because of the UART.
;***********************************************************************
;
;
for only DDB-K0070A
;
$set (DDB)
;
;======================================================================
;
;
Internal high RAM allocation
;
dseg
IHRAM
ds
20h
Stack:
;
;
Short address space
;
dseg
saddr
count:
ds
(1)
$ej
;======================================================================
2-5
Sine Wave Generation
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
;
org
24h
dw
INTTM1
;Generation of 8-bit timer/event counter 1 match
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 1000h
ResetStart:
di
;
;
Select register bank 0
;
sel
RB0
;
;
Select Master clock (5 MHz)
;
. MCS = 1, no divided clock
;
mov
OSMS,#00000001b
;
;
Init. I/O registers for sine wave
;
call
!InitSineWaveOutput
;
;
Set stack pointer (IHMEM + 20H)
;
movw
sp,#Stack
;
;
Enable INTP0 for DDB-K0070A
;
$if (DDB)
clr1
PMK0
$endif
;
;
Enable interrupt
;
;Disable interrupt
;Select register bank 0 for background
output
;Stack ptr
EI
;
;
Wait here
;
main_loop:
br
main_loop
;
$ej
;======================================================================
;
Output each step of the sine wave
;
Switch to register bank 1
;
Input:
;
count = step count
;
Output:
;
DAC output
;======================================================================
INTTM1:
sel
RB1
; Get the data
movw
hl,#SineDataTable
2-6
Sine Wave Generation
mov
mov
mov
a,count
b,a
a,[hl+b]
; output
mov
; next step
inc
cmp
bc
; reset counter
mov
inttm1_10:
reti
SineDataTable:
db
db
db
db
db
db
db
DACS0,a
count
count,#TableSizeSineData+1
$inttm1_10
count,#0
09bh
0b4h
0cbh
0dfh
0efh
0fah
0ffh
;3.02 v
;3.5168
;3.9695
;4.3579
;4.6651
;4.8776
;4.9863
db
db
db
db
db
db
db
0ffh
0fah
0efh
0dfh
0cbh
0b4h
09bh
;4.9863
;4.8776
;4.6651
;4.3579
;3.9695
;3.5168
;3.02 v
db
db
db
db
db
db
db
db
080h
065h
04ch
035h
021h
011h
006h
001h
;2.5 v
;1.9802
;1.4832
;1.0305
;0.6421
;0.3349
;0.1224
;0.0137
db
db
db
db
db
db
db
db
SineDataEnd:
001h
006h
011h
021h
035h
04ch
065h
080h
;0.0137
;0.1224
;0.3349
;0.6421
;1.0305
;1.4832
;1.9802
;2.5 v
TableSizeSineData
equ
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
;Degree
12
24
36
48
60
72
84
96
108
120
132
144
156
168
180
192
204
216
228
240
252
264
276
288
300
312
324
336
348
360
(SineDataEnd - SineDataTable)
;***********************************************************************
;
Init. I/O registers for sine wave output
;
;
Sine wave output specification:
;
. Sine wave output 50 Hz
;
. Real-time mode
;
. Number of steps for output = 30 steps
;
. 8-bit timer mode = interval
;***********************************************************************
InitSineWaveOutput:
;
;
Set port13 in input mode (PM13)
2-7
Sine Wave Generation
;
;
p130 must be set to input mode for D/A conversion
mov
;
;
;
;
8-bit timer register 1 count clock selection (TCL1)
. tcl1_0/3 = 1001b, MCS= 1, fx/24 (313 kHz = 3.2 µs)
mov
;
;
;
DACS0,#80h
DAM,#00010001b
. Clear 8-bit timer 1 interrupt request flag
. Enable 8-bit timer 1 interrupt
clr1
clr1
;
;
;
TCE1
D/A converter mode register (DAM)
DACE0 (bit 0) = 1 conversion enable for channel 0
DAM4 (bit 4 ) = 1 real-time output mode for channel 0
mov
;
;
;
;
TMC1,#00000000b
Set D/A converter - 0 degree (2.5 v)
mov
;
;
;
;
;
; t = 667 µs/3.2 = 208.44
8-bit timer operation enable
set1
;
;
;
CR10,#208
Set 8-bit timer/event control register
. tce1 (bit0) = 0, Disable 8-bit timer register 1
. tce2 (bit1) = 0, Disable 8-bit timer register 2
. tmc12 (bit2) = 0, 8-bit timer register * 2 channel mode (tm1,tm2)
mov
;
;
;
TCL1,#11011001b
Set 8-bit timer compare register to 668 µs (50 Hz, 30 steps)
mov
;
;
;
;
;
;
PM13,#11111111b
TMIF1
TMMK1
Reset Step-Counter to 0
mov
ret
count,#0
;***********************************************************************
end
_
2-8
Sine Wave Generation
C Language Program: Example of D/A Conversion
#define DEBUG 0
#pragma interrupt INTTM1 IRQ_8bit_Timer RB1
/***********************************************************************
;
File name: sine.c
;
Date: 9/2/97
;***********************************************************************
; This sample program demonstrates the use of a D/A converter channel with an
; 8-bit resolution. The D/A can be used in two modes: normal mode and
; real-time mode. In the normal mode, the output trigger writes
; data to the D/A conversion value setting registers 0 and 1 (DACS0 and DACS1).
; In the real-time mode, the output is triggered by interrupt
; requests (INTTM1 and INTTM2), which are asserted by 8-bit timer/event counters 1 and 2.
; In this mode, data is set into DACS0 and DACS1 after an output trigger has
; been generated or until the next output trigger is generated.
;
;
Sine wave output:
;
================
;
;
The sine wave output example has a frequency of 50 Hz and is implemented by using
;
the 8-bit real-time output mode of D/A converter channel 0. Each
;
8-bit real-time interrupt, DACS0 is output and the next output
;
data is set into DACS0.
;
The interval time of the 8-bit timer/event counter 1 is set to
;
667 µs (30 steps if a 50-Hz frequency is chosen).
;
;
1 MHz
;
Step Timer value = ------------------ = 667 µs
;
50 Hz x 30 (steps)
;
;
D/A Output:
;
AVref1 x DACS0
;
ANO0 pin output voltage = ----------------;
256
;***********************************************************************
;
Sample program specification
;=======================================================================
;***********************************************************************
;
Restrictions if using the DDB-K0070A Development Board:
;
. Always leave bit 1 of register MK0L equal to 0 (INTP0).
;
. Do not use the software break (BRK). The monitor uses it.
;
. Do not use the 32-kHz subsystem clock because of the UART.
;
. Do not use the STANDBY mode either because of the UART.
;
=====================================================================*/
#include "define.h"
/*=====================================================================
;
Delta value for sine wave output
====================================================================*/
unsigned char const SineDataTable[] ={
0x9b,
//;3.02 v
12
0xb4,
//;3.5168 v
24
0xcb,
//;3.9695 v
36
0xdf,
//;4.3579 v
48
0xef,
//;4.6651 v
60
0xfa,
//;4.8776 v
72
0xff,
//;4.9863 v
84
0xff,
0xfa,
//;4.9863 v
//;4.8776 v
96
108
2-9
Sine Wave Generation
0xef,
0xdf,
0xcb,
0xb4,
0x9b,
//;4.6651
//;4.3579
//;3.9695
//;3.5168
//;3.02 v
0x80,
0x65,
0x4c,
0x35,
0x21,
0x11,
0x06,
0x01,
//;2.5 v
//;1.9802
//;1.4832
//;1.0305
//;0.6421
//;0.3349
//;0.1224
//;0.0137
0x01,
0x06,
0x11,
0x21,
0x35,
0x4c,
0x65,
0x80
//;0.0137
//;0.1224
//;0.3349
//;0.6421
//;1.0305
//;1.4832
//;1.9802
//;2.5 v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
v
120
132
144
156
168
180
192
204
216
228
240
252
264
276
288
300
312
324
336
348
360
};
//
//
//
__sreg unsigned char count;
void InitSineWaveOutput ();
/*======================================================================
;
Main
;=====================================================================*/
void main (void)
{
DI ();
//
//
Select Master clock (5 MHz)
//
MCS = 1, no divided clock
//
OSMS = 0b00000001;
//
//
Init. I/O registers for sine wave output
//
InitSineWaveOutput ();
#ifdef DDB
//
//
Enable INTP0 for DDB-K0070A
//
PMK0 = 0;
#endif
EI ();
//
//
Wait here
//
while (TRUE);
}
/*=====================================================================
;
Output a step for sine wave
;
Switch to register bank 1
;
Input:
;
count = step number
;
Output:
;
Output DAC count
2-10
Sine Wave Generation
;====================================================================*/
void IRQ_8bit_Timer ()
{
DACS0 = SineDataTable[count++];
if ( count > sizeof SineDataTable) count = 0;
}
/***********************************************************************
;
Init. I/O registers for sine wave output
;
;
Sine wave output specification:
;
. Sine wave output 50 Hz
;
. Real-time mode
;
. Number of steps for output = 30 steps
;
. 8-bit timer mode = interval
;**********************************************************************/
void InitSineWaveOutput ()
{
//
//
Set port 13 in input mode (PM13)
//
p130 must be set to input mode for D/A conversion
//
PM13= 0b11111111;
//
//
8-bit timer register 1 count clock selection (TCL1)
//
//
. tcl1_0/3 = 1001b, MCS= 1, fx/24 (313 kHz = 3.2 µs)
TCL1=0b11011001;
//
//
//
Set 8-bit timer compare register to 668 µs (50 Hz, 30 steps)
CR10=208; //t = 667 µs/3.2 = 208.44
//
//
//
//
//
//
Set 8-bit timer/event control register
. tce1 (bit0) = 0, Disable 8-bit timer register 1
. tce2 (bit1) = 0, Disable 8-bit timer register 2
. tmc12 (bit2) = 0, 8-bit timer register * 2 channel mode (tm1,tm2)
TMC1=0b00000000;
//
//
//
8-bit timer operation enable
TCE1 = 1;
//
//
//
Set D/A converter - 0 degree (2.5 v)
DACS0=0x80;
//
//
//
//
//
D/A converter mode register (DAM)
DACE0 (bit 0) = 1 conversion enable for channel 0
DAM4 (bit 4) = 1 real-time output mode for channel 0
DAM=0b00010001;
//
//
//
//
. Clear 8-bit timer 1 interrupt request flag
. Enable 8-bit timer 1 interrupt
TMIF1 = 0;
TMMK1 = 0;
//
//
//
Reset Step-Counter to 0
count = 0;
}
_
2-11
Sine Wave Generation
2-12
A/D Converter
3
Applicable K0 Devices
•
•
•
•
•
•
•
•
•
•
•
•
•
µPD7808x
µPD7801xF
µPD7801xH
µPD7805x
µPD7805xF
µPD78005x
µPD7807x
µPD78070A
µPD7806x
µPD78030x
µPD7804xH
µPD7804xF
µPD78020x
Description
The K Series A/D converter consists of eight channels (ANI0 to ANI7) with 8-bit resolution. The
conversion is based on the successive approximation method and the conversion result is held
in the 8-bit A/D conversion result register (ADCR). There are two ways to start A/D conversion.
1. Hardware: conversion is triggered by the interrupt input (INTP3).
2. Software: conversion starts by setting the A/D converter mode register
The input channel is selected from ANI0 through ANI7, and A/D conversion is carried out. In a
hardware start,operation stops after a single conversion. In a software start, the operation is
repeated and an interrupt request (INTAD) generated each time an A/D conversion is
completed.
A/D conversion is performed continuously until bit 7 (CS) of the ADM register is reset to 0 by
software. If a write access to the ADM register is performed during an A/D conversion, the
conversion is initialized, and if the CS bit is set to 1, conversion starts again from the beginning.
Upon termination of the A/D conversion, the result is stored in the ADCR and an interrupt
request signal (INTAD) generated. If data sets bit 7 (CS) of the ADM during an A/D conversion,
the operation stops immediately.
A/D Converter Registers
Function
Register
Analog input
8 channels (ANI0 to ANI7)
Control register
A/D converter mode (ADM) register (Figure 3-1)
A/D converter input select (ADIS) register (Figure 3-2)
External interrupt mode register 1 (INTM1)
A/D conversion result (ADCR) register
3-1
A/D Converter
A/D Converter Program
The example program (Figure 3-3) reads all eight channels sequentially in a loop.
Software Specification
•
•
•
Number of A/D input channels to be selected: 8
Conversion time selection: 20 µs (100/fx, MCS = 1 with fx = 5.0 MHz)
Conversion starts: software
Figure 3-1. A/D Converter Mode Register (ADM) Setup
7
6
5
4
3
2
1
0
CS
TRG
FR1
FR0
ADM3
ADM2
ADM1
HSC
Bit(s)
Name
Description
5, 4, 0
FR1, FR0, HSC
A/D conversion time
3–1
ADM3–ADM1
6
TRG
7
CS
1 0 1 = 20 µs
Analog input channel selection
0 0 0 = channel 0
External trigger selection
0 = Software start
A/D conversion operation control
0 = Stop
Figure 3-2. A/D Converter Input Select Register (ADIS) Setup
7
6
5
4
3
2
1
0
0
0
0
0
ADIS3
ADIS2
ADIS1
ADIS0
Bits
Name
Description
3–0
ADIS3–ADIS0
Number of analog input channels
1 0 0 0 = 8 channels
Input Voltage and Conversion Results
The relation between the voltage at the analog input pins and the A/D conversion result (the
value stored in ADCR) = INT [VIN/VIN x 256 + 0.5].
Where:
– INT[ ] = function that returns integer parts of value in brackets
– VIN = analog input voltage
– VREF = AVREF0 pin voltage
3-2
A/D Converter
Figure 3-3. Flowchart of A/D Conversion Program
A/D conversion in
software start
Initialization:
• Set P1 mode to intput
direction (all 8 bits).
• Set ADIS register to
0x8h to select all
8 channels for A/D
conversion.
• Set conversion time to
20.0 µs in ADM register
Set channel number
to 0
• Set current channel
number in ADM register
• Clear ADF flag in
register IF1L and start
conversion (CS = 1).
No
Conversion done?
Yes
• Read conversion
result (ADCR).
• Increment channel
number.
No
Channel number
≥ 8?
Yes
97YL-0309C (12/97)
3-3
A/D Converter
Assembly Language Program: Example of A/D Conversion
;***********************************************************************
;
File name: ADC.ASM
;
Date: 9/5/97
;***********************************************************************
; This module performs the A/D converter function in the K0 family.
; The conversion method is based on successive approximation and the
; conversion result is held in the 8-bit A/D conversion result register (ADCR).
;=======================================================================
; - A/D CONVERSION OPERATION IN SOFTWARE START
;
;
. Set an A/D channel for A/D conversion.
;
. Set a conversion time.
;
. Start conversion.
;
. Wait for the A/D channel conversion completed.
;
. Read the conversion result.
;
. Reset the interrupt request flag.
;
. Return with the result in the A register.
;
;=======================================================================
;
Input voltage and result:
;
;
ADCR (result register) = INT [(Vin/Vref) x 256 + 0.5]
;
;
Where,
;
INT
= integer parts of the result
;
Vin
= analog input voltage
;
Vref = AVref0 pin voltage (reference voltage)
;
ADCR = the conversion result register
;=======================================================================
;
;
Module name: ReadADdata
;
;
Input:
;
A = channel # (0 to 7)
;
;
Return:
;
A = The A/D result of the given channel
;
;***********************************************************************
;
;
for only DDB-K0070A
;
$set (DDB)
;======================================================================
;
Port assignment for A/D
;======================================================================
ADDirPort
equ
PM1
;======================================================================
;
; Select 100/fx (20 µs) if fx = 5.00 MHz
;
fr1/fr0/hsc = 101b and Start conversion bit on
;
ConversionTime
equ
00100001b
;======================================================================
;
;
Internal high RAM allocation
;
FWA = 0fb00h
;======================================================================
dseg
IHRAM
ds
20h
3-4
A/D Converter
Stack:
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
; interrupt vector if any
org
20h
;
dw
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
ResetStart:
di
;
;
Select register bank 0
;
sel
RB0
;
;
Set stack pointer (IHMEM + 20H)
;
movw
SP,#Stack
;
;
Select Master clock (4.19 MHz)
;
. MCS = 1, no divided clock
;
mov
OSMS,#00000001b
;
;
Enable INTP0 for DDB-K0070A
;
$if (DDB)
clr1
PMK0
$endif
;
;
Init. ADC register
;
call
!InitADC
;
;
16 step pwm output
;
loop:
mov
a,#0
call
!ReadADdata
br
loop
;Disable interrupt
;Select register bank 0
;Stack ptr
;Channel # 0
;=======================================================================
;
;
Module name: ReadADdata
;
;
Input:
;
A = channel # (0 to 7)
;
Return:
;
A = The A/D result of the given channel
;
;=======================================================================
ReadADdata:
;
Set A/D channel
add
a,a
;position to bit 1
;
merge with conversion time and start A/D conversion
or
a,#ConversionTime
3-5
A/D Converter
;
;
Clear interrupt flag
Start conversion
mov
ADM,a
clr1
set1
;
;
;
wait:
;
;
;
ADIF
ADM.7
Wait for conversion done
bf
ADIF,$wait
Read the conversion result
mov
a,ADCR
Stop conversion
clr1
ADM.7
ret
;***********************************************************************
;
ADC init
;
. Set conversion time
;
. Set # of A/D channels
;***********************************************************************
InitADC:
;
Set memory expansion mode register
mov
ADDirPort,#11111111b
;
;
A/D conversion mode register
;
mov
ADM,#ConversionTime
;
;
A/D input selection (select all 8 channels)
;
mov
ADIS,#00001000b
ret
;***********************************************************************
end
;
3-6
A/D Converter
C Language Program: Example of A/D Conversion
/***********************************************************************
;
File name: ADC.C
;
Date: 9/5/97
;***********************************************************************
; This module performs the A/D converter function in the K0 family.
; The conversion method is based on successive approximation and the
; conversion result is held in the 8-bit A/D conversion result register (ADCR).
;=======================================================================
; - A/D Conversion Operation in Software Start
;
;
. Set an A/D channel for A/D coversion.
;
. Set a conversion time.
;
. Start conversion.
;
. Wait for the A/D conversion to be completed.
;
. Read the conversion result.
;
. Reset the interrupt request flag.
;
. Return with the result in the A register.
;
;=======================================================================
;
Input voltage and result:
;
;
ADCR (result register) = INT [(Vin/Vref) x 256 + 0.5]
;
;
Where,
;
INT = integer parts of the result
;
Vin = analog input voltage
;
Vref= AVref0 pin voltage (reference voltage)
;
ADCR= the conversion result register
;=======================================================================
;
;
Module name: ReadADdata
;
;
Input:
;
A = channel # (0 to 7)
;
;
Return:
;
A = The A/D result of the given channel
;
;***********************************************************************
;
;
for only DDB-K0070A
;
;**********************************************************************/
#include "define.h"
//;======================================================================
//;
Port assignment for A/D
//;======================================================================
#define ADDirPortPM1
//;======================================================================
//;
//; Select 100/fx (20 µs) if fx = 5.00 MHz
//;
fr1/fr0/hsc = 101b and start conversion bit on
//;
#define ConversionTime
0b00100001
//
//
Variables
//
__sreg unsigned char ChannelNumber;
3-7
A/D Converter
__sreg unsigned char AD_Data;
//
//
functions
//
void InitADC ();
void ReadADdata ();
//;======================================================================
//;
Main
//;======================================================================
void Main (void)
{
//;
//;
Select Master clock ( 5.00 MHz)
//;
. MCS = 1, no divided clock
//;
OSMS = 0b00000001;
//;
//;
Enable INTP0 for DDB-K0070A
//;
#ifdef DDB
PMK0 = 0;
#endif
//;
//;
Init. ADC register
//;
InitADC ();
//;
//;
16-step pwm output
//;
ChannelNumber = 0;
while (TRUE)
{
ReadADdata ();
}
}
/*;=======================================================================
;
Module name: ReadADdata
;
;
Input:
;
ChannelNumber = channel # (0 to 7)
;
Return:
;
Unsigned char = The A/D result of the given channel
;======================================================================*/
void ReadADdata ()
{
//;
Set A/D channel
//
ADM = ChannelNumber<< 1 | ConversionTime;
ADM = ConversionTime;
ADM |= ChannelNumber<< 1;
ADIF = 0;
ADM.7 = 1;
//;
//;
//;
Wait for conversion done
while (TRUE)
{
if ( ADIF == 1 ) break;
}
//;
//;
//;
Read the conversion result
AD_Data = ADCR;
3-8
A/D Converter
//;
Stop conversion
ADM.7 = 0;
}
/************************************************************************
;
ADC init
;
. Set conversion time
;
. Set # of A/D channels to all 8
;***********************************************************************/
void InitADC ()
{
//
Set memory expansion mode register
ADDirPort = 0b11111111l;
//
//
Starts by software, conversion time = 20 µs
//
ADM = ConversionTime;
//
//
A/D input selection (select all 8 channels)
//
ADIS = 0B00001000;
}
3-9
A/D Converter
3-10
3-Wire Serial I/O (SPI)
4
Applicable K0 Devices
•
•
•
•
•
•
•
µPD7801xF/7801xH
µPD7805x/78005x/7805xF
µPD7807x/78070A
µPD7806x
µPD78030x
µPD7804xH/7804xF
µPD78020x
Description
Most K0 and K0S microcontrollers support 3-wire serial I/O mode, which includes an emulation
of the serial peripheral interface (SPI) and is used for transfer of 8-bit data using three lines:
serial clock (SCKn), serial output (SOn), and serial input (SIn). This technique enables
simultaneous transmission and reception and reduces data transfer processing time.
The start bit of transferred 8-bit data is switchable between the most MSB and LSB, so any
serial device can be connected regardless of its start-bit recognition. The 3-wire mode should
be used when connecting with peripheral I/O devices or display controllers that incorporate a
conventional synchronous clocked serial interface. The clock source can be selectable either
internally or externally, and the maximum clock speed can be selected up to 1.25 MHz (fxx/4).
3-Wire I/O Registers
Register
Description
Register
Serial data output register (SOn)
Control register
Timer clock select register (TCL3)
Serial operating mode register 0 (CSIMn)
Serial bus interface control register (SBIC)
Port mode register 2 (PM2)
Operation
The 3-wire serial I/O mode is used for data transmission/reception in 8-bit data units. A bit-wise
data transmission/reception is carried out in synchronization with the serial clock.
•
Transmission: When data is written to SOn, transmission occurs on a bit-by-bit basis at the
falling edge of the serial clock (SCKn). The transmitted data is held in the SOn latch and
output on the SOn pin. When the 8-bit data is completely transmitted, SOn operation
terminates and an interrupt request flag (CSIIF0) is set.
•
Reception: To read 8-bit data with the internal timer (8-bit timer register 2), dummy data has
to be transmitted to the SOn in order to start generation of a clock SCKn. The received data
is latched in SIn at the rising edge of SCKn. Upon completion of the 8-bit data transfer, SIn
operation stops automatically and the interrupt request flag (CSIIFn) is set.
4-1
3-Wire Serial I/O (SPI)
Example Program
The example program transmits a test string ‘ABCDEFGHIJKLMN’ and receives 256 bytes of
data from channel 0. See Figures 4-1 through 4-3 for the timing diagram, mode register format
(CSIM0), and program flowchart.
Software Specification
Specification
Description
Interface setup
Master and a slave
Serial interface
Channel 0
Output string
ABCDEFGHIJKLMN
I/O timer clock selection
19.5 kHz with MCS = 1; fx = 5.0 MHz
Input buffer size
256-byte ring buffer
Figure 4-1. 3-Wire Serial I/O Timing
SCK0
1
2
3
4
5
6
7
8
SI0
d7
d6
d5
d4
d3
d2
d1
SO0
d7
d6
d5
d4
d3
d2
d1
CSIIF0
End of Transfer
97YL-0330C (12/97)
Figure 4-2. Serial Operation Mode Register 0 (CSIM0)
7
6
5
4
3
2
1
0
CSIE0
COI
WUP
CSIM04
CSIM03
CSIM02
CSIM01
CSIM00
Bit(s)
Name
1–0
CSIM01, CSIM00
Description
Clock selection
110 = clock specified with bits 0 to 3 of register TCL3
2
CSIM02
Start bit
0 = MSB
4–3
CSIM04, CSIM03
Serial I/O mode
0 0 = 3-wire
5
WUP
Wake-up function
0 = Interrupt request signal with each transfer in any mode
6
COI
Slave address comparison result
0 = Slave address register not equal to serial I/O register 0 data
7
CSIE0
Serial interface channel 0 operation
0 = stop and 1 = enable
4-2
3-Wire Serial I/O (SPI)
Figure 4-3. Flowchart of 3-Wire I/O Program
3-wire demo program
entry
Initialization:
Set serial operation mode
register 0 (CSIM0), Timer
clock select register 3
(TCL3), and Port 2 mode
register.
• Set output string pointer
and clear offset.
• Set input buffer pointer
and clear offset.
Read a byte and
output to SO0 register.
No
End of transfer
(CSIIF0 = 1)?
Yes
• Clear CSIIF0 (=0).
• Increment string offset.
No
Offset > string size?
Yes
Transmit a dummy byte
(0ffh).
No
End of transfer
(CSIIF0 = 1)?
Yes
• Clear CSIIF0 (=0).
• Increment input buffer
pointer.
No
Buffer pointer > 256?
Yes
97YL-0328C (12/97)
4-3
3-Wire Serial I/O (SPI)
Assembly Language Program: Example of 3-Wire Serial Interface
;***********************************************************************
;
File name: SPI.ASM
;
Date: 9/6/97
;
;***********************************************************************
; This sample program demonstrates the SPI (serial peripheral interface)
; mode (3-wire serial I/O mode) of the K0 family (Master operation).
;
;;
Algorithm:
;
- Transmission:
;
.Set Rx/Tx to regular 3-wire serial mode.
;
.Transmit a character.
;
.Wait for Tx to be done.
;
.Clear the interrupt flag and wait for next data.
;
;
;
;
;
;
- Receive:
.Set Rx/Tx to regular 3-wire serial mode.
.Transmit a dummy character (000h) to be output to SCK.
.Wait for Rx to be done.
.Read a serial data sting.
.Clear the interrupt flag and wait for next data.
;
This example code outputs a data string:
;
;
"ABCDEFGHIJKLMN"
;
;
And reads 256 bytes of data.
;
;***********************************************************************
;
;
for only DDB-K0070A
;
$set (DDB)
;======================================================================
;
Equates
;======================================================================
SioInDir
equ
pm2.5
;Input port direction
SioInPort
equ
p2.5
;Input port
SioOutDir
equ
pm2.6
;Output port direction
SioOutPort
equ
p2.6
;Output port
SClockDir
equ
pm2.7
;Clock
SClockPort
equ
p2.7
;Clock
;======================================================================
;
Saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
;======================================================================
;
Even boundary
;======================================================================
dseg
saddrp
;======================================================================
;
Bit segment
;======================================================================
bseg
;======================================================================
;
;
Internal high RAM allocation
;
dseg
IHRAM
4-4
3-Wire Serial I/O (SPI)
;
;
Input buffer
;
InputBuffer:
ds
100h
InputBufferEnd:
InputBufferSize equ (InputBufferEnd - InputBuffer) and 0ffh
;
;
Stack ptr
Fwa_Stack:
ds
20h
Stack:
;
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
ResetStart:
di
;
;
Oscillation mode select register
;
. Does not use divider circuit
;
mov
osms,#00000001b
;
;
Set stack pointer (IHMEM + 20H)
;
movw
sp,#Stack
;
;
Init. UART register
;
call
!Init_SPI1
;
;
Enable INTP0 for DDB-K0070A
;
$if (DDB)
clr1
pmk0
$endif
;
;
Output test string
;
'ABCDEFGHIJKLMN'
;
OutputData:
set1
csiif0
;Disable interrupt
;Stack ptr
movw
hl,#TestString
mov
c,#TestStringSize
mov
b,#0
Write_loop:
mov
a,[hl+b]
;
Wait for transfer completion
bf
csiif0,$$
;
Output data
4-5
3-Wire Serial I/O (SPI)
clr1
mov
inc
dbnz
;
;
csiif0
sio0,a
b
c,$Write_loop
;Output data
Jump to input data from serial I/O
br
InputData
;
;
Test output string
;
TestString:
db
'ABCDEFGHIJKLMN',0
TestStringEnd:
TestStringSize equ TestStringEnd - TestString
;======================================================================
;
Read data and store to an input buffer (256 bytes)
;======================================================================
InputData:
;
;
Read data from serial input
;
==========
;
Clear buffer
;
clear:
movw
hl,#InputBuffer
mov
c,#InputBufferSize
mov
b,#0
mov
a,#0
clear_loop:
mov
[hl+b],a
inc
b
dbnz
c,$clear_loop
;
clr1
csiif0
;
;
Read data
;
movw
hl,#InputBuffer
mov
c,#InputBufferSize
mov
b,#0
Read_loop:
mov
sio0,#00 ;Output dummy data for clock generation
;
Wait for transfer completion
bf
csiif0,$$
clr1
csiif0
;
Input data
mov
a,sio0
mov
[hl+b],a
;store data
inc
b
dbnz
c,$Read_loop
br
OutputData
;output data
;======================================================================
;
Init. for SPI case 3
;
. Set 3-wire serial I/O
;
. Clock speed = 51.28 µs (19.5 kHz)
;======================================================================
Init_SPI1:
;
4-6
3-Wire Serial I/O (SPI)
;
Clock specified with bits 0 to 3 of timer clock selection register 3 (TCL3)
;
Disable operation (port mode), bit7 = 0
;
;****************************************************************
;*
Serial interface channel 0 control register (CSIM0) *
;*
*
;*
1 0 0 0 0 0 1 1
*
;*
^ ^ ^ ^ ^ ^ ^ ^
*
;*
| | | | | | | |__ 1 Clock specified with bits 0 to 3 of TCL3 *
;*
| | | | | | |
*
;*
| | | | | | |____ 1 Clock specified with bits 0 to 3 of TCL3 *
;*
| | | | | |
*
;*
| | | | | |______ DIR0: Start bit 0 = MSB, 1 = LSB*
;*
| | | | |
*
;*
| | | | |________ 0 3-wire mode
*
;*
| | | |
*
;*
| | | |__________ 0 3-wire mode
*
;*
| | |
*
;*
| | |____________ 0 Interrupt request signal generation *
;*
|
with each serial transfer in any mode*
;*
| |
*
;*
| |______________ 0 Slave address register not equal to *
;*
|
serial I/O shift register 0 data*
;`
|________________ 1 Enable operation
*
;*
*
;****************************************************************/
mov
csim0,#10000011b
;
;
;
Clock selection (chn0) - mcs = 1, fxx/28 = 51.28 µs (19.5 kHz)
mov
;
;
;
tcl3,#00001101b
Serial data input,output, clock
set1
SioInDir
;Input data direction
clr1
clr1
SioOutDir
SioOutPort
;Output data direction
;Output data low
clr1
set1
SClockDir
SClockPort
;Clock output
;Output clock High
;
;
ret
;***********************************************************************
end
_
4-7
3-Wire Serial I/O (SPI)
C Language Program: Example of 3-Wire Serial Interface
/***********************************************************************
;
File name: SPI.C
;
Date: 9/8/97
;
;***********************************************************************
; This sample program demonstrates the SPI (serial peripheral interface)
; mode (3-wire serial IO mode) of the K0 family (Master operation).
;
;
;
Algorithm:
;
- Transmission:
;
.Set Rx/Tx to regular 3-wire serial mode.
;
.Transmit a character.
;
.Wait for Tx to be done.
;
.Clear the interrupt flag and wait for next data.
;
;
;
;
;
;
- Receive:
.Set Rx/Tx to regular 3-wire serial mode.
.Transmit a dummy character (0ffh) to be output to SCK.
.Wait for Rx to be done.
.Read a serial data string.
.Clear the interrupt flag and wait for next data.
;
This example code outputs a data string:
;
;
"ABCDEFGHIJKLMN"
;
;
And reads 256 bytes of data.
;
;***********************************************************************/
#include "define.h"
/*;======================================================================
;
Equates
;======================================================================*/
#define SioInDir
PM2.5 // ;Input port direction
#define SioInPort
P2.5 // ;Input port
#define SioOutDir
PM2.6 // ;Output port direction
#define SioOutPort
P2.6 // ;Output port
#define SClockDir
PM2.7 // ;Clock
#define SClockPort
P2.7 // ;Clock
//
//;
//;
Test Output String
//;
const unsigned char TestString[] = "ABCDEFGHIJKLMN";
//;
//;
Input buffer
//;
unsigned char InputBuffer[0x100];
__sreg
unsigned char i,j;
//
//
//
void
Init_spi ();
/*;======================================================================
*
Main
*;======================================================================*/
void Main (void)
{
DI ();
//;Disable interrupt
4-8
3-Wire Serial I/O (SPI)
//;
//;
//;
//;
Oscillation mode select register
Does not use divider circuit
OSMS =0b00000001;
//;
//;
//;
Init UART Register
Init_spi ();
//;
//;
//;
#ifdef
Enable INTP0 for DDB-K0070A
DDB
PMK0 = 0;
#endif
{
//;=======================================================
//;
Output a test string
//;
'ABCDEFGHIJKLMN'
//;=======================================================
CSIIF0 = 1;
for (i=0;i< sizeof TestString;i++)
{
while (TRUE) { if ( CSIIF0 ) break; }
CSIIF0 = 0;
SIO0 = TestString[i];
}
//;=======================================================
//;
Read data and store to an input buffer (256 bytes)
//;=======================================================
//;
Clear buffer
//;
for (i=0;i< sizeof InputBuffer;i++) InputBuffer[i] = 0;
//
//
Read data
//
CSIIF0 = 0;
for (i=0;i< sizeof InputBuffer;i++)
{
SIO0 = 0x00;
// output a dummy byte
while (TRUE) { if ( CSIIF0 ) break; }
CSIIF0 = 0;
InputBuffer[i] = SIO0;
}
}
}
/*;======================================================================
;
Init. for SPI case 3
;
. Set 3-wire serial I/O
;
. Clock speed = 51.28 µs (19.5 kHz)
;======================================================================*/
void
Init_spi ()
{
//;
//;
Clock specified with bits 0 to 3 of timer clock selection register (TCL3)
//;
Disable operation (port mode), bit7 = 0
//;
4-9
3-Wire Serial I/O (SPI)
/*;****************************************************************
;*
Serial interface channel 0 control register, (CSIM0) *
;*
*
;*
1 0 0 0 0 0 1 1
*
;*
^ ^ ^ ^ ^ ^ ^ ^
*
;*
| | | | | | | |__ 1 Clock specified with bits 0 to 3 of TCL3 *
;*
| | | | | | |
*
;*
| | | | | | |____ 1 Clock specified with bits 0 to 3 of TCL3 *
;*
| | | | | |
*
;*
| | | | | |______ DIR0:Start bit 0 = MSB, 1 = LSB *
;*
| | | | |
*
;*
| | | | |________ 0 3-wire mode
*
;*
| | | |
*
;*
| | | |__________ 0 3-wire mode
*
;*
| | |
*
;*
| | |____________ 0 Interrupt request signal generation *
;*
| |
with each serial transfer in any mode* *
;*
| |______________ 0 Slave address register not equal to*
;*
|
serial I/O shift register 0 data*
;*
|________________ 1 Enable operation
*
;*
*
;****************************************************************/
CSIM0 =0b10000011;
//;
//;
//;
Clock selection (chn0) - MCS= 1, fxx/2 8 = 51.28 µs (19.5 kHz)
TCL3=0b00001101;
//;
//;
//;
Serial data input,output, clock
SioInDir = 1;
//;Input data direction
//;
SioOutDir = 0;
//;Output data direction
SioOutPort = 0; //;Output data low
//;
SClockDir = 0;
//;Clock output
SClockPort = 1; //;Output clock High
}
4-10
Asynchronous Serial Interface (UART)
5
Applicable K0 Devices
•
•
•
•
•
•
•
•
µPD7808x
µPD7805x
µPD7805xF
µPD78005x
µPD7807x
µPD78070A
µPD7806x
µPD78030x
Description
Asynchronous serial I/O is widely used in the industry, most commonly for RS-232
communication. The data transmission/reception is provided at programmable rates, generated
either by a dedicated on-chip baud rate generator or by scaling the input clock. A data frame of
transmitted/received data consists of a start bit, character bits, a parity bit, and stop bits. Prior to
a data transmission or reception, the asynchronous control registers have to be set according to
the required data format.
Baud Rate
When using the on-chip baud-rate generator, a baud rate must be selected. A programmable
divide factor of the main system clock generates the transmit/receive clock for the baud rate,
calculated as baud rate = fxx/ 2n x k.
Where:
– fxx = main system clock frequency (5 MHz typical)
– n = value set by TPS0–TPS3 in baud rate generator control register (BRGC)
– k = value set in MDL0–MDL3 in BRGC
UART Registers
Register Name
Description
__________ register
Transmit shift register (TXS)
Receive shift register (RXS)
Receive buffer register (RXB)
Control register
Serial operating mode register (CSIMn)
Asynchronous serial interface mode register (ASIM)
Asynchronous serial interface status register (ASIS)
Baud rate generator control register (BRGC)
Port mode register 7 (PM7)
5-1
Asynchronous Serial Interface (UART)
Example Program
The example program initializes the internal UART control registers for asynchronous serial
interface mode and transmits a UART test string. The serial input data and errors on input data
routines are interrupt driven (Figure 5-1).
Figure 5-1. Flowchart of Example Program
UART mode entry
Serial input IRQ
routine
Initialization:
• Set ASIM and BRGC
registers.
• Reset input buffer
pointers.
• Reset output string
pointer.
• Select RB1
(Register group 1).
• Read a byte.
Char = CR?
Yes
No
Save the CR.
Output a byte.
Buffer
overflowed?
No
Byte = CR?
Yes
Yes
Set receive done flag.
• Save the byte.
• Increment buffer
pointer.
No
Increment output
string pointer.
Return
Input data string
received?
Yes
No
Input error entry
Transmit input string.
Wait
• Select RB1.
• Read Asynchronous
serial interface status
register (ASIS).
Save the error status.
Return
97YL-0310C (12/97)
5-2
Asynchronous Serial Interface (UART)
Software Specifications
Specification
Description
Serial data format
1 start bit, 7 data bits, even parity bit, 2 stop bits
Baud rate
9600 baud
Output string
UART TEST STARTS
Input module
Interrupt driven; received data is stored in an input buffer
Error detection
Errors in the receiving data are handled by a serial error interrupt routine
Control Register Settings
Figure 5-2. Asynchronous Serial Interface Mode Register (ASIM)
7
6
5
4
3
2
1
0
TXE
RXE
PS1
PS0
CL
SL
ISRM
SCK
Bit
Name
Description
0
SCK
Clock selection
1 = Dedicated baud rate generator output
1
ISRM
Reception completion interrupt
0 = Interrupt generated in case of error generation
2
SL
Transmit data stop bits
1 = 2 bits
3
CL
Character length
0 = 7 bits
5–4
PS1–PS0
Parity bits
11 = Even parity
6
RXE
Receive operation
1 = Enabled
7
TXE
Transmit operation
1 = Enabled
Note: In UART mode, register CSIM2 should be set to 00h.
Figure 5-3. Asynchronous Serial Interface Status Register (ASIS)
7
6
5
4
3
2
1
0
0
0
0
0
0
PE
FE
OVE
Bit
Name
0
OVE
Description
Overrun error flag
0 = Error not generated
1 = Error generated
1
FE
Framing error flag
0 = Error not generated
1 = Error generated
2
PE
Parity error flag
0 = Error not generated
1 = Error generated
5-3
Asynchronous Serial Interface (UART)
Assembly Language Program: Example of UART
****************************************************************************
;
File name: UART.ASM
;
Date: 9/9/97
;****************************************************************************
;
Description:
; This example program demonstrates the asynchronous serial
; interface (UART). Serial interface channel 2 is set by using serial operation
; mode register 2 (CSIM2), asynchronous serial interface mode register (ASIM),
; asynchronous serial interface status register (ASIS), baud-rate generator
; control register (BRGC), and oscillation mode select register (OSMS).
; The UART mode of serial interface channel 2 transmits or receives 1-byte
; data following a start bit and can perform full-duplex operation.
;
; The example program will output a start-up message 'UART TEST STARTS' and then wait
; for string data up to 20 bytes or a carriage return, and output the input buffer to verify data.
;
;
The main program uses registers in RB0 (register group 0) and the receive interrupt
;
routine uses registers in RB1 (register group 1).
;
;
One frame of transmit/receive data consists of a start bit,
;
8 character bits, no parity bit, and 2 stop bits.
;
;
The baud-rate setting:
;
;
fxx
;
Baud rate = -----------;
2n x k
;
;
fxx = Main system clock frequency
;
n = Value set by TPS0-TPS3 (1 <= n <= 11)
;
k = Value set by MDL0-MDL3 (0 <= k <= 14)
;
;
Example:
;
Baud rate: 9600 bauds
;
Even parity
;
Start bit: 1
;
Stop bits: 2
;
8-bit: LSB first
;
CTS input pin: p31
;
RTS output pin: p32
;
;======================================================================
;
Output test string:'UART TEST STARTS'
;
Non-interrupt-driven TX module
;======================================================================
;
Input: Serial data stored in RxDataBuffer (10 bytes)
;
Interrupt-driven RX module
;======================================================================
;
Input error: Stored status of error bits
;======================================================================
;
for only DDB-K0070A
;
$set (DDB)
;
;
;======================================================================
;
CR
equ
13
;Carriage return
LF
equ
10
;Line feed
;======================================================================
;
Equates
5-4
Asynchronous Serial Interface (UART)
;======================================================================
RTS_O
RTSDirPort
CTS_I
equ
equ
equ
P3.2
P3.2
P3.1
;Request-to-send
;Request-to-send direction port
;Clear-to-send
;======================================================================
;
Device selection flag
;======================================================================
;
;
K0S family
;
K789026 set
0
;
;
K780024, K780034
;
K780024 set
1
;======================================================================
;
$_if K789026 = 1
RXDirPort
equ
PM2.2
;RX direction port
TXDirPort
equ
PM2.1
;TX direction port
TXDataPort
equ
P2.1
;TX data port
$else
$_if K780024 = 1
RXDirPort
TXDirPort
TXDataPort
equ
equ
equ
PM2.3
PM2.4
P2.4
;RX direction port
;TX direction port
;TX data port
equ
equ
equ
PM7.0
PM7.1
P7.1
;RX direction port
;TX direction port
;TX data port
$else
RXDirPort
TXDirPort
TXDataPort
$endif
; K7800024
$endif
; K780026
;======================================================================
;
saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
RXData:
ds
RXDataBufferSize equ10
RXDataBuffer: ds
RXDataBufferSize+1
ErrorFlags:
ds
1 ;RX Error
OverrunErr
FramingErr
ParityErr
equ
equ
equ
0
1
2
;RX data
;RX data buffer size
;Add 1 more byte for CR
;======================================================================
;
Even boundary pair
;======================================================================
dseg
saddrp
5-5
Asynchronous Serial Interface (UART)
;======================================================================
;
Bit segment
;======================================================================
bseg
F_RX_end
dbit
;Reception end flag
F_Err
dbit
;Reception error flag
RecDone
dbit
;a string received done
;======================================================================
;
;
Internal High RAM allocation
;
dseg
IHRAM
ds
20h
Stack:
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
;
;
org
dw
org
dw
org
dw
18h
INTSER
1ah
INTSR
1ch
INTST
;Serial interface channel 2 UART reception error
;End of serial interface channel 2 UART reception
;End of serial interface channel 2 UART transfer
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
ResetStart:
di
;
;
Oscillation mode select register
;
. Does not use divider circuit
;
mov
OSMS,#00000001b
;
;
Set stack pointer (IHMEM + 20H)
;
movw
SP,#Stack
;
;
Init. UART register
;
call
!Init_UART
;
;
Enable INTP0 for DDB-K0070A
;
$if (DDB)
clr1
PMK0
$endif
clr1
RecDone
ei
;
;
Output start message
;
mov
c,#TestStringSize
5-6
;Disable interrupt
;Stack ptr
;string received flag = 0
Asynchronous Serial Interface (UART)
movw
call
;
;
;
Wait for a string to be received
bf
;
;
;
RecDone,$$
;string received flag = 0
Output the input buffer data
mov
movw
call
;
;
hl,#TestString
!OutputAString
c,#RxDataBufferSize
hl,#RxDataBuffer
!OutputAString
Reset flag to 0
clr1
RecDone
br
$$
;
TestString:
db
TestStringEnd:
'UART TEST STARTS',CR,LF
TestStringSizeequ
TestStringEnd - TestString
;======================================================================
;
Module name: Init_UART
;
;
DESCRIPTION:
;
.This module is to initialize UART control and mode
;
registers.
;
;
OPERATION:
;
.Set dual ports to input for RX and output for TX
;
and latch the TX port to high.
;
. Data format: 1 start, 8-bit data, 1 stop, no parity.
;
. Set baud rate to 9600.
;
. Enable RX and TX operation.
;
. Clear all variables and flags for serial data transfer.
;======================================================================
Init_UART:
;
;
p3.1 = CTS (input), P3.2 = RTS (output)
;
set1
RTS_O
clr1
RTSDirPort
;
;
Set TX/RX port direction and output latch
;
set1
RXDirPort
;RX set to input direction
clr1
TXDirPort
;TX set to output direction
set1
TXDataPort
;Latch output high
;
;
Baud rate (9600 bauds/err=1.73 %)
;
mov
BRGC,#10010000b ;9600 bauds err = 1.73%/MCS = 1, fx = 5 MHz
5-7
Asynchronous Serial Interface (UART)
;****************************************************************
;*
Asynchronous serial interface mode register (ASIM) *
;*
*
;*
1 1 1 1 0 1 0 1
*
;*
^ ^ ^ ^ ^ ^ ^ ^
*
;*
| | | | | | | |__ 1 Dedicated baud rate generator output*
;*
| | | | | | |
*
;*
| | | | | | |____ 0 Reception error interrupt *
;*
| | | | | |
*
;*
| | | | | |______ 1 2 stop bits
*
;*
| | | | |
*
;*
| | | | |________ 0 7-bit data
*
;*
| | | |
*
;*
| | | |__________ 1 Even parity
*
;*
| | |
*
;*
| | |____________ 1 Even parity
*
;*
| |
*
;*
| |______________ 1 RX operation enabled *
;*
|
*
;*
|________________ 1 TX operation enabled *
;*
*
;****************************************************************/
mov
ASIM,#11110101b
;
;
;
Set TX done interrupt flag to 1
set1
;
;
;
Clear reception end receive error interrupt request flags
clr1
clr1
;
;
;
F_Rx_end
F_Err
;Reception end
;Error in data reception
Set receive buffer ptr
sel
movw
mov
;
;
;
SERIF
SRIF
Clear software flags
clr1
clr1
;
;
;
STIF
RB1
hl,#RxDataBuffer
b,#0
;offset to 0
Set to background register bank
sel
RB0
;
;
;
Enable reception end and receive error interrupts
;
clr1
SERMK
clr1
SRMK
No TX interrupt driven
set1
STMK
ret
;
$ej
;======================================================================
;
Module name: OutputAString
;
;
DESCRIPTION:
5-8
Asynchronous Serial Interface (UART)
;
.This module outputs data in the buffer pointed by the HL register
;
up to carriage return, a null, or maximum buffer size.
;
;
OPERATION:
;
. Read a byte from the buffer and incr. offset in B register.
;
. Check if the byte is the terminator.
;
. If no output, use the byte else return.
;
;
Input registers:
;
HL = output buffer ptr
;
c = size of buffer
;======================================================================
OutputAString:
mov
b,#0
OutLoop:
mov
a,[hl+b]
cmp
a,#CR
bz
$tx10
;no more
cmp
a,#0
bz
$tx10
;no more
xch
a,b
;save a register
cmp
a,c
xch
a,b
bnc
$tx10
;full, exit
call
!OutAByte
Incr. data ptr
inc
b
br
OutLoop
; output a CR
tx10:
mov
a,#CR
call
!OutAByte
mov
a,#LF
call
!OutAByte
ret
;
;======================================================================
;
Module name: OutAByte
;
;
DESCRIPTION:
;
.This module outputs a byte in the A register.
;
;
OPERATION:
;
. Wait for TX to be done.
;
. Clear TX done flag.
;
. Output a character to the TX buffer.
;
;
Input registers:
;
A register
;======================================================================
OutAByte:
;
Wait for Tx done
bf
STIF,$$
clr1
STIF
;
Output a data
mov
TXS,a
ret
5-9
Asynchronous Serial Interface (UART)
;======================================================================
;
Module name: INTSR
;
;
DESCRIPTION:
;
.This module is the interrupt service routine for a
;
receive operation.
;
;
OPERATION:
;
. Switch bank to 1.
;
. Disable request to send (RTS).
;
. Read a byte in the RX buffer.
;
. Save the byte to the input buffer.
;
. Incr. offset pointer.
;
. If number of bytes received exceeds 10 bytes or
;
character received is CR, then set buffer full flag
;
and reset offset pointer to 0.
;
. Enable RTS.
;
;
Input registers:
;
RXB = data
;
HL = buffer ptr
;
B reg = offset
;
;======================================================================
INTSR:
sel
RB1
;
Set RTS - Busy
set1
RTS_O
;
;
Receive data
;
mov
a,RXB
set1
F_RX_end
;Set a character received
;
Save to the buffer
mov
[hl+b],a
inc
b
; check end
cmp
a,#CR
;CR?
bz
$yesCr
;Yes
;
mov
a,b
cmp
a,#RXDataBufferSize
bc
$not full
yesCr:
; Rec buffer is full
set1
RecDone
;Set buffer full flag
mov
b,#0
;reset offset
;
notfull:
;
Clear RTS
clr1
RTS_O
;
Clear error flag
clr1
F_Err
;
reti
$ej
5-10
Asynchronous Serial Interface (UART)
;======================================================================
;
Module name: INTSER
;
;
DESCRIPTION:
;
.This module is the interrupt service routine for a
;
reception error.
;
;
OPERATION:
;
. Switch bank to 1.
;
. Read error status and store in the error flags variable (ErrorFlags).
;======================================================================
INTSER: ;Serial interface channel 2 UART reception error
sel
;
;
;
Check reception error
mov
mov
;
;
;
RB1
a,ASIS
ErrorFlags,a
Set an error flag
set1
F_Err
;
reti
;***********************************************************************
end
5-11
Asynchronous Serial Interface (UART)
C Language Program: Example of UART
/*;****************************************************************************
;
File name: UART.C
;
Date: 9/9/97
;****************************************************************************
;
Description:
; This example program demonstrates the asynchronous serial
; interface (UART). Serial interface channel 2 is set by using serial operation
; mode register 2 (CSIM2), asynchronous serial interface mode register (ASIM),
; asynchronous serial interface status register (ASIS), baud-rate generator
; control register (BRGC), and oscillation mode select register (OSMS).
; The UART mode of serial interface channel 2 transmits or receives 1-byte
; data following a start bit and can perform full-duplex operation.
;
; The example program will output a start-up message 'UART TEST STARTS' and then wait
; for string data up to 20 bytes or a carriage return, and output the input buffer to verify data.
;
;
The main program uses registers in RB0 (register group 0) and the Receive interrupt
;
routine uses registers in RB1 (register group 1).
;
;
One frame of transmit/receive data consists of a start bit,
;
8 character bits, no parity bit, and 2 stop bits.
;
;
The baud rate setting:
;
;
fxx
;
Baud rate = -----------;
;
;
;
;
;
;
;
;
;
;
;
;
;
2n x k
fxx = Main system clock frequency
n = Value set by TPS0-TPS3 ( 1 <= n <= 11)
k = Value set by MDL0-MDL3 ( 0 <= k <= 14)
Example:
Baud rate: 9600 bauds
Even parity
Start bit: 1
Stop bits: 2
8-bit: LSB first
CTS input pin: p31
RTS output pin: p32
;
;======================================================================
;
Output test string:'UART TEST STARTS'
;
Non-interrupt-driven TX module
;======================================================================
;
Input: Serial data stored in RxDataBuffer (10 bytes)
;
Interrupt-driven RX module
;======================================================================
;
Input error: Stored status of error bits
;======================================================================
;======================================================================*/
//
//
//
#include "define.h"
//
//
interrupt vectors
//
#pragma interrupt INTSER IntSerialError RB1
#pragma interrupt INTSR IntSerialInRB1
5-12
Asynchronous Serial Interface (UART)
/*;======================================================================
;
Equates
;======================================================================*/
#define RTS_O
#define RTSDirPort
#define CTS_I
P3.2
P3.2
P3.1
// ;Request-to-send
// ;Request-to-send direction port
// ;Clear-to-send
/*;======================================================================
;
Device selection flag
;======================================================================*/
//;
//;
K0S family
//;
// #define K789026
0
//;
//;
K780024, K780034
//;
// #define K780024
1
//;======================================================================
//;
#ifdef K789026
#define RXDirPort
#define TXDirPort
#define TXDataPort
PM2.2
PM2.1
P2.1
//;RX direction port
//;TX direction port
//;TX Data port
PM2.3
PM2.4
P2.4
//;RX direction port
//;TX direction port
//;TX data port
PM7.0
PM7.1
P7.1
//;RX direction port
//;TX direction port
//;TX data port
#else
#ifdef K780024
#define RXDirPort
#define TXDirPort
#define TXDataPort
#else
#define RXDirPort
#define TXDirPort
#define TXDataPort
#endif
//; K780024
#endif
//; K789026
/*;======================================================================
;
saddr area
;
FWA = 0fe20h
;======================================================================*/
__sreg unsigned char RXData;
__sreg unsigned char bptr;
__sreg unsigned char RXDataBuffer[10];
__sreg unsigned char TXData;
__sreg unsigned char i;
__sreg unsigned ErrorFlags;
#define OverrunErr
#define FramingErr
#define ParityErr
0
1
2
5-13
Asynchronous Serial Interface (UART)
unsigned char const TestString[] = {"UART TEST STARTS\n"};
/*;======================================================================
;
Bit Segment
;======================================================================*/
bit F_Err;
bit RecDone
;
//;Reception error flag
//;a string received Done
void OutAByte ();
void Init_UART ();
/*;======================================================================
;
Main
;======================================================================*/
void main ()
{
//;
//;
//;
//;
Oscillation mode select register
. Does not use divider circuit
OSMS = 0b00000001;
//;
//;
//;
Init. UART register
Init_UART ();
//;
//;
Enable INTP0 for DDB-K0070A
//;
#ifdef DDB
PMK0 = 0;
#endif
RecDone = 0;//;string received flag = 0
EI ();
//;
//;
Output start message
//;
for (i=0;i < sizeof TestString ; i++)
{
TxData = TestString[i];
OutAByte ();
if (TxData == '\n') break; // == LF
}
TxData = CR;
OutAByte ();
//;
//;
Wait for a string to be received
//;
while (TRUE) { if ( RecDone ) break;}
//;
//;
//;
Output the input buffer data
for (i=0;i < sizeof RxDataBuffer ; i++)
{
TxData = RxDataBuffer[i];
OutAByte ();
if (TxData == CR ) break;
}
TxData = LF;
OutAByte ();
//;
5-14
Asynchronous Serial Interface (UART)
//;
Reset flag to 0
RecDone = 0;
//;
while (TRUE);
}
/*;======================================================================
;
Module name: Init_UART
;
;
DESCRIPTION:
;
.This module is to initialize UART control and mode
;
registers.
;
;
OPERATION:
;
.Set dual ports to input for RX and output for TX
;
and latch the TX port to high
;
. Data format:1 start, 8-bit data, 1 stop, no parity
;
. Set Baud rate to 9600.
;
. Enable RX and TX operation.
;
. Clear all variables and flags for serial data transfer
;======================================================================*/
void Init_UART ()
{
//;
//;
p3.1 = CTS (input), P3.2 = RTS (output)
//;
RTS_O
= 1;
RTSDirPort = 0;
//;
//;
Set TX/RX port direction and output latch
//;
RXDirPort =1;
//;RX set to input direction
TXDirPort =0;
//;TX set to output direction
TXDataPort=1;
//;Latch output high
//;
//;
Baud rate (9600 baud/err=1.73%)
//;
BRGC = 0b10010000; //;9600 baud err = 1.73%/MCS = 1, fx = 5 MHz
/*****************************************************************
;*
Asynchronous serial interface mode register (ASIM) *
;*
*
;*
1 1 1 1 0 1 0 1
*
;*
^ ^ ^ ^ ^ ^ ^ ^
*
;*
| | | | | | | |__ 1 Dedicated baud rate generator output*
;*
| | | | | | |
*
;*
| | | | | | |____ 0 Reception error interrupt *
;*
| | | | | |
*
;*
| | | | | |______ 1 2 stop bits
*
;*
| | | | |
*
;*
| | | | |________ 0 7-bit data
*
;*
| | | |
*
;*
| | | |__________ 1 Even parity
*
;*
| | |
*
;*
| | |____________ 1 Even parity
*
;*
| |
*
;*
| |______________ 1 RX operation enabled *
;*
|
*
;*
|________________ 1 TX operation enabled *
;*
*
;****************************************************************/
ASIM = 0b11110101;
5-15
Asynchronous Serial Interface (UART)
//;
//;
//;
Set TX done interrupt flag to 1
STIF = 1;
//;
//;
//;
Clear reception end receive error interrupt request flags
SERIF = 0;
SRIF = 0;
//;
//;
//;
Clear software flags
F_Err = 0; // ;Error in data reception
//;
//;
//;
//;
Enable reception end and receive error interrupts
SERMK = 0;
SRMK = 0;
No TX interrupt driven
STMK = 1;
}
/*;======================================================================
;
Module name: OutAByte
;
;
DESCRIPTION:
;
.This module outputs a byte in the A register.
;
;
OPERATION:
;
. Wait for TX to be done.
;
. Clear TX done flag.
;
. Output a character to the TX buffer.
;
;
Input registers:
;
TXData = data byte
;======================================================================*/
void OutAByte ()
{
//;
Wait for TX done
while (TRUE) { if ( STIF ) break; }
STIF = 0;
//;
Output a data
TXS = TXData;
}
/*;======================================================================
;
Module Name: INTSR
;
;
DESCRIPTION:
;
.This module is the interrupt service routine for a
;
receive operation.
;
;
OPERATION:
;
. Switch bank to 1.
;
. Disable request to send (RTS).
;
. Read a byte in the RX buffer.
;
. Save the byte to the input buffer.
;
. Incr. offset pointer.
;
. If number of bytes received exceeds 10 bytes or
;
character received is CR, then set buffer full flag
;
and reset offset pointer to 0.
;
. Enable RTS.
;
5-16
Asynchronous Serial Interface (UART)
;
Input registers:
;
RXB = data
;
HL = buffer ptr
;
B reg = offset
;
;======================================================================*/
void IntSerialIn ()
{
RTS_O = 1;
//;
//;
Receive data
//;
RxData = RXB;
RxDataBuffer[bptr++] = RxData;
if (RxData == CR || bptr >= size of RxDataBuffer)
{
bptr = 0;
RecDone = 1;
}
//;
Clear RTS
RTS_O = 0;
//;
Clear error flag
F_Err = 0;
;
}
/*;======================================================================
;
Module name: INTSER
;
;
DESCRIPTION:
;
.This module is the interrupt service routine for a
;
reception error.
;
;
OPERATION:
;
. Switch bank to 1.
;
. Read error status and store in the error flags variable (ErrorFlags).
;======================================================================*/
void IntSerialError ()
{
//;
//;
Check reception error
//;
ErrorFlags = ASIS;
//;
//;
Set an error flag
//;
F_Err
= 1;
//;
}
5-17
Asynchronous Serial Interface (UART)
5-18
Software UART
6
Applicable Devices
•
All K0 microcontrollers
•
All K0S microcontrollers
Description
A software UART is a software-driven, asynchronous serial interface I/O. The software UART
needs a standard output port and a standard input port with an interrupt enable on the input
port. The data transmission timing is carried out with an 8-bit timer that generates a bit or a halfbit time for a given baud rate. A frame of transmit/receive data consists of a start bit, character
bits, stop bits, and a parity bit. Unlike the hardware UART, the frame size of the software UART
can be easily changed, and no other control registers are required except an 8-bit timer control
register. The software UART contains the following registers:
•
Output port for Tx
•
Input port for Rx (This port should be interrupted when a falling edge is detected on the pin.)
•
8-bit timer control registers
Setting Baud Rate
A software UART uses an 8-bit timer to set the baud rate. The bit time of a baud rate is
calculated as bit time in µs = 106/baud rate. In other words, for 9600 baud rate, 1,000,000/9600
= 104.1667 µs.
Example Program
This program demonstrates the functionality of a software UART by using an output port and an
input port with an interrupt on a falling edge of a serial data. When the program starts, it calls a
software UART initialization routine to set the ports and 8-bit timer. Once the initialization is
complete, it outputs a test string “Send a test string” and waits for a string of data from the host.
Each received data is echoed back to the host as well as stored in the buffer. If the string is
terminated by a carriage return, the entire data string received is sent to the host. A parity check
can be easily implemented by adding 1s in the character and 1s in the parity bit. If odd parity is
being checked, the 1s in the character and the parity bit must result in an odd number.
6-1
Software UART
Specifications
Specification
Description
Modules
Main loop
Output a data string
Output a character
Input a character
Initialization
Baud rate
9600 baud
Data format
1 start bit, 8 data bits, 2 stop bits, and no parity bit
Usage Restrictions
6-2
•
Receiving cannot be faster than 19.2K because of the relatively slow input data service time.
•
When a frame is transmitted, all other interrupts must be disabled because an interrupt will
cause a bit-time error.
•
The software UART will not work if Tx and Rx data is simultaneously transmitted and
received.
Software UART
Figure 6-1. Flowchart of a Software UART Program
External Interrupt 2
entry by a falling edge
of Rx data on
input port.
Software UART mode
entry.
Initialization:
• Tx and Rx ports.
• Set an 8-bit timer.
• Set Rx buffer pointers.
• Set output string
pointer.
• Select register group 1.
• Set a half-bit time and
wait for bit time over.
• Set a bit time.
• Set a counter to 8.
• Clear Rx data register.
Output test string
"Send test string"
Input data string
received?
Bit time over?
No
Yes
Yes
Transmit input
string.
No
Rx port = 1?
Carry bit = 0
No
Tx port = 0
Yes
Tx port = 1
Shift Tx data right
with carry bit.
Bit counter = 0
?
Store Rx data into
Rx buffer.
Yes
Bit = 1?
Carry bit = 1
Decrement counter.
• Set a bit time.
• Set a counter to 8.
Bit time over?
Char = CR or buffer
full?
No
Increment
buffer pointer.
Decrement counter.
No
Yes
Shift Rx data right
with carry bit.
Transmit a character
entry.
No
No
Bit counter = 0
?
Echo Rx data.
Return
Return
Yes
Terminated the Rx
buffer by a null.
Set receive done
flag.
97YL-0313C (12/97)
6-3
Software UART
Assembly Language Program: Example of Software UART Implementation
;****************************************************************************
;
File name: SOFTUART.ASM
;
Date: 9/16/97
;****************************************************************************
;
Description:
;
; This program implements a software UART.
;
; The serial data pin P02 (INTP2) is used for Rx data and P01 for Tx data.
;
;
Tx data: Output a test string.
;
Rx data: Data from RS-232 is stored in the RxBuffer when INTP2 is interrupted
;
by the start bit of a character.
;
;
The baud rate for this demo module is set to 9600 baud.
;
;
; Description:
; ------------;
; Serial data is transmitted or received with a fixed baud rate. The
; standard baud rates are:
;
;
300, 600, 1200, 2400, 4800, 9600, 14.4k, 19.2k, ...
;
;
To calculate the bit time of a baud rate, an 8-bit timer (tc0)
;
is used to set a bit time or half-bit (HBt) time.
;
;
Formula of a bit time:
;
;
Bit time = fxx/baud_rate
;
;
fxx = fx/2n (selected by timer clock select register)
;
;
For example, 9600 baud rate (fxx = 1.25 MHz):
;
;
1,250,000/9600 = 130.2083 µs
;
;
Serial data format for this example program:
;
;
1 start bit, 8 data bits, 2 stop bits, no-parity bit.
;
;
LIMITS:
;
------;
;
. Software UART may not be usable if the baud rate is faster than
;
19.2k because the input data service time is not fast enough
;
to service the data.
;
;
. When a character is transmitted, all other interrupts must be disabled
;
because an interrupt will cause a bit-time error.
;
;
. It will not work if Tx and Rx data are simultaneously transmitted
;
and received.
;
;
This example uses 9600 baud rate.
;
;**************************************************************************************
;======================================================================
;
Output test string:'Send a test data string',0
;
Non-interrupt-driven TX module
;======================================================================
6-4
Software UART
;
Input: Serial data stored in RxDataBuffer (80 bytes)
;
Interrupt-driven RX module
;
;======================================================================
;
for only DDB-K0070A
;
$set (DDB)
;
;
;======================================================================
;
CR
equ
13
;Carriage return
LF
equ
10
;Line feed
;======================================================================
;
Equates
;======================================================================
;//
;//
Bit time of some baud rates based on fx = 5 MHz
;//
Counter resolution
;//
fxx = 1.25 MHz (0.8 µs)
;//
BitTime_BaudRate384k
equ 33
;// Theoretical count 32.5521
BitTime_BaudRate192k
equ 65
;// 65.1042
BitTime_BaudRate144k
equ 87
;// 86.8056
BitTime_BaudRate9600
HBtTime_BaudRate9600
;/;
;/;
K0S family
;/;
;/ #define K0S
;
$set (K0)
equ 130
equ 65
;// 130.2083
;// 65.1041
$if (K0)
TxData
TxDataPDir
equ P0.1
equ PM0.1
;// TX
;// TX data dir
RxData
RxDataPDir
equ P0.2
equ PM0.2
;// RX
;// RX data dir
TxData
TxDataPDir
equ P3.1
equ PM3.1
;// TX
;// TX data dir
RxData
RxDataPDir
equ P3.2
equ PM3.2
;// RX
;// RX data dir
$else
$endif
;======================================================================
;
Saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
;======================================================================
;
Even-boundary pair
;======================================================================
dseg
saddrp
6-5
Software UART
;======================================================================
;
Bit segment
;======================================================================
bseg
Full
dbit
;buffer full
;======================================================================
;
;
Internal High RAM allocation
;
;======================================================================
dseg
IHRAM
ds
20h
Stack:
RxBufferSize
RxBuffer:
equ 80
ds (RxBufferSize)
;======================================================================
;
;
macro
;
;;WaitT1Int while (TRUE){if (TMIF1) break;} TMIF1 = 0
;======================================================================
WaitT1Int macro
bf
TMIF1,$$
clr1
TMIF1
endm
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
org
dw
0Ah
INTERRUPT2
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
ResetStart:
di
;
;
Oscillation mode select register
;
. Does not use divider circuit
;
mov
OSMS,#00000001b
;
;
Set stack pointer (IHMEM + 20H)
;
movw
SP,#Stack
;.
;
Init UART Register
;
call
!Init_UART
;
;
Enable INTP0 for DDB-K0070A
;
6-6
;Disable interrupt
;Stack ptr
Software UART
$if (DDB)
clr1
PMK0
clr1
ei
Full
$endif
Main_Loop:
;
;
;
Output start message
mov
movw
call
;
;
;
Wait for a string to be received
bf
clr1
;
;
;
c,#TestStringSize
hl,#TestString
!OutputAString
Full,$$ ;string received flag = 0
Full
Output the input buffer Data
mov
call
mov
call
a,#LF
!OutAByte
a,#CR
!OutAByte
mov
movw
call
c,#RxBufferSize
hl,#RxBuffer
!OutputAString
mov
call
mov
call
a,#LF
!OutAByte
a,#CR
!OutAByte
br
$Main_Loop
;
;
TestString:
db 'Send a test data string',0
TestStringEnd:
TestStringSizeequ
TestStringEnd - TestString
;======================================================================
;
Module name: Init_UART
;
;
DESCRIPTION:
;
.This module is to initialize UART control and mode
;
registers.
;
;
OPERATION:
;
.Set dual ports to input for Rx and output for Tx
;
and latch the Tx port to high.
;
. Data format:
;
. 1 start bit, 8-bit data, 2stop bits, no parity bit.
;
. Set baud rate to 9600.
;
. Enable Rx and Tx operation.
;
. Clear all variables and flags for serial data transfer.
;======================================================================
Init_UART:
;
;
Set Port
;
6-7
Software UART
set1
clr1
set1
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
PMK2 = 0
INTM1 = 0
clr1
PMK2
mov
INTM1,#0
;// Unmask INTP2
;// all falling edge interrupt
Baud rate = 9600 baud
Set timer 0 Register
Tick = 1.25 MHz (800 ns)
Disable 8-bit timer
TCL1 = 0b00000111
TMC1 = 0B00000000
TOC1 = 0B00000000
TCL1,#00000111b
TMC1,#00000000b
TOC1,#00000000b
;// Select 1.25 MHz as count clock
;// stop operation
;// No output compare
;// Select 1.25 MHz as count clock
;// stop operation
;// No output compare
Clear software flags
Set receive buffer ptr
sel
movw
mov
;
;
;
; Input direction
; Output direction
; Set to high
Set interrupt for INTP2
mov
mov
mov
;
;
;
;
RxDataPDir
TxDataPDir
TxData
RB1
hl,#RxBuffer
b,#0
;offset to 0
Set to background register bank
sel
ret
RB0
;
$ej
;======================================================================
;
Module name: OutputAString
;
;
DESCRIPTION:
;
.This module outputs data in the buffer pointed by the HL register
;
up to carriage return, a null, or maximum buffer size.
;
;
OPERATION:
;
. Read a byte from the buffer and increment offset in B register.
;
. Check if the byte is the terminator.
;
. If no output,use the byte else return.
;
;
Input registers:
;
HL = output buffer ptr
;
c = size of buffer
;======================================================================
OutputAString:
mov
e,#0
OutLoop:
mov
a,e
mov
b,a
mov
a,[hl+b]
cmp
a,#CR
bz
$tx10
;no more
cmp
a,#0
bz
$tx10
;no more
6-8
Software UART
xch
cmp
xch
bnc
a,e
a,c
a,e
$Tx10
;Save a register
;full, exit
call
!OutAByte
Incr. data ptr
inc
e
br
OutLoop
; output a CR
Tx10:
mov
a,#CR
call
!OutAByte
mov
a,#LF
call
!OutAByte
ret
;
;======================================================================
;
Module name: OutAByte
;
;
DESCRIPTION:
;
.This module outputs a byte in the A register.
;
;
OPERATION:
;
. Wait for Tx to be done.
;
. Clear Tx done flag.
;
. Output a character to the Tx buffer.
;
;
Input registers:
;
A register
;
used B reg.
;======================================================================
OutAByte:
;
Set a bit time
mov
CR10,#082H
; 130
;
;
Start bit
;
set1
TMC1.0
clr1
TxData
;
;
Read 8 Bits
;
mov
b,#8H ; 0
outlp:
; wait for a bit time
WaitT1Int
bf
a.0,$?L0028
set1
TxData
br
$?L0029
?L0028:
clr1
TxData
?L0029:
clr1
CY
rorc
a,1
dbnz
b,$outlp
WaitT1Int
; // wait for a bit time
;
;
two stop bits
;
set1
TxData
WaitT1Int
; // wait for a bit time
WaitT1Int
; // wait for a bit time
clr1
TMC1.0
6-9
Software UART
ei
ret
;======================================================================
;
Module name: INTSR
;
;
DESCRIPTION:
;
.This module is the interrupt service routine for
;
receive operation.
;
;
OPERATION:
;
. Switch bank to 1.
;
. Disable request to send (RTS).
;
. Read a byte in the Rx buffer
;
. Save the byte to the input buffer.
;
. Incr. offset pointer.
;
. If number of bytes received exceeds 10 bytes or
;
character received is CR, then set buffer full flag
;
and reset offset pointer to 0.
;
. Enable RTS
;
;
Input registers:
;
HL = buffer ptr
;
B reg = offset
;
;======================================================================
INTERRUPT2:
sel
RB1
;
;
Half-bit time
;
mov
CR10,#HBtTime_BaudRate9600 - 8 ; 8*4 Cycles Compensation
set1
TMC1.0
WaitT1Int
; // wait for a bit time
;
mov
CR10,#BitTime_BaudRate9600;
mov
a,#0
mov
c,#8
Rxlp:
WaitT1Int
;// wait for a bit time
clr1
cy
bf
RxData,$rx10
set1
cy
Rx10:
rorc
a,1
dbnz
c,$rxlp
;
;
Save data
;
;
Save to the buffer
mov
[hl+b],a
mov
d,a
inc
b
; check end
cmp
a,#CR
;CR?
bz
$yesCr
;Yes
;
mov
a,b
cmp
a,#RxBufferSize
bc
$notfull
yesCr:
dec
b
;
Store a terminator
mov
a,#0
6-10
Software UART
mov
;
;
;
Full
b,#0
;Set buffer full flag
;reset offset
Output a char.
Reset int2 flag
clr1
;
;
;
;terminator
Rec buffer is full
set1
mov
;
;
;
notfull:
;
;
;
[hl+b],a
PIF2
Echo the char.
push
mov
call
pop
bc
a,d
! OutAByte
bc
;
reti
;***********************************************************************
end
6-11
Software UART
C Language Program: Example of Software UART Implementation
#define DEBUG 0
#pragma interrupt INTP2 Interrupt2 RB1
/*********************************************************************************
;
File Name: SOFTUART.C
;
Date: 9/16/97
;
; This program is an application for a software UART.
;
; The serial data pins are P02 (INTP2) for Rx data and P01 for Tx data (K0 family).
;
;
Tx data: Output a test string.
;
Rx data: Data from RS-232 is stored in the RxBuffer when INTP2 is interrupted
;
by the start bit of a character.
;
;
The baud rate for this demo module is set to 9600.
;
;
; Description:
; ------------; Serial data is transmitted or received with a fixed baud rate. The
; standard baud rates are:
;
;
300, 600, 1200, 2400, 4800, 9600, 14.4k 19.2k, ...
;
;
To calculate the bit time of a baud rate, an 8-bit timer (tc0)
;
is used to set a bit time or half-bit (HBt) time.
;
;
Formula of a bit time:
;
;
Bit time = fxx/baud_rate
;
;
fxx = fx/2n (selected by timer clock select register)
;
;
For example, 9600 baud rate (fxx = 1.25 MHz):
;
;
1,250,000 / 9600 = 130.2083 µs
;
;
Serial data format for this application example program:
;
;
1 start bit, 8 data bits, 2 stop bits, no parity bit.
;
;
LIMITS:
;
------;
;
Software UART may not be usable if the baud rate is faster than
;
19.2k because the input data service time is not fast enough
;
to service the data.
;
;
When a character is transmitted, all other interrupts must be disabled
;
because an interrupt will cause bit-time error.
;
;
It will not work if Tx and Rx data are simultaneously transmitted
;
and received.
;
;
This example uses 9600 baud rate.
;
***************************************************************************************/
#include "define.h"
//
6-12
Software UART
//
Bit time of some baud rates based on fx = 5 MHz
//
Counter resolution
//
fxx = 1.25 MHz (0.8 µs)
//
#define BitTime_BaudRate384k
33
#define BitTime_BaudRate192k
65
#define BitTime_BaudRate144k
87
#define BitTime_BaudRate9600
#define HBtTime_BaudRate9600
//
//
130
65
;// Theoretical count 32.5521
;// 65.1042
;// 86.8056
;// 130.2083
;// 65.1041
//#define K0S
#ifndef K0S
#define TxData
#define TxDataPDir
PM0.1
#define RxData
#define RxDataPDir
PM0.2
P0.1
//TX
//TX data dir
P0.2
//RX
//RX data dir
P3.1
//TX
//TX data dir
P3.2
//RX
//RX data dir
#else
#define TxData
#define TxDataPDir
PM3.1
#define RxData
#define RxDataPDir
PM3.2
#endif
#define WaitT1Intwhile (TRUE){if (TMIF1) break;} TMIF1 = 0
#if 1
unsigned char const TestString[] = "Send a test data string";
#else
unsigned char const TestString[] = {0x55,0x55,0};
#endif
#define RxBufferSize80
unsigned char RxBuffer[RxBufferSize];
__sreg unsigned char i,j,k,c;
__sreg unsigned char ir,ichar, bptr;
bit full;
void SerialTx (unsigned char c);
void Main ()
{
DI ();
OSMS = 0b00000001;
PMK0 = 0;
// select 5 MHz
// for DDB BOARD - INTP0 has to be set
// Set timer 0 Register
TCL1 = 0b00000111;
TMC1 = 0B00000000;
// Select 1.25 MHz as count clock
// stop operation
6-13
Software UART
TOC1 = 0B00000000;
// No output compare
RxDataPDir = 1;
TxDataPDir = 0;
TxData
= 1;
// set to input dir. for Rx
// Set to output dir. for Tx
// Set to high
PMK2 = 0;
INTM1 = 0;
// Unmask INTP2
// all falling edge interrupt
bptr = 0;
EI ();
while (TRUE)
{
Full = 0;
//
// clear Rx buffer
//
for (i = 0; i < sizeof RxBuffer; i++) RxBuffer[i++] = 0;
i = 0;
while (TRUE)
{
c = TestString[i++];
if ( !c ) break;
SerialTx (c);
}
// Output CR/LF
SerialTx (0x0D);
SerialTx (0x0A);
// CHECK input buffer full
while (!Full);
SerialTx (0x0A);
//LF
for (i=0;i< strlen (RxBuffer) ; i++)
{
c = RxBuffer[i];
if ( !c ) break;
SerialTx (c);
}
// Output CR/LF
SerialTx (0x0D);
//CR
SerialTx (0x0A);
//LF
}
}
/************************************************************************=*****
*
Output a character to serial port
*
Send from LSB to MSB
************************************************************************=*****/
void SerialTx (unsigned char c)
{
register unsigned char i;
DI ();
CR10 = BitTime_BaudRate9600;
TCE1 = 1; // Enable tc1 only
//
6-14
Software UART
// Start Bit
//
TxData = 0;
//
// Send Data
//
for (i = 0; i < 8; i ++)
{
WaitT1Int;
// wait for a bit time
if ( c & 1) TxData = 1; else TxData = 0;
c >>= 1;
}
WaitT1Int; // wait for a bit time
//
// two stop bit
//
TxData = 1;
WaitT1Int; // wait for a bit time
WaitT1Int; // wait for a bit time
TCE1 = 0;
EI ();
// Disable tc1 only
}
/************************************************************************=*****
*
Read a character from the serial port
*
Read a character and store to the input buffer
*
Note:
*
Interrupt acknowledge time is min. 7 clks to 33 clks.
*
This time must be compensated when data is formed.
************************************************************************=*****/
void Interrupt2 (void)
{
NOP ();
CR10 = HBtTime_BaudRate9600 - 8; // 8*4 Cycles Compensation
TCE1 = 1;
// Enable tc1 only
WaitT1Int; // wait for a bit time
// Position at the half of start bit
//
// Rec Data
//
CR10 = BitTime_BaudRate9600;
ichar = 0;
for (ir= 0; ir< 8; ir++)
{
ichar >>= 1;
WaitT1Int;
if ( RxData == 1) ichar |= 0x80;
}
//
//
Don't read stop bit to speed up for next character reading
//
Save to buffer
//
RxBuffer[bptr++] = ichar;
if (bptr >= RxBufferSize || ichar == 0X0D)
{
bptr--;
RxBuffer[bptr] = 0;
bptr = 0;
Full = 1;
}
TCE1 = 0;
// Disable TC1 only
6-15
Software UART
//
//
//
}
6-16
Reset the interrupt flag
PIF2 = 0;
Echo the char.
SerialTx (ichar);
// Reset INT2 interrupt flag
Interval Timer Operation with 8-Bit Timer 2
7
Applicable Devices
•
•
•
•
•
•
•
•
•
•
•
•
µPD7801xF
µPD7801xH
µPD7805x
µPD7805xF
µPD78005x
µPD7807x
µPD78070A
µPD7806x
µPD78030x
µPD7804xH
µPD7804xF
µPD78020x
Description
The purpose of this program is to demonstrate interval timer operation in the K series
environment. The 8-bit timer/event counter channels 1 and 2 operate as interval timers by
generating interrupt requests repeatedly at intervals preset to 8-bit compare registers CR10 and
CR20. When the current counter values of timer registers 1 and 2 match the values set to the
compare registers, the timer registers are reset to 0 and interrupt request signals INTTM1 and
INTTM2 are generated.
The counting clock of timer TM1 can be selected with bits 0 to 3 (TCL10 to TCL13) of timer
clock select register TCL1. The counting clock of timer TM2 can be selected with bits 4 to 7
(TCL14 to TCL17) of TCL1.
The interval timer operation is widely used in such areas as a sampling rate with an ADC
operation, an elapsed time setting, various delay functions, and time-of-day setting.
The 8-bit timer 2 includes the following registers:
•
•
•
•
Timer register 2 (TM2)
Output compare register 2 (CR20)
Timer clock select register TCL1)
8-bit timer mode control register 1 (TMC1)
Example Program
This sample program sets two channels’ elapse time values in the range from 200 µs to 12.8
seconds (see Figures 7-1 and 7-2). When the current value of the count clock matches the
value of compare register 2, an interrupt request is generated. With interval timer operation, the
user can set longer elapse times by decrementing the repeat counter.
7-1
Interval Timer Operation with 8-Bit Timer 2
1. SoftCounter_0 is an 8-bit software counter that decrements every 200 µs until it reaches
0. The counter can be used to set elapse time between 200 µs and 51.2 milliseconds.
2. SoftCounter_1 is a 16-bit software counter that decrements every 200 µs until it reaches
0. The counter can be used to set elapse time between 200 µs and 12.8 seconds.
3. The background module will set an elapse time to 10 and 100 milliseconds, respectively,
and toggle P1.0 and P1.1 whenever each time reaches 0.
The modules in the sample program contain three parts:
1. Main module
2. 8-bit timer mode 2 initialization
3. 8-bit timer mode 2 interrupt service routine
Figure 7-1. 8-Bit Timer Mode Control Register (TMC1)
7-2
7
6
5
4
3
2
1
0
0
0
0
0
0
TMC12
TCE2
TCE1
Bit
0
TCE1
8-bit timer register 1 operation
0 = Operation stop (TM1 clear to 0)
1
TCE2
8-bit timer register 2 operation
1 = Operation enable
2
TMC12
Operating mode
0 = 8-bit timer register x 2 channel modes (TM1, TM2)
Interval Timer Operation with 8-Bit Timer 2
Figure 7-2. Flowchart of Interval Timer Operation
Interval mode operation
sample program
8-bit timer 2 interrupt
service routine entry
Initialization:
• Set 0.8-µs count
clock in TCL1.
• Enable TM2 in TMC1.
• Enable TM2 interrupt.
Set to RB1.
SoftCounter_0 > 0
?
Yes
No
• Set SoftCounter_0
(8-bit elapse time
counter) = 50 (10 ms).
• Set SoftCounter_1
(16-bit elapse time
counter) = 500 (100 ms).
SoftCounter_1 > 0
?
No
SoftCounter_0 = 0
?
No
Yes
Decrement
SoftCounter_1 by 1.
Yes
• Toggle P1.0.
• Reset SoftCounter_0
= 50 for 10-ms elapse
time.
No
SoftCounter_1 = 0
?
Decrement
SoftCounter_0 by 1.
Return
Yes
• Toggle P1.1.
• Reset SoftCounter_1
= 500 for 100-ms
elapse time.
97YL-0312C (2/98)
7-3
Interval Timer Operation with 8-Bit Timer 2
Assembly Language Program: Example of an 8-Bit Interval Timer Implementation
;****************************************************************************
;
File name: TIMER2.ASM
;
Date: 9/17/97
;****************************************************************************
;
Description:
;
; This program demonstrates interval timer operations in the K0 and
; K0S family microcontrollers. The 8-bit timer/event counters 1 and 2 operate as
; interval timers. They generate interrupt requests repeatedly at intervals
; preset to 8-bit compare registers CR10 and CR20. When the
; counter values of 8-bit timer registers 1 and 2 match the values set
; to the compare registers, the timer registers are reset to 0 and
; interrupt request signals INTTM1 and INTTM2 are generated.
;
; The counting clock of TM1 can be selected with bits 0 to 3
; of timer clock select register TCL1. The counting clock of TM2 can be selected
; with bits 4 to 7 of TCL1.
;
; The interval timer operation is widely used in the areas of sample rate with ADC
; operation, elapsed time setting, various delay functions, and time-of-day setting.
;
;
Sample program
;
-------------;
; The sample program sets two delay times from 200 µs to 12.8 seconds.
; When the count clock matches the value of compare register 2, an interrupt
; request is generated. With interval timer operation, the user can set longer elapse
; times by decrementing the repeat counter.
;
;SoftCounter_0 is an 8-bit software counter that decrements
;
every 200 µs until it reaches 0.
;
The counter can be used to set elapse times between 200 µs and
;
51.2 ms.
;
;SoftCounter_1 is a 16-bit software counter that
;
decrements every 200 µs until it reaches 0.
;
The counter can be used to set elapse times between 200 µs and
;
12.8 seconds.
;
;The background module will set an elapse time to 10 and 100 ms and
;toggle P1.0 and P1.1, respectively, whenever each time reaches 0.
;
;======================================================================
;
for only DDB-K0070A
;
$set (DDB)
$set (K0)
;======================================================================
;
Equates
;======================================================================
;======================================================================
;
saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
;
;
Time of day by interval mode
;
SoftCounter_0: ds 1 ; 8-bit elapse counter
;======================================================================
7-4
Interval Timer Operation with 8-Bit Timer 2
;
Even boundary pair
;======================================================================
dseg
saddrp
SoftCounter_1: ds 2 ; 16-bit elapse counter
;======================================================================
;
Bit segment
;======================================================================
bseg
;======================================================================
;
;
Internal high RAM allocation
;
dseg
IHRAM
ds
20h
Stack:
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
org
dw
26h
Interval_timer_2 ; 8-bit timer 2 interrupt
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
public
ResetStart
ResetStart:
;
;
Oscillation mode select register
;
. Does not use divider circuit
;
$if (K0)
mov
OSMS,#00000001b
$endif
;
;
Set stack pointer (IHMEM + 20H)
;
movw
SP,#Stack
;Stack ptr
;
;
Init. Watch timer control register
;
Call
!InitTimer_2
;
;
Enable INTP0 for DDB-K0070A
;
$if (DDB)
clr1
PMK0
$endif
;
;
Clear time variables
;
;
Set Port 1.0 and Port 1.1 to output direction
;
7-5
Interval Timer Operation with 8-Bit Timer 2
clr1
clr1
clr1
clr1
;
;
;
;
;
PM1.0
P1.0
PM1.1
P1.1
Clear IRQ flags
clr1
TMIF2
ei
Set for 10-ms and 100-ms elapse time
mov
movw
SoftCounter_0,#50
SoftCounter_1,#500
;10 ms
;100 ms
;
main_loop:
;
;
;
;
main15:
cmp
SoftCounter_0,#0
bnz
$main15
Toggle P1.0
set1
P1.0
nop
clr1
P1.0
mov
SoftCounter_0,#50
set for 100-ms elapse time
movw
cmpw
bnz
ax,SoftCounter_1
ax,#0
$main20
movw
SoftCounter_1,#500
;Don't decrement if the value is 0
;
;
Toggle P1.1
set1
P1.1
nop
clr1
P1.1
;
main20:
br
$main_loop
;======================================================================
;
Initialization
;
;
. Set 8-bit timer 2 to 0.8-µs count clock.
;
. Set interrupt every 200 µs.
;
. Enable 8-bit timer 2 interrupt request.
;
;======================================================================
InitTimer_2:
;
;
8-bit timer mode control register (TMC1)
;
;
0 0 0 0 0 0 1 0
;
| | | | | | | |__ timer 1 operation disable
;
| | | | | | |____ timer 2 operation enable
;
| | | | | |______ 8-bit timer register x 2 channel mode
;
| | | | |________ 0
;
| | | |__________ 0
;
| | |____________ 0
;
| |______________ 0
;
|________________ 0
;
mov
TMC1,#00000010b
;
7-6
Interval Timer Operation with 8-Bit Timer 2
;
;
;
8-bit timer clock selection register (TCL1)
Set count clock to 0.8 µs for timer 2
mov
;
;
;
;
Set interval timer to timer 2 output compare register
as 200 interval timer operation
mov
;
;
;
TCL1,#01110000b
CR20,#250
Set TM2 interrupt mask register (enable interrupt)
clr1
ret
TMMK2
;======================================================================
;
Module name: Interval timer 2 interrupt
;
;
DESCRIPTION:
;
.Set interval time variables.
;
;
OPERATION:
;
. Increment tick.
;
. If tick = 33, then increment seconds.
;
. If seconds = 60, increment minutes.
;
. If minutes = 60, increment hours.
;
;======================================================================
public
Interval_timer_2
Interval_timer_2:
sel
RB1
;
;
8-bit soft counter
;
cmp
SoftCounter_0,#0
bz
$it10
dec
SoftCounter_0
;
;
16-bit soft counter
;
it10:
movw
ax,SoftCounter_1
cmpw
ax,#0
bz
$it20
; Decrement
decw
ax
movw
SoftCounter_1,ax
;
it20:
reti
;Don't decrement if the value is 0
;Don't decrement if the value is 0
;======================================================================
end
_
7-7
Interval Timer Operation with 8-Bit Timer 2
C Language Program: Example of an 8-Bit Interval Timer Implementation
/*;****************************************************************************
;
File name: TIMER2.C
;
Date: 9/17/97
;****************************************************************************
;
Description:
; This program demonstrates interval timer operations in the K
; series microcontrollers. The 8-bit timer/event counters 1 and 2 operate as
; interval timers. They generate interrupt requests repeatedly at intervals
; preset to 8-bit compare registers CR10 and CR20. When the
; counter values of 8-bit timer registers 1 and 2 match the values set
; to the compare registers, the timer registers are reset to 0 and
; interrupt request signals INTTM1 and INTTM2 are generated.
;
; The counting clock of TM1 can be selected with bits 0 to 3
; of timer clock select register TCL1. The counting clock of TM2 can be selected
; with bits 4 to 7 of TCL1.
;
; The interval timer operation is widely used in the areas of sample rate with ADC
; operation, elapsed time setting, various delay functions, and time-of-day setting.
;
;
Sample program
;
-------------;
; The sample program sets two delay times from 200 µs to 12.8 seconds.
; When the count clock matches the value of compare register 2, an interrupt
; request is generated. With interval timer operation, the user can set longer elapse
; times by decrementing the repeat counter.
;
;SoftCounter_0 is an 8-bit software counter that decrements
;
every 200 µs until it reaches 0.
;
The counter can be used to set elapse times between 200 µs and
;
51.2 ms.
;
;SoftCounter_1 is a 16-bit software counter that
;
decrements every 200 µs until it reaches 0.
;
The counter can be used to set elapse times between 200 µs and
;
12.8 seconds.
;
;The background module will set an elapse time to 10 and 100 ms and
;toggle P1.0 and P1.1, respectively, whenever each time reaches 0.
;
;=================================================================================*/
#include "define.h"
#define K0
#pragma interrupt INTTM2 Interval_timer_2 RB1
//;
//;
//;
__sreg
__sreg
Time of day by Interval mode
unsigned char SoftCounter_0;//; 8-bit elapse counter
unsigned int SoftCounter_1;//; 16-bit elapse counter
void InitTimer_2 (void);
/*;======================================================================
;
Main
;======================================================================*/
void main (void)
{
7-8
Interval Timer Operation with 8-Bit Timer 2
//;
//;
//;
//;
#ifdef K0
Oscillation mode select register
. Does not use divider circuit
OSMS = 0b00000001;
#endif
//;
//;
//;
Init. Watch timer control register
InitTimer_2 ();
//;
//;
Enable INTP0 for DDB-K0070A
//;
#ifdef DDB
PMK0 = 0;
#endif
//;
//;
//;
//;
//;
Clear time variables
Set Port 1.0 and Port 1.1 to output direction
PM1.0 = 0;
P1.0 = 0;
PM1.1 = 0;
P1.1 = 0;
//;
//;
//;
Clear IRQ flags
TMIF2 = 0;
EI ();
//;
//;
//;
Set for 10-ms and 100-ms elapse time
SoftCounter_0 = 50;// ;10 ms
SoftCounter_1 = 500;// ;100 ms
//;
while (TRUE)
{
if ( !SoftCounter_0)
{
//;
//;
//;
Set for 100-ms elapse time
SoftCounter_0 = 50;
//; Toggle P1.0
P1.0 = 1;
NOP ();
P1.0 = 0;
}
//;
//;
//;
if ( !SoftCounter_1)
{
Set for 100-ms elapse time
SoftCounter_1 = 500;
//; Toggle P1.0
P1.1 = 1;
NOP ();
P1.1 = 0;
}
7-9
Interval Timer Operation with 8-Bit Timer 2
}
}
/*;======================================================================
;
Initialization
;
;
. Set 8-bit timer 2 to 0.8-µs count clock.
;
. Set interrupt every 200 µs.
;
. Enable 8-bit timer 2 interrupt request.
;
;======================================================================*/
void InitTimer_2 (void)
{
/*
;
;
8-bit timer mode control register (TMC1)
;
;
0 0 0 0 0 0 1 0
;
| | | | | | | |__ timer 1 operation disable
;
| | | | | | |____ timer 2 operation enable
;
| | | | | |______ 8-bit timer register x 2 channel mode
;
| | | | |________ 0
;
| | | |__________ 0
;
| | |____________ 0
;
| |______________ 0
;
|________________ 0
;
*/
TMC1 = 0b00000010;
//;
//;
8-bit timer clock selection register (TCL1)
//;
Set count clock to 0.8 µs for timer 2
//;
TCL1 = 0b01110000;
//;
//;
Set interval timer to timer 2 output compare register
//;
as 200 interval timer operation
//;
CR20 = 250;
//;
//;
Set TM2 interrupt mask register (enable interrupt)
//;
TMMK2 = 0;
}
/*;======================================================================
;
Module name: Interval timer 2 interrupt
;
;
DESCRIPTION:
;
.Set interval time variables.
;
;
OPERATION:
;
. Increment tick.
;
. If tick = 33, then increment seconds.
;
. If seconds = 60, increment minutes.
;
. If minutes = 60, increment hours.
;
;======================================================================*/
void Interval_timer_2 (void)
{
//;
//;
8-bit soft counter
//;
if (SoftCounter_0) SoftCounter_0--;
7-10
Interval Timer Operation with 8-Bit Timer 2
//;
//;
//;
16-bit soft counter
if (SoftCounter_1) SoftCounter_1--;
}
7-11
Interval Timer Operation with 8-Bit Timer 2
7-12
8
DTMF Tone Generation
Applicable Devices
•
•
•
µPD7808x
µPD7807x
µPD780870A
Description
Dual-tone multifrequency (DTMF) signaling is widely used in telephony and
telecommunications. With the growing popularity of voice and electronic mail, along with other
interactive communication services, the need for DTMF signaling is expanding.
DTMF tones can be generated by pulse width modulation (PWM), eliminating the need for an
external DAC. The tones are produced by using a form of delta modulation. When run through a
low-pass filter, the result is an accurate DTMF tone.
The actual implementation of a DTMF signal is accomplished by adding two different sinusoids.
The following matrix shows the required frequencies for a digit (phone button) selection. The
formula “delta” adds these two tones and selects the appropriate cosine value from a table. This
cosine value is used to set T1. The total value of T1 + T2 is fixed; therefore (T1 + T2) – T1 = T2.
Both values are loaded into the PWM registers and the appropriate PWM timing is output.
Matrix
Column 1: 1209 Hz
Column 2: 1336 Hz
Column 3: 1477 Hz
Column 4: 1633 Hz
Row 1:
697 Hz
1
2
3
A
Row 2:
770 Hz
4
5
6
B
Row 3:
852 Hz
7
8
9
C
Row 4:
941 Hz
*
0
#
D
Example: If the “1” digit is selected, tones of 1209 Hz and 697 Hz are used.
The “delta” equation shown below calculates the sine wave frequency for a selected digit.
Delta = N*f/fs
Where:
f = DTMF frequency
fs = sampling frequency (typically 8 kHz)
N = 256 table length
Note: A higher sampling rate will generate a more accurate sine wave.
8-1
DTMF Tone Generation
Low-Pass Filter Output with PWM Signal Timing
t1
•
•
t2
t1 + t2 = sample frequency (example 8 kHz = 125 µs)
The delta value must be adjusted according to the system clock.
Cosine Twiddle Factor Formula for Dual-Tone with 8-Bit Resolution
•
•
Cosine (360/256 * n) * (0x10000/0x100/4) + 0x40
Cosine (360/256 * n) * 0x40 + 0x40
PWM Output Signal Duty Cycle Computing Formula
T1 = Delta of low-tone frequency + delta of high-tone frequency
PWM Output Operation Registers
•
•
•
8-bit timer control registers 5 and 6 (TMCn)
Output compare registers for 8-bit timers 5 and 6 (CR50 or CR60)
8-bit timer clock select registers 5 and 6 (TCLn)
DTMF Tone Generation Demo Program
The DTMF tone program module employs a PWM output function of the 8-bit timer control
register (TMC5) in the µPD7808x, µPD7807x, and µPD78070A families (Figure 8-1). The 5MHz system clock is used. The duty ratio of the PWM signal is determined by the preset values
in the compare register (CR50). Pulses are output from pin TO5. The active level of the PWM
pulse is selected by setting bit 1 of the TMC register to 1. The program transmits a one-second
DTMF tone for each symbol in the 4 x 4 matrix in a loop.
Figure 8-2 is the PWM output timing diagram. Figure 8-3 is the program flowchart.
The PWM output frequency is selected at 9.765 kHz (102.4 µs). The program initializes the first
high-frequency and low-frequency delta values from the initial delta table for a DTMF tone when
a new digit’s DTMF tone is generated.
A new phase value is generated at each interrupt (every 102.4 µs) by adding the delta value to
the previous phase value for high and low frequencies. After that, two twiddle factors based on
new phase values for high and low frequencies are added to load the value to the output
compare register 5 in order to output a new duty cycle.
8-2
DTMF Tone Generation
Figure 8-1. 8-Bit Timer Control Register (TMC5); Settings for PWM Output Operation
7
6
5
4
3
2
1
0
TCE
TMC
0
0
LVS
LVR
TMC
TOE
Bit
Name
Description
0
TOE
TOUT enable = 1
1
TMC
Active level low = 1
2
LVR
x = don’t care
3
LVS
x = don’t care
6
TMC
PWM mode = 1
7
TCE
TM operation enable = 1
If CRn0 is changed during TMn operation, the value changed is not reflected until TMn
overflows. If the CRn0 is set to 00, the Tout line is set to an inactive level. If CRn0 is set to 255,
only one cycle out of 256 cycles is set to low.
Figure 8-1. PWM Output Timing (CR50=N)
Count clock
TM5 Count Value
00
01
02
03
N
N+1
FF
00
01
INTTM5
TO5
Active level
Inactive level
Active level
97YL-0319C (1/98)
8-3
DTMF Tone Generation
Figure 8-1. Flowchart of a DTMF Tone Generation Demo Program
DTMF tone generation
entry
T5 interrupt service
routine
Initialization:
• Set TMC5, CR50,
TCL5 registers.
• Set P10 as an output
port.
• T5 interrupt on.
• Set digit counter to 0.
• New phase for low
frequency = previous
phase + delta for low
frequency.
• New phase for high
frequency = previous
phase + delta for high
frequency.
Output a DTMF tone.
Get the twiddle factor
for the new phase value
for low frequency.
No
1 second over?
Yes
Increment digit number.
No
Get the twiddle factor
for the new phase value
for high frequency.
Add the two twiddle
factors and set to the
CR50 for PWM output.
Digit ≥ 16?
Return
Yes
Reset digit number to 0.
97YL-0314C (12/97)
8-4
DTMF Tone Generation
Assembly Language Program: Example of DTMF Implementation
;/**************************************************************************
;
File name: DTMF.ASM
;
Date: 7/26/97
; BHA 7/26/97
;
; Demonstrates DTMF tone generation. Each DTMF is generated in
; sequence from digit 1.
;
; Dual-tone multifrequency signaling is widely used in
; telephone/communication environments. With the popularity of
; voice mail, electronic mail, and other interactive communication services,
; the need for DTMF signaling is expanding. Two sinusoids are added
; together to implement a DTMF signal.
;
;
Column 1
Column 2
Column 3
Column 4
;
1209 Hz
1336 Hz
1477 Hz
1633 Hz
; Row 1 697 Hz
1
2
3
A
; Row 2 770 Hz
4
5
6
B
; Row 3 852 Hz
7
8
9
C
; Row 4 941 Hz
*
0
#
D
;
;
; The step-size delta is calculated according to the sine wave frequency
; to be generated (delta = N*f/fs).
; This program uses the following data:
;
;
fs = 8 kHz, the sampling frequency
;
Cosine wave table scaled by 256
;
Sine wave output on PWM output
;
N = 256 table length
;
; This module is designed to produce DTMF tones without an external DAC.
; The tones are produced by a form of delta modulation using a PWM
; output port. When the output is run through a low-pass filter, the result is an
; accurate DTMF tone. Crystal frequency is 8.38 MHz.
;
;
Low-pass filter output with PWM signal timing:
;
;
t1
t2
;
t1 + t2 = sample frequency (ex: 8 kHz = 125 µs)
;
if t1 = t2, then low-pass filter output = 0
;
if t1 > t2, then low-pass filter output = positive
;
positive peak: t1 = 125 µs and t2 = 0 µs
;
if t1 < t2, then low-pass filter output = negative
;
negative peak: t1 = 0 µs and t2 = 125 µs
;
;
The delta value may need to be adjusted when the actual circuit is designed,
;
depending on the clock.
;
;
Twiddle factor formula:
;
cosine (360/256 * n) * (0x10000/0x100/4) + 0 x 40
;
cosine (360/256 * n) * 0 x 40 + 0 x 40
;
;***********************************************************************
;*
Revision history
;*
;*
rev. 1.0 8/14/97
;*
. Digit 0 and '*' delta values are swapped.
;*
8-5
DTMF Tone Generation
;*
Old:
;*
25,32,
// ;0 941 + 1336
;*
25,35,
// ;* 941 + 1209
;*
New:
;*
25,35,
// ;0 941 + 1336
;*
25,32,
// ;* 941 + 1209
;**********************************************************************/
PWM_DirPort0
equ PM10.0
PWM_Port0
equ P10.0
PWM_DirPort1
equ PM10.1
PWM_Port1
equ P10.1
PWM_Enable
equ TMC5.7 = 1
PWM_Disable
equ TMC5.7 = 0
PWM_Reg0
equ CR50
_1SEC
equ 5000 ; // 1000000 / 200 = 5000
;======================================================================
;
Bit segment
;======================================================================
bseg
_1SecFlag dbit
;======================================================================
;
saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
Delta1:
ds
1
Delta2:
ds
1
DigitN:
ds
1
DeltaValue:
ds
1
Phase1:
ds
1
Phase2:
ds
1
_i:
ds
1
;======================================================================
;
Even boundary pair
;======================================================================
dseg
saddrp
_200UsecTick:
ds
2
;======================================================================
;
;
Internal High RAM allocation
;
dseg
IHRAM
ds
20h
Stack:
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
org
dw
2Ah
DTMF_ToneGen
;T5 interrupt
$ej
;======================================================================
;
Main
;======================================================================
8-6
DTMF Tone Generation
Main
cseg
public
ResetStart:
mov
call
clr1
EI
mov
clr1
at 80h
ResetStart
OSMS,#00000001b
!PWM_Init
PMK0
DigitN,#0
TMMK5
; // select 5 MHz
; // for DDB BOARD - INTP0 has to be set
; // enable interrupt
; // T5 interrupt on
;
main_loop:
;
i = DigitN *2;
;
Delta1 = DeltaTable[i];
;
Phase1 = Delta1;
;
Delta2 = DeltaTable[i+1];
;
Phase2 = Delta2;
;
Low frequency
mov
a,DigitN
clr1
CY
rol
a,1 ;DigitN *= 2;
mov
b,a
movw
hl,#DeltaTable
mov
a,[hl+b]
mov
Phase1,a
;
High frequency
inc
b
mov
a,[hl+b]
mov
Phase2,a
;
;
// min. output length 50 ms (typically 75 ms)
;
_1SecFlag = 0;
;
_200UsecTick = 0;
;
PWM_Enable;
;
while (TRUE) if ( _1SecFlag) break;
;
PWM_Disable;
;
clr1
_1SecFlag
movw
AX,#0
movw
_200UsecTick,ax
set1
TMC5.7
;
Wait for 1 second over
bf
_1SecFlag,$$
clr1
_1SecFlag
set1
TMC5.7
inc
DigitN
mov
a,DigitN
cmp
a,#16
bc
$main_loop
;
mov
DigitN,#0
br
$main_loop
;/*********************************************************************
;*
A tone generation function
;*
Input: digit #
;*;********************************************************************/
DTMF_ToneGen:
;
Phase1 = Phase1 + Delta1;
;
Phase2 = Phase2 + Delta2;
;
DeltaValue = Cosine [Phase1] + Cosine [Phase2];
8-7
DTMF Tone Generation
;
;
Output delta value to PWM
;
;
PWM_Reg0 = DeltaValue;
; High frequency
mov
a,Phase2
add
a,Delta2
mov
Phase2,a
; Low frequency
mov
a,Phase1
add
a,Delta1
mov
Phase1,a
; Low frequency
mov
b,a
movw
hl,#Cosine
mov
a,[hl+b]
mov
c,a
; High frequency
movw
hl,#Cosine
mov
a,Phase2
mov
b,a
mov
a,[hl+b]
add
a,c
mov
PWM_Reg0,a
ret
;/**********************************************************************
;*
PWM init.
;**********************************************************************/
PWM_Init:
;//
Set PWM output port
;
PWM_DirPort0 = 0;
;
PWM_Port0 = 0;
clr1
PWM_DirPort0
clr1
PWM_Port0
;//
Selects CR50 as compare register
;
PWM_Reg0 = 0b00000000;
mov
PWM_Reg0,#0
;/*=====================================================================
;*
Set clock count register
;*
;
TCL53 to TCL50
;
;
0101
= fx/1 (5.0 MHz)
;
0110
= fx/2 (2.5 MHz)
;
0111
= fx/22 (1.25 MHz)
;
1000
= fx/23 (625 kHz)
;
1001
= fx/24 (313 kHz)
;
1010
= fx/25 (156 kHz)
;
1011
= fx/26 (78.1 kHz)
;
1100
= fx/27 (39.1 kHz)
;
1101
= fx/28 (19.5 kHz)
;
1110
= fx/29 (9.8 kHz)
;
1111
= fx/211 (2.4 kHz)
;
;
If clock count = fx/2, then sample rate would be 9,765 Hz == 9.8 kHz.
;
Delta = 256 * fs/fx (9800 Hz).
;=====================================================================*/
;
TCL5 = 0b00000110;
mov
TCL5,#00000110b ;
;/*=====================================================================
8-8
DTMF Tone Generation
;
8-bit timer mode control register
;
; (MSB)
TCE
= 1, TM0 operation enable
;
TMC
= 1, PWM mode
;
= 0, always
;
= 0, always
;
LVS
= 0, Don't care
;
LVR
= 0, Don't care
;
TMC
= 1, Active High
; (LSB)
TOE
= 1, TOn output enable
;=====================================================================*/
;
TMC5 = 0b11000011;
mov
TMC5,#11000011b ;
ret
;/********************************************************************
;; Hex codes --> Tone pairs Phone Pad
;;
0001
1 697 + 1209
1
;;
0010
2 697 + 1336
2
;;
0011
3 697 + 1477
3
;;
0100
4 770 + 1209
4
;;
0101
5 770 + 1336
5
;;
0110
6 770 + 1477
6
;
0111
7 852 + 1209
7
;
1000
8 852 + 1336
8
;
1001
9 852 + 1477
9
;
1010
A 941 + 1336
0
;
1011
B 941 + 1209
*
;
1100
C 941 + 1477
#
;
1101
D 697 + 1633
A
;
1110
E 770 + 1633
B
;
1111
F 852 + 1633
C
;
0000
0 941 + 1633
D
;********************************************************************
;*
;*
Delta values (with 5-MHz system clock)
;*
;*
Delta = Fs * 256 / Fx
;*
where, Fs = Sample frequency
;*
Fx = Tone frequecy
;*
(Base counter clock = 0.4 µs)
;*
(Sample freq = 1/(0.4 * 256) = 9765.625 Hz)
;*
;*******************************************************************/
DeltaTable:
db 18,32
db 18,35
db 18,39
; // ;1 697 + 1209
; // ;2 697 + 1336
; // ;3 697 + 1477
db 20,32
db 20,35
db 20,39
; // ;4 770 + 1209
; // ;5 770 + 1336
; // ;6 770 + 1477
db 22,32
db 22,35
db 22,39
; //;7 852 + 1209
; //;8 852 + 1336
; //;9 852 + 1477;
db 25,35
db 25,32
db 25,39
; //;0 941 + 1336
; //;* 941 + 1209
; //;# 941 + 1477
db 18,43
db 20,43
; //;A 697 + 1633
; //;B 770 + 1633
8-9
DTMF Tone Generation
db 22,43
db 25,43
;//
; //;C 852 + 1633
; //;D 941 + 1633
Twiddle factors
Cosine:
db 07fh,07fh,07fh,07fh,07fh,07fh,07eh,07eh
db 07eh,07dh,07dh,07dh,07ch,07ch,07bh,07bh
db 07ah,07ah,079h,078h,078h,077h,076h,075h
db 074h,074h,073h,072h,071h,070h,06fh,06eh
db 06dh,06bh,06ah,069h,068h,067h,066h,064h
db 063h,062h,060h,05fh,05eh,05ch,05bh,05ah
db 058h,057h,055h,054h,052h,051h,04fh,04eh
db 04ch,04bh,049h,048h,046h,045h,043h,042h
db
db
db
db
db
db
db
db
040h,03eh,03dh,03bh,03ah,038h,037h,035h
034h,032h,031h,02fh,02eh,02ch,02bh,029h
028h,026h,025h,024h,022h,021h,020h,01eh
01dh,01ch,01ah,019h,018h,017h,016h,015h
013h,012h,011h,010h,00fh,00eh,00dh,00ch
00ch,00bh,00ah,009h,008h,008h,007h,006h
006h,005h,005h,004h,004h,003h,003h,003h
002h,002h,002h,001h,001h,001h,001h,001h
db
db
db
db
db
db
db
db
001h,001h,001h,001h,001h,001h,002h,002h
002h,003h,003h,003h,004h,004h,005h,005h
006h,006h,007h,008h,008h,009h,009h,00bh
00ch,00ch,00dh,00eh,00fh,010h,011h,012h
013h,015h,016h,017h,018h,019h,01ah,01ch
01dh,01eh,020h,021h,022h,024h,025h,026h
028h,029h,02bh,02ch,02eh,02fh,031h,032h
034h,035h,037h,038h,03ah,03bh,03dh,03eh
db
db
db
db
db
db
db
db
040h,042h,043h,045h,046h,048h,049h,04bh
04ch,04eh,04fh,051h,052h,054h,055h,057h
058h,05ah,05bh,05ch,05eh,05fh,060h,062h
063h,064h,066h,067h,068h,069h,06ah,06bh
06dh,06eh,06fh,070h,071h,072h,073h,074h
074h,075h,076h,077h,078h,078h,079h,07ah
07ah,07bh,07bh,07ch,07ch,07dh,07dh,07dh
07eh,07eh,07eh,07fh,07fh,07fh,07fh,07fh
end
8-10
DTMF Tone Generation
C Language Program: Example of DTMF Implementation
#define DEBUG 0
/**************************************************************************
;
File name: DTMF.C
;
Date: 7/26/97
; BHA 7/26/97
;
; Demonstrates DTMF tone generation. Each DTMF is generated in
; sequence from 1.
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
Dual-tone multifrequency signaling is widely used in
telephone/communication environments. With the popularity of
voice mail, electronic mail, and other interactive communication services,
the need for DTMF signaling is expanding. Two sinusoids are added
together to implement a DTMF signal.
Row
Row
Row
Row
1
2
3
4
697
770
852
941
Hz
Hz
Hz
Hz
Column 1
1209 Hz
1
4
7
*
Column 2
1336 Hz
2
5
8
0
Column 3
1477 Hz
3
6
9
#
Column 4
1633 Hz
A
B
C
D
The step-size delta is calculated according to the sine wave frequency
to be generated (delta = N*f/fs).
This program uses the following data:
fs = 8 kHz, the sampling frequency
Cosine-wave table scaled by 256
Sine-wave output on PWM output
N = 256 table length
This module is designed to produce DTMF tones without an external DAC.
The tones are produced by a form of delta modulation, using a PWM
output port. When run through a low-pass filter, the result is an
accurate DTMF tone. Crystal frequency is 8.38 MHz.
Low-pass filter output with PWM signal timing:
t1
t2
;
t1 + t2 = sample frequency (ex: 8 kHz = 125 µs)
;
if t1 == t2, then low-pass filter output = 0
;
if t1 > t2, then low-pass filter output = positive
;
positive peak: t1 = 125 µs and t2 = 0
;
if t1 < t2, then low-pass filter output = negative
;
negative peak: t1 = 0 and t2 = 125 µs
;
;
The delta value may need to be adjusted when the actual circuit is designed,
;
depending on the clock.
;
;
Twiddle factor formula:
;
cosine (360/256 * n) * (0x10000/0x100/4)+ 0 x 40
;
cosine (360/256 * n) * 0 x 40 + 0 x 40
;
***********************************************************************
*
Revision history
*
*
rev. 1.0 8/14/97
*
. Digit 0 and '*' delta values are swapped.
8-11
DTMF Tone Generation
*
*
Old:
*
25,32,
// ;0 941 + 1336
*
25,35,
// ;* 941 + 1209
*
New:
*
25,35,
// ;0 941 + 1336
*
25,32,
// ;* 941 + 1209
**********************************************************************/
#include "define.h"
#pragma interrupt INTTM5 DTMF_ToneGenRB1
#pragma interrupt INTTM1 Timer_8bit_IntervalRB2
/********************************************************************
; Hex codes --> Tone pairs Phone Pad
; 0001 1 697 + 1209
1
; 0010 2 697 + 1336
2
; 0011 3 697 + 1477
3
; 0100 4 770 + 1209
4
; 0101 5 770 + 1336
5
; 0110 6 770 + 1477
6
; 0111 7 852 + 1209
7
; 1000 8 852 + 1336
8
; 1001 9 852 + 1477
9
; 1010 A 941 + 1336
0
; 1011 B 941 + 1209
*
; 1100 C 941 + 1477
#
; 1101 D 697 + 1633
A
; 1110 E 770 + 1633
B
; 1111 F 852 + 1633
C
; 0000 0 941 + 1633
D
********************************************************************
*
*
Delta values (with 5-MHz system clock)
*
*
delta =
Fs * 256 / Fx
*
Where, Fs = Sample frequency
*
Fx = Tone frequency
*
(Base counter clock = 0.4 µs)
*
(Sample freq = 1/(0.4 * 256) = 9765.625 Hz)
*
*******************************************************************/
const unsigned char DeltaTable[] =
{
#ifdef DEBUG
0,0,
32,32,
64,64,
96,96,
128,128,
160,160,
192,192,
226,226,
000,000
#else
18,32,
// ;1 697 + 1209
18,35,
// ;2 697 + 1336
18,39,
// ;3 697 + 1477
8-12
20,32,
20,35,
20,39,
// ;4 770 + 1209
// ;5 770 + 1336
// ;6 770 + 1477
22,32,
// ;7 852 + 1209
DTMF Tone Generation
22,35,
22,39,
// ;8 852 + 1336
// ;9 852 + 1477
25,35,
25,32,
25,39,
// ;0 941 + 1336
// ;* 941 + 1209
// ;# 941 + 1477
18,43,
20,43,
22,43,
25,43
//
//
//
//
;A
;B
;C
;D
697
770
852
941
+
+
+
+
1633
1633
1633
1633
#endif
};
//
Twiddle factors
const unsigned char Cosine[] =
{
0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7e,0x7e,
0x7e,0x7d,0x7d,0x7d,0x7c,0x7c,0x7b,0x7b,
0x7a,0x7a,0x79,0x78,0x78,0x77,0x76,0x75,
0x74,0x74,0x73,0x72,0x71,0x70,0x6f,0x6e,
0x6d,0x6b,0x6a,0x69,0x68,0x67,0x66,0x64,
0x63,0x62,0x60,0x5f,0x5e,0x5c,0x5b,0x5a,
0x58,0x57,0x55,0x54,0x52,0x51,0x4f,0x4e,
0x4c,0x4b,0x49,0x48,0x46,0x45,0x43,0x42,
0x40,0x3e,0x3d,0x3b,0x3a,0x38,0x37,0x35,
0x34,0x32,0x31,0x2f,0x2e,0x2c,0x2b,0x29,
0x28,0x26,0x25,0x24,0x22,0x21,0x20,0x1e,
0x1d,0x1c,0x1a,0x19,0x18,0x17,0x16,0x15,
0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,
0x0c,0x0b,0x0a,0x09,0x08,0x08,0x07,0x06,
0x06,0x05,0x05,0x04,0x04,0x03,0x03,0x03,
0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,
0x02,0x03,0x03,0x03,0x04,0x04,0x05,0x05,
0x06,0x06,0x07,0x08,0x08,0x09,0x09,0x0b,
0x0c,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,
0x13,0x15,0x16,0x17,0x18,0x19,0x1a,0x1c,
0x1d,0x1e,0x20,0x21,0x22,0x24,0x25,0x26,
0x28,0x29,0x2b,0x2c,0x2e,0x2f,0x31,0x32,
0x34,0x35,0x37,0x38,0x3a,0x3b,0x3d,0x3e,
0x40,0x42,0x43,0x45,0x46,0x48,0x49,0x4b,
0x4c,0x4e,0x4f,0x51,0x52,0x54,0x55,0x57,
0x58,0x5a,0x5b,0x5c,0x5e,0x5f,0x60,0x62,
0x63,0x64,0x66,0x67,0x68,0x69,0x6a,0x6b,
0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,
0x74,0x75,0x76,0x77,0x78,0x78,0x79,0x7a,
0x7a,0x7b,0x7b,0x7c,0x7c,0x7d,0x7d,0x7d,
0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f
};
#define
#define
#define
#define
#define
#define
#define
PWM_DirPort0
PWM_Port0
PWM_DirPort1
PWM_Port1
PWM_Enable
PWM_Disable
PWM_Reg0
PM10.0
P10.0
PM10.1
P10.1
TMC5.7 = 1
TMC5.7 = 0
CR50
8-13
DTMF Tone Generation
#define _1SEC
5000
// 1000000 / 200 = 5000
bit
_1SecFlag;
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
char
Delta1;
Delta2;
DigitN;
DeltaValue;
Phase1;
Phase2;
i;
unsigned int _200UsecTick;
void PWM_Init ();
void main (void)
{
OSMS = 0b00000001;
// select 5 MHz
PWM_Init ();
PMK0 = 0;
// for DDB BOARD - INTP0 has to be set
EI ();
// enable interrupt
DigitN = 0;
TMMK5 = 0;
// T5 interrupt on
TMMK1 = 0;
// T1 interrupt on
while (TRUE)
{
i = DigitN * 2;
Delta1 = DeltaTable[i];
Phase1 = Delta1;
Delta2 = DeltaTable[i+1];
Phase2 = Delta2;
// Min. output length 50 ms (typically 75 ms)
_1SecFlag = 0;
_200UsecTick = 0;
PWM_Enable;
while (TRUE)
{
if ( _1SecFlag) break;
}
PWM_Disable;
DigitN += 1;
if (DigitN >= 16 ) DigitN = 0;
}
}
/*********************************************************************
*
A tone generation function
*
Input: digit #
*;********************************************************************/
void DTMF_ToneGen (void)
{
//
// Output initial value
//
#ifndef DEBUG
Phase1 = Phase1 + Delta1;
8-14
DTMF Tone Generation
Phase2 = Phase2 + Delta2;
DeltaValue = Cosine [Phase1] + Cosine [Phase2];
//
//
Output delta value to PWM
//
PWM_Reg0 = DeltaValue;
#else
DeltaValue = Cosine [Phase1];
//
//
Output delta value to PWM
//
PWM_Reg0 = DeltaValue;
#endif
}
/**********************************************************************
*
PWM init.
**********************************************************************/
void PWM_Init ()
{
//
Set PWM output port
PWM_DirPort0 = 0;
PWM_Port0 = 0;
//
Selects CR50 as compare register
PWM_Reg0 = 0b00000000;
/*=====================================================================
*
Set clock count register
*
;
TCL53 to TCL50
;
;
0101
= fx/1 (5.0 MHz)
;
0110
= fx/2 (2.5 MHz)
;
0111
= fx/22 (1.25 MHz)
;
1000
= fx/23 (625 kHz)
;
1001
= fx/24 (313 kHz)
;
1010
= fx/25 (156 kHz)
;
1011
= fx/26 (78.1 kHz)
;
1100
= fx/27 (39.1 kHz)
;
1101
= fx/28 (19.5 kHz)
;
1110
= fx/29 (9.8 kHz)
;
1111
= fx/211(2.4 kHz)
;
;
If clock count = fx/2, then sample rate would be 9,765 Hz == 9.8 kHz.
;
Delta = 256 * fs/fx (9800 Hz).
;=====================================================================*/
TCL5 = 0b00000110;
/*=====================================================================
;
8-bit timer mode control register
;
; (MSB)
TCE
= 1, TM0 operation enable
;
TMC
= 1, PWM mode
;
= 0, always
;
= 0, always
;
LVS
= 0, Don't care
;
LVR
= 0, Don't care
;
TMC
= 1, Active high
; (LSB)
TOE
= 1, TOn output enable
;=====================================================================*/
TMC5 = 0b11000011;
8-15
DTMF Tone Generation
#ifdef DEBUG
//
Set 8-bit timer interval for 409.6 µs
TCL1 = 0x07;// SET 800 ns
TMC1 = 0x03;// enable
CR10 = 250;// 200 µs
#endif
}
void Timer_8bit_Interval ()
{
// test point
#ifdef DEBUG
PM2 = 0; // output direction
P2.0 = 1;
P2.0 = 0;
#endif
_200UsecTick++;
if (_200UsecTick > _1SEC)
{
_200UsecTick = 0;
#ifndef DEBUG
_1SecFlag = 1;
#endif
}
}
_
8-16
I2C Bus Interface
9
Applicable Devices
•
•
•
•
•
•
•
•
•
µPD7801xF (Y version)
µPD7801xH (Y version)
µPD7805x (Y version)
µPD7805xF (Y version)
µPD78005x (Y version)
µPD7807x (Y version)
µPD78070A (Y version)
µPD7806x (Y version)
µPD78030x (Y version)
Description
The I2C™ bus uses a two-wire interface consisting of a serial data line (SDA) and a serial clock
line (SCL) to exchange information between devices connected to the bus. Each device on the
bus has a unique address and can operate as a transmitter or a receiver depending on its
particular function. Devices are further characterized as master or slave. A master is defined as
a device that initiates, controls, and terminates a transfer and generates all framing and clock
signals. A slave is defined as any device addressed by a master.
Multiple masters are allowed by I2C bus specifications because a bus arbitration and clock
synchronization scheme is defined so that messages are not corrupted when more than one
device attempts to take master control.
Both the SDA and SCL lines are bidirectional and are pulled up to the positive logic supply rail
via resistors. Both lines are high for the bus idle state. In the output mode, the SDA and SCL
lines are open-drain or open-collector. Data is exchanged 8 bits at a time and can be transferred
at rates up to 100 kbps (standard mode) or 400 kbps (fast mode).
Data transfers on the I 2C bus are controlled by two bus states generated by the bus master
START and STOP bit conditions. A START condition is defined as a high-to-low transition on the
SDA line while the SCL line is high. A STOP condition is defined as a low-to-high transition on
the SDA line while the SCL line is high. Refer to Figure 9-1.
Data must always be valid on SDA during SCL high, and that is only allowed to be changed
during the SCL low period. Refer to Figure 9-2. Thus, one bit of data is transmitted for each SCL
period.
I2 C is a trademark of NV Philips.
9-1
I2C Bus Interface
Figure 9-1. START and STOP Conditions
SDA
SCL
Start condition
Stop condition
97YL-0315C (12/97)
Figure 9-2. Valid Bit Data on the I 2C Bus
SDA
SCL
Data line stable
Data Valid
Change of
data allowed
97YL-0316C (12/97)
Following the START condition, the first 8-bit byte sent in a bus message is a 7-bit slave
address field, along with a data direction or R/W bit. (This discussion is limited to the 7-bit
addressing mode.) The data direction bit (LSB) controls whether or not the master will transmit
(0 = write) or receive (1 = read) data from the addressed slave. For every byte exchanged, the
MSB is always transmitted first. All bus byte transactions are followed by an acknowledge bit
(refer to Figure 9-3). The acknowledge bit is a low-level signal placed on the SDA line by the
receiving device (master or slave) during the master-transmitted acknowledge clock pulse (ninth
high SCL clock pulse).
Figure 9-3. I 2C Bus Acknowledge, Non-Acknowledge
Data output
by transmitter
Non-acknowledge
(High)
MSB
Data output
by receiver
SCL from
Master
S
1
2
8
9
Acknowledge
(Low)
Start condition
Clock pulse for
acknowledgment
97YL-0317C (12/97)
9-2
I2C Bus Interface
If the receiver is unable to receive data (busy slave receiver) or must signal the end-of-data
condition (master receiver), a non-acknowledge is sent (SDA high during the ninth high SCL
clock pulse time as shown in Figure 9-3). Following the START and slave address transmission,
data is exchanged between the master and receiver as required. Upon exchange of the final
byte and its acknowledge, the master issues the STOP condition to end bus usage. See Figure
9-4 for a sample I2C bus data transfer.
Figure 9-4. Sample I 2C Bus Message
SCL
1-7
8
Address
R/W
1-7
9
8
9
1-7
8
9
SDA
Start condition
ACK
Data
ACK
Data
ACK
Stop
97YL-0318C (1/98)
EEPROM Interface
The preceding general overview of I2C bus operation provides the foundation necessary to
proceed with a serial EEPROM interface in the I2C 7-bit addressing mode.
Control Registers for I2C Bus Mode Operation
•
Serial operating mode register 0 (CSIM0)
•
Serial bus interface control register (SBIC)
•
Interrupt timing specification register (SINT)
Example Program for the I2C Bus EEPROM Specification
This program provides an overview of the I2C bus interface and the two-wire 24Cxxx EEPROM
family (I2C slave). See the flowchart in Figure 9-5.
Device
Bytes
24C01A
128
Max. Devices
Page Write (Bytes)
8
8
Device Address (MSB to LSB)
1 0 1 0 a2 a1 a0 R/W
Example Mode Operation for Output
•
Write "ABCDEFGH” to the EEPROM.
•
Read the same data back.
•
Compare for a match.
9-3
I2C Bus Interface
Figure 9-5. Flowchart for I 2C Interface
I2C bus serial I/O
entry
Write data string
ABCDEFGH to
EEPROM.
Read data from
EEPROM.
Initialization:
• Set CLK SDA port to
output direction.
• Set serial operating
mode register 0
(CSIM0).
• Set Interrupt timing
specification register
(SINT).
• Set clock rate (TCL3).
Set START condition
(CMDT = 1).
Set START condition
(CMDT = 1).
Send device address
(10100000b).
Send device address
(10100000b).
Nak
Ack or Nak?
• Set slave address.
• Set SDA high.
Nak
Ack or Nak?
Ack
Ack
Send
a page address.
Send
a page address.
Write data string
ABCDEFGH to
EEPROM.
Err
Nak
Ack or Nak?
Nak
Ack or Nak?
Ack
Ack
Read data string
ABCDEFGH from
EEPROM.
Compare
receive data string
with
output string.
Err
• Set START condition.
• Send a device
address with read
bit (0b10100001).
Send a byte.
Nak
Ack or Nak?
Nak
Ack
Yes
Ack
Increment byte pointer.
Input string =
Output string?
No
Ack or Nak?
Read a byte from
EEPROM.
No
End of string?
Increment byte pointer.
Yes
Error
Send a STOP condition.
Error Flag = 0
Yes
Error Flag = 1
More?
No
Send a STOP condition.
Error Flag = 0
Return
Error Flag = 1
Return
EEPROM = 24Cxxx family.
97YL-0306C (2/98)
9-4
I2C Bus Interface
Assembly Language Program: Example of I2C Bus Interface and 24Cxxx EEPROM
;****************************************************************************
;
File name: I2CBUS.ASM
;
Date: 9/20/97
;****************************************************************************
;
Description:
; The I2C bus uses a two-wire interface consisting of a serial data line (SDA)
; and a serial clock line (SCL) to exchange information between devices connected
; to the bus. Each device on the bus has a unique address and can
; operate as a transmitter or a receiver depending on its particular function.
; Devices are further characterized as master or slave.
; A master is defined as a device that initiates, controls, generates all framing and clock
; signals, and terminates a transfer. A slave is defined as any
; device addressed by a master.
;
; Multiple masters are allowed by I2C bus specifications because a bus arbitration
; and clock synchronization scheme is defined so that messages are not corrupted when
; more than one device attempts to take master control.
;
; Both the SDA and SCL lines are bidirectional and are pulled up to the positive
; logic supply rail.
;
; Data transfers on the I2 C bus are controlled by two bus states generated by
; the bus master START and STOP bit conditions. A START condition is defined
; as a high-to-low level transition on the SDA line while the SCL line is high. A STOP condition
; is defined as a low-to transition on the SDA line while the SCL line is high.
; Data must always be valid on SDA during SCL high, and that is only allowed
; to be changed during the SCL low period. Thus, one bit of data is transmitted for
; each SCL period.
;
; Following the START condition, the first 8-bit byte sent in a bus message is
; a 7-bit slave address field ,along with a data direction or R/W bit. (This
; discussion is limited to the 7-bit addressing mode.) The data direction bit (LSB)
; controls whether or not the master will transmit (0 = write) or receive (1 = read) data
; from the addressed slave. For every 8-bit byte exchanged, the MSB is always
; transmitted first. All 8-bit byte bus transactions are followed by an acknowledge
; bit. The acknowledge bit is a low-level signal placed on the SDA line by the
; receiving device (master or slave) during the master-transmitted acknowledgment
; pulse (ninth high SCL clock pulse).
;
; If the receiver is unable to receive data or must signal the end-of-data condition
; (master receiver), a non-acknowledge is sent. Upon exchange of the final byte
; and its acknowlege, the master issues the STOP condition to end bus usage.
;======================================================================
;
I2C bus EEPROM specification.
;
;
This example program provides an overview of the I2C bus interface
;
and the two-wire 24Cxxx EEPROM family (I2C slave).
;
;
# of
Max. # of
Page Write
Device Address
;
Device
Bytes
devices
(# of bytes)
(MSB to LSB)
;;
24C01A
128
8
8
1 0 1 0 a2 a1 a0 R/W
;
;======================================================================
;
Example mode operation for output
;
;
Write "ABCDEFGH' to the EEPROM.
;
Read the same data back.
;
Compare for a match.
;
;======================================================================
;
for only DDB-K0070A
9-5
I2C Bus Interface
;
$set (K0)
$set (DDB)
;======================================================================
;
DebugFlag set 1
;
CR
equ
13
;Carriage return
LF
equ
10
;Line feed
;======================================================================
;
Equates
;======================================================================
SDAPort
equ
P2.5
;Latch output high for SDA0
SDADirBit
equ
PM2.5
;Serial data direction register
SCLKPort
equ
P2.7
;Latch output high for SCL
SCLKDirBit
equ
PM2.7
;Serial clock direction register
;
CLCx
EQU
SINT.3
;
;
Slave address for 24C01A (8 bytes/page)
SlaveAddr
;
;
;
PageAddr
equ
10100000b
;a2/a1/a0 = 0
24C01A page address
equ
00000000b
;page address in the EEPROM
;======================================================================
;
Wait for IRQ and check acknowledge signal
;======================================================================
WaitIntAndAck
macro
j1
bf
CSIIF0,$$
clr1
CSIIF0
bf
ACKD,$j1 ;No Ack
endm
;======================================================================
;
Wait for START condition and set clock low
;======================================================================
SetStartCondition macro
;
Set START Condition
set1
CMDT
; Start ON
bf
CMDD,$$
; Wait for START condition detected
endm
;======================================================================
;
Wait for STOP condition and set clock low
;======================================================================
SetStopCondition macro
bf
CLD,$$
;busy
;
Set STOP condition
set1
RELT
;
Set clock line to high impedence
set1
CLCx
bf
CLD,$$
;Low (busy)?
endm
;======================================================================
;
Send device address
;======================================================================
SendDeviceAddress macro
;
Set START Condition
mov
a,SVA0
mov
SIO0,a
;Send a device address
9-6
I2C Bus Interface
endm
;======================================================================
;
saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
SVA0:
DS
1
;======================================================================
;
Even boundary pair
;======================================================================
dseg
saddrp
;======================================================================
;
Bit segment
;======================================================================
bseg
;======================================================================
;
Internal High RAM allocation
;
dseg
IHRAM
ds
20h
Stack:
InputBuffer:
ds
10
;10 bytes
$ej
;======================================================================
;
Reset Vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
;
;
org
dw
20h
I2CInter ;I2C bus interrupt
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
AT
80h
ResetStart:
;
;
;
;
Oscillation mode select register
. Does not use divider circuit
$if (K0)
mov
$endif
;
;
;
OSMS,#00000001b
Set stack pointer (IHMEM + 20H)
movw
SP,#Stack
;Stack ptr
;
;
;
Init. I2 C bus mode/control register
call
;
;
;
!InitI2C
Set receive buffer ptr
sel
mov
RB1
b,#0
;offset to 0
9-7
I2C Bus Interface
sel
;
;
;
$if (DDB)
Enable INTP0 for DDB-K0070A
clr1
$endif
main_loop:
;
;
;
!OutputToI2C
$Error
Read data from I2 C bus I/F
call
bnc
;
;
;
PMK0
Write to I2 C bus I/F
call
bnc
;
;
;
RB0
!InputFromI2C
$Error
Check data valid
movw
movw
mov
hl,#TestString
de,#InputBuffer
c,#TestStringSize
mov
cmp
bz
Error - Not
nop
nop
a,[de]
a,[hl]
$matched
Matched
incw
incw
dbnz
hl
de
c,$cmpr
br
main_loop
cmpr:
;
matched:
;
;
;
;
Error:
Error condition detected
nop
br
main_loop
;======================================================================
;
Module name: OutputToI2C
;
;
DESCRIPTION:
;
This module is to write a page data (8 bytes) to the
;
24Cxxx (EEPROM) through I2C bus I/F.
;
;
OPERATION:
;
;
.Set IRQ on 9th clock (falling edge).
;
.Set START condition.
;
.Write a device address and wait for the IRQ.
;
.Check ACK signal.
;
.Write EEPROM address to be written.
;
.Load a byte from the test string.
;
.Write data and check ACK signal.
;
.After last byte is transferred, set STOP condition.
;
;======================================================================
9-8
I2C Bus Interface
;
Input:
;
None
;
Return:
;
CY = 1 for normal return
;
CY = 0 for Error return
;======================================================================
OutputToI2C:
;
Check clock level
bf
CLD,$$
;Low - busy
SetStartCondition
SendDeviceAddress
WaitIntAndAckTxError
;
Send page address in the EEPROM
mov
SIO0,#PageAddr
WaitIntAndAckTxError
;
;
;
Output data
movw
mov
hl,#TestString
c,#TestStringSize
Outloop:
mov
a,[hl]
mov
SIO0,a
WaitIntAndAckTxError
incw
hl
dbnz
c,$Outloop
;Send data
;
SetStopCondition
;
set1
ret
;
;
;
TxError:
CY
;Return with CY = 1
Error
SetStopCondition
;
clr1
ret
CY
;Return with CY = 0
db
'ABCDEFGH',CR,LF
equ
TestStringEnd - TestString
TestString:
TestStringEnd:
TestStringSize
;======================================================================
;
Module name: InputFromI2 C
;
;
;
;
;
;
;
;
;
;
;
;
DESCRIPTION:
This module is to read a page data (8 bytes) from the
24Cxxx (EEPROM) through I2 C bus I/F.
OPERATION:
.Set IRQ on 9th clock.
.Write slave device address to be written.
.Write EEPROM address to be written.
.Send ACK signal if OK.
9-9
I2C Bus Interface
;
.Set IRQ on 8th clock.
;
.Send START condition..
;
.Read data and check ACK signal
;
.After last byte is read, set STOP condition.
;
;======================================================================
;
Input:
;
None
;
Return:
;
CY = 1 for normal return
;
CY = 0 for error return
;======================================================================
2
InputFromI C:
SetStartCondition
SendDeviceAddress
WaitIntAndAckTxError
;
;
;
Send page address in the EEPROM
mov
SIO0,#PageAddr
WaitIntAndAckTxError
;
SetStartCondition
;
;
;
;
;
;
;
Send device address with read signal
mov
a,SVA0
add
a,#1
mov
SIO0,a
Wait for IRQ and Check ACK
WaitIntAndAckTxError
Check receive status
When LSB of device address = 1
Read data
movw
mov
Inloop:
;
;
;
;
;Set read signal
;Send a device address
hl,#InputBuffer
c,#TestStringSize
Cancel wait and start reception
mov
SIO0,#0ffh
WaitIntAndAckRxError
;Start receiving data
Read data
mov
mov
incw
dbnz
a,SIO0
[hl],a
hl
c,$Inloop
;Read data
SetStopCondition
;
set1
ret
;
;
;
RxError:
;
CY
;Return with CY = 1
Error
SetStopCondition
;
clr1
9-10
CY
;Return with CY = 0
I2C Bus Interface
ret
;======================================================================
2
;
Module name: InitI C
;
;
DESCRIPTION:
;
This module is to initialize the I2 C bus I/F control and mode
;
registers.
;
;
OPERATION:
;
.Set SCL to output direction and SDA to output direction.
;
.Set transfer clock.
;
.Enable operation.
;
.Enable IRQ on STOP condition.
;
.Set slave device address.
;
.Enable IRQ on 9th clock falling edge.
;
;======================================================================
;
Input:
none
;
Output: none
;
;======================================================================
2
InitI C:
o
;
Set SCL to output direction
;
set1
SDAPort
;Latch output high for SDA
set1
SCLKPort
;Latch output high for SCLK
;
clr1
SCLKDirBit
;Serial cloock set to output direction
clr1
SDADirBit
;Serial data to output direction
;****************************************************************
; Serial operating mode register 0 (CSIM0)
;*
*
;*
1 0 0 1 1 1 1 1
*
;*
^ ^ ^ ^ ^ ^ ^ ^
*
;*
| | | | | | |_|__ 11 - Clock specified with bits 0 to 3 of TCL3*
;*
| | | | | |
*
;*
| | | |_|_|______ 111 I2C bus mode (P25 = SDA0) *
;*
| | |____________ 0 IRQ with each serial transfer *
;*
| |______________ 0 Read only - slave addr. not equal to serial I/O shift register data*
;*
|________________ 1 Enable operation
*
;****************************************************************/
mov
CSIM0,#10011111b
;****************************************************************
;*
Interrupt timing specification register (SINT) *
;*
*
;*
0 0 0 0 1 0 1 1
*
;*
^ ^ ^ ^ ^ ^ ^ ^
*
;*
| | | | | | |_|__ 11 9-clock wait
*
;*
| | | | | |______ 0 Indicates that the wait state has *
;*
| | | | | released
*
;*
| | | | |________ 1 Other than serial transfer SCL *
;*
| | | |
pin, output is set to high impedance *
;*
| | | |__________ 0 Bits 0 to 7
*
;*
| | |
*
;*
| | |____________ 0 CSIIF0 is set to 1 after end of *
;*
| |
serial transfer *
;*
| |______________ 0 SCL line level low (read only) *
;*
|
*
;*
|________________ 0
*
;*
*
9-11
I2C Bus Interface
;****************************************************************/
mov
SINT,#00001011b
;
;
Clock selection = 1000b (39.1 kHz)
;
mov
TCL3,#11001000b
;
;
Serial bus interface control register (SBIC)
;
set1
RELT;SO Latch is set to 1 after setting automatically clear to 0
;
;
Slave address for 24C1A
;
1010 A2 A1 A0 R/W = 10100000b
;
mov
SVA0,#SlaveAddr
ret
;***********************************************************************
end
_
9-12
I2C Bus Interface
C Language Program: Example of I2C Bus Interface and 24Cxxx EEPROM
/*;**************************************************************************
;
File name: I2CBUS
;
Date: 9/20/97
;****************************************************************************
;
Description:
; The I2C bus uses a two-wire interface consisting of a serial data line (SDA)
; and a serial clock line (SCL) to exchange information between devices connected
; to the bus. Each device on the bus has a unique address and can
; operate as a transmitter or a receiver depending on its particular function.
; Devices are further characterized as master or slave.
; A master is defined as a device that initiates, controls, and terminates a transfer and generates
; all framing and clock signals. A slave is defined as any device addressed by a master.
;
2
; Multiple masters are allowed by I C bus specifications because a bus arbitration
; and clock synchronization scheme is defined so that messages are not corrupted when
; more than one device attempts to take master control.
;
; Both the SDA and SCL lines are bidirectional and are pulled up to the positive
; logic supply rail.
;
; Data transfers on the I2 C bus are controlled by two bus states generated by
; the bus master START and STOP bit conditions. A START condition is defined
; as a high-to-low transition on the SDA line while the SCL line is high. A STOP condition
; is defined as a low-to-high transition on the SDA line while the SCL line is high.
; Data must always be valid on SDA during SCL high, and that is only allowed
; to be changed during the SCL low period. Thus, one bit of data is transmitted for
; each SCL period.
;
; Following the START condition, the first 8-bit byte sent in a bus message is
; a 7-bit slave address field, along with a data direction or R/W bit. (This
; discussion is limited to the 7-bit addressing mode.) The data direction bit (LSB)
; controls whether or not the master will transmit (0 = write) or receive (1 = read) data
; from the addressed slave. For every 8-bit byte exchanged, the MSB is always
; transmitted first. All 8-bit byte bus transactions are followed by an acknowledge
; bit. The acknowledge bit is a low-level signal placed on the SDA line by the
; receiving device (master or slave) during the master-transmitted acknowledgment
; pulse (ninth high SCL clock pulse).
;
; If the receiver is unable to receive data or must signal the end-of-data condition
; (master receiver), a non-acknowledge is sent. Upon exchange of the final byte
; and its acknowlege, the master issues the STOP condition to end bus usage.
;======================================================================
;
I2 C bus EEPROM specification.
;
;
This example program provides an overview of the I2C bus interface
and the two-wire 24Cxxx EEPROM family (I2 C slave).
;
;
;
# of
Max. # of
Page Write
Device Address
;
Device
Bytes
devices
(# of bytes)
(MSB to LSB)
;;
24C01A
128
8
8
1 0 1 0 a2 a1 a0 R/W
;
;======================================================================
;
Example mode operation for output
;
;
Write "ABCDEFGH' to the EEPROM.
;
Read the same data back.
;
Compare for a match.
;
;======================================================================*/
9-13
I2C Bus Interface
#include "define.h"
/*;======================================================================
;
Equates
;======================================================================*/
#define SDAPort
P2.5
// Latch output high for SDA0
#define SDADirBit
PM2.5
// Serial data direction register
#define SCLKPort
P2.7
// Latch output high for SCL
#define SCLKDirBit
PM2.7
// Serial clock direction register
//
#define CLCx
SINT.3
//;
//;
Slave address for 24C01A (8 bytes/page)
//;
#define SlaveAddr
0b10100000
;//a2/a1/a0 = 0
//;
//;
24C01A page address
//;
#define PageAddr
0b00000000
;//page address in the EEPROM
/*;==================================================================
;
Macro definitions
;==================================================================*/
#define
#define
#define
#define
#define
TxWaitIntAndAck while (!CSIIF0); CSIIF0 = 0; if (!ACKD) goto TxError;
RxWaitIntAndAck while (!CSIIF0); CSIIF0 = 0; if (!ACKD) goto RxError;
SetStartCondition CMDT = 1; while (!CMDD);
SetStopCondition while (!CLD); RELT = 1; CLCx = 1; while (!CLD);
SendDeviceAddress SIO0 = SVA0;
__sreg unsigned char SVA0;
#define InputBufferSize 10
__sreg unsigned char InputBuffer[InputBufferSize];
__sreg unsigned char i;
__sreg unsigned char c;
bit ErrorFlag;
unsigned char const TestString[] = "ABCDEFGH";
void InputFromI2C ();
void InitI2C ();
void OutputToI2C ();
/*;======================================================================
;
Main
;======================================================================*/
void main ()
{
//;
//;
Oscillation mode select register
//;
. Does not use divider circuit
//;
#ifdef K0
OSMS=0b00000001;
#endif
//;
//;
Init. I2 C bus mode/control register
//;
InitI2C ();
//;
9-14
I2C Bus Interface
//;
//;
Set receive buffer ptr
while (TRUE)
{
ErrorFlag = 0;
//;
2
//;
Write to I C bus I/F
//;
OutputToI2C ();
if (ErrorFlag) go to ErrorStop;
//;
2
//;
Read data from I C bus I/F
//;
InputFromI2C ();
if (ErrorFlag) goto ErrorStop;
//;
//;
Check data valid
//;
for (i =0 ;i < InputBufferSize; i++)
{
if (TestString[i] != InputBuffer[i]) goto ErrorStop;
}
}
ErrorStop:
while (TRUE);
}
/*;======================================================================
;
Module name: OutputToI2 C
;
;
DESCRIPTION:
;
This module is to write a page data (8 bytes) to the
;
24Cxxx (EEPROM) through I2 C bus I/F.
;
;
OPERATION:
;
;
.Set IRQ on 9th clock (falling edge).
;
.Set START condition.
;
.Write a device address and wait for the IRQ.
;
.Check ACK signal.
;
.Write EEPROM address to be written.
;
.Load a byte from the test string.
;
.Write data and check ACK signal.
;
.After last byte is transferred, set STOP condition.
;
;======================================================================
;
Input:
;
None
;
Return:
;
CY = 1 for normal return
;
CY = 0 for error return
;======================================================================*/
void OutputToI2C ()
{
//;
Check clock level
while (!CLD);//
;Low - busy
SetStartCondition;
SendDeviceAddress;
TxWaitIntAndAck;
9-15
I2C Bus Interface
//;
Send page sddress in the EEPROM
SIO0 = PageAddr;
TxWaitIntAndAck;
//;
//;
//;
Output Data
for (i= 0 ;sizeof TestString;i++)
{
SIO0 = TestString[i];
TxWaitIntAndAck;
}
//
SetStopCondition;
//
ErrorFlag = 0;
return;
//;
//;
//;
TxError:
Error
SetStopCondition
//;
ErrorFlag = 1;
}
/*;======================================================================
;
Module name: InputFromI2C
;
;
DESCRIPTION:
;
This module is to read a page data (8 bytes) from the
;
24Cxxx (EEPROM) through I2C bus I/F.
;
;
OPERATION:
;
;
.Set IRQ on 9th clock.
;
.Write slave device address to be written.
;
.Write EEPROM address to be written.
;
.Send ACK signal if OK.
;
.Set IRQ on 8th clock.
;
.Send START condition.
;
.Read data and check ACK signal.
;
.After last byte is read, set STOP condition.
;
;======================================================================
;
Input:
;
None
;
Return:
;
CY = 1 for normal return
;
CY = 0 for error return
;======================================================================*/
void InputFromI2C ()
{
SetStartCondition;
SendDeviceAddress;
RxWaitIntAndAck;
//;
//;
//;
Send page address in the EEPROM
SIO0 = PageAddr;
RxWaitIntAndAck;
//;
SetStartCondition;
//
9-16
I2C Bus Interface
//;
//
Send device address with read signal
SIO0 = SVA0+1;
RxWaitIntAndAck;
//
//
//
Read data string
for (i=0;i<sizeof InputBuffer;i++)
{
SIO0 = 0xff;
RxWaitIntAndAck;
InputBuffer[i] = SIO0;
}
//
SetStopCondition;
ErrorFlag = 0;
return;
//
//
//
RxError:
Error
ErrorFlag = 1;
}
/*;======================================================================
;
Module name: InitI2 C
;
;
DESCRIPTION:
;
.This module is to initialize the I2C bus I/F control and mode
;
registers.
;
;
OPERATION:
;
.Set SCL to output direction and SDA to output direction.
;
.Set transfer clock.
;
.Enable operation.
;
.Enable IRQ on STOP condition.
;
.Set slave device address
;
.Enable IRQ on 9th clock falling edge.
;======================================================================
;
Input:
none
;
Output: none
;=====================================================================*/
void InitI2C ()
{
//;
//;
Set SCL to output direction
//;
SDAPort = 1;// ;Latch output high for SDA
SCLKPort = 1;// ;Latch output high for SCLK
SCLKDirBit = 0; // ;Serial clock set to output direction
SDADirBit = 0;// ;Serial data to output direction
/*;****************************************************************
; Serial operating mode register 0 (CSIM0)
;*
*
;*
1 0 0 1 1 1 1 1
*
;*
^ ^ ^ ^ ^ ^ ^ ^
*
;*
| | | | | | |_|__ 11 - Clock specified with bits 0 to 3 of TCL3*
;*
| | | | | |
*
;*
| | | |_|_|______ 111 I2C bus mode (P25 = SDA0) *
;*
| | |____________ 0 IRQ with each serial transfer *
;*
| |______________ 0 Read only - slave addr. not equal to serial I/O shift register data.
;*
|________________ 1 Enable operation
*
;****************************************************************/
CSIM0 = 0b10011111;
9-17
I2C Bus Interface
/*;****************************************************************
;*
Interrupt timing specification register (SINT) *
;*
*
;*
0 0 0 0 1 0 1 1
*
;*
^ ^ ^ ^ ^ ^ ^ ^
*
;*
| | | | | | |_|__ 11 9-clock wait
*
;*
| | | | | |______ 0 Indicates that the wait state has *
;*
| | | | | released
*
;*
| | | | |________ 1 Other than serial transfer SCL *
;*
| | | |
pin, output is set to high impedance *
;*
| | | |__________ 0 Bits 0 to 7
*
;*
| | |
*
;*
| | |____________ 0 CSIIF0 is set to 1 after end of *
;*
| |
serial transfer. *
;*
| |______________ 0 SCL line level low (read only) *
;*
|
*
;*
|________________ 0
*
;*
*
;****************************************************************/
SINT = 0b00001011;
//;
//;
Clock selection = 1000b (39.1 kHz)
//;
TCL3 = 0b1001000;
//;
//;
Serial bus interface control register (SBIC)
//;
(SBIC)
//;
RELT = 1; //;SO Latch is set to 1 after setting automatically clear to 0
//;
//;
Slave address for 24C01A
//;
1010 A2 A1 A0 R/W = 10100000b
//;
SVA0 = SlaveAddr;
}
9-18
LCD Controller/Driver
10
Applicable Devices
•
•
µPD78030x
µPD7806x
Description
Liquid crystal displays (LCDs) are widely used in handheld embedded applications as reliable,
low-power, compact readouts. Many of these applications require drivers/controllers on-board.
The example program is an LCD driver using 4-time-division and 1/2 bias. The program
displays the time of day: HOURS:MINUTES:SECONDS. Default time is 12:00:00. Every 15.6
milliseconds, the program checks whether a second has passed and, if so, updates the display.
LCD Controller/Driver Features
1. Automatic output of segment signals and common signals is possible by automatic reading
of the display data memory.
2. Any of five display modes can be selected:
–
–
–
–
–
Static
3/4 duty (1/2 bias)
1/3 duty (1/2 bias)
1/3 duty (1/3 bias)
1/4 duty (1/3 bias)
3. Any of four frame frequencies can be selected in each display mode.
4. There are a maximum of 40-segment signal outputs (S0 to S39 = 160 bits) and four common
signal outputs (COM0 to COM3).
5. Sixteen of the segment signal outputs can be switched to input/output ports in units of two
(P80/S39 to P87/S32 and P90/S31 to P97/S24).
6. In mask ROM versions, split resistors for LCD driver voltage generation can be incorporated
by mask option.
7. Operation on the subsystem clock is also possible.
Maximum Number of Displayable Pixels in Each Display Mode
Bias Method
Time Division
COM Signals
Max. Pixels
–
Static
COM0
40 (40 segments x 1 common)
1/2
2
COM0 – COM1
80 (40 segments x 2 commons)
3
COM0 – COM2
120 (40 segments x 3 commons)
COM0 – COM3
160 (40 segments x 4 commons)
1/3
3
4
10-1
LCD Controller/Driver
LCD Controller/Driver Configuration
Display outputs
Dedicated segment signals: 24
Segment signal, input/output port dual function: 16
Common signals 4 (COM0 to COM3)
Control registers
LCD display mode register (LCDM)
LCD display control register (LCDC)
LCD Display Data Memory
The LCD display data memory is mapped onto addresses FA58h to FA7Fh. The data stored in
the memory can be displayed on an LCD panel by the LCD controller/driver.
Figure 10-1 shows the relationship between the LCD display data memory contents and the
segment/common outputs. Any area not used for display can be used as normal RAM.
Figure 10-1. Display Data Memory
Address
7
6
5
4
3
2
1
0
FA7FH
S0
FA7EH
S1
FA7DH
S2
FA7CH
S3
FA5AH
S37/P82
FA59H
S38/P81
FA58H
S39/P80
COM3
COM2
COM1
COM0
97YL-0322C (12/97)
LCD Display Mode Register (LCDM)
1. This LCDM register (Figure 10-2) sets the display mode, supply voltage, LCD clock frequency, and display on or off.
2. The LCD clock is supplied from the clock timer. When LCD display is performed, set TMC2
bit 1 of the watch timer mode control register to 1.
3. To reduce power consumption, clear LCDM3 to 0 when LCD display is not performed. Before
manipulating LCDM3, be sure to turn off the LCD display.
10-2
LCD Controller/Driver
Figure 10-2. LCD Display Mode Register (LCDM)
7
6
5
4
3
2
1
0
LCDON
LCDM6
LCDM5
LCDM4
LCDM3
LCDM2
LCDM1
LCDM0
Bit(s)
Name
Description
2–0
LCDM2–LCDM0
LCD controller display mode
000
Time div = 4, bias = 1/3
001
Time div = 3, bias = 1/3
010
Time div = 2, bias = 1/2
011
Time div = 3, bias = 1/2
100
Static
Other = prohibited
3
LCDM3
LCD controller supply voltage
0 = normal (2.7–5.5 V)
1 = low voltage (2–3.4 V)
6–4
LCDM6–LCDM4
7
LCD clock frequency
LCDON
000
76 Hz (5.0 MHz), 64 Hz (4.19 MHz), 64 Hz (32.768 kHz)
001
153 Hz (5.0 MHz), 128 Hz (4.19 MHz),128 Hz (32.768 kHz)
010
305 Hz (5.0 MHz), 256 Hz (4.19 MHz), 256 Hz (32.768 kHz)
011
610 Hz (5.0 MHz), 512 Hz (4.19 MHz), 512 Hz (32.768 kHz)
100
Setting prohibited
LCD display: 1 = on and 0 = off
LCD Display Control Register (LCDC)
The LCDC register (Figure 10-3) sets cutoff of the current flowing to split resistors for LCD drive
voltage generation and switchover between segment output and input/output port functions.
Figure 10-3. LCD Display Control Register (LCDC)
7
6
5
4
3
2
1
0
LCD7
LCD6
LCD5
LCD4
0
0
LEPS
LIPS
Bits
Name
1–0
LEPS, LIPS
Description
Power to LCD
00
7–4
Does not supply power to LCD
01
From VDD pin
10
From BIAS pin
LCD7–LCD4
Port pins
Segment pins
0000
P80–P97
None
0001
P80–P95
S24 – S25
0010
P80–P93
S24 – S27
0011
P80–P91
S24 – S29
0100
P80–P87
S24 – S31
0101
P80–P85
S24 – S33
0110
P80–P83
S24 – S35
0111
P80–P81
S24 – S37
1000
None
S24 – S39
10-3
LCD Controller/Driver
LCD Controller/Driver Settings
LCD controller/driver settings should be performed as listed below. When the LCD controller/
driver is used, the watch timer should be set to the operational state beforehand.
1. Set “Watch Operation enabled” in timer clock selection register 2 (TCL2) and the watch timer
mode control register (TMC2).
2. Set the initial value in the display data memory (FA58h to FA7Fh).
3. Set the pins to be used as segment outputs in the LCD display control register (LCDC).
4. Set the display mode, operating mode, and LCD clock in the LCD display mode register
(LCDM).
5. Set data in the display data memory according to the display contents.
Common Signals and Segment Signals
1. An individual pixel on an LCD panel lights when the potential difference of the corresponding
common signal and segment signal reaches or exceeds a given voltage (the LCD drive voltage VLCD).
2. For common signals, the selection timing order is COM0, 1, 2, and 3. With 2-time-division,
pins COM2 and COM3 are left open; with 3-time-division, the COM3 pin is left open.
3. Segment signals correspond to a 40-byte LCD display data memory. Each memory bit 0, 1,
2, and 3 is read in synchronization with the COM0, 1, 2, and 3 timings, respectively, and if
the value of the bit is 1, it is converted to the selection voltage. If the value of the bit is 0, it is
converted to the non-selection voltage and output to a segment pin (S0 to S39).
4. LCD display data memory bits 1 and 2 are not used with the static display mode, bits 2 and 3
are not used with the 2-time-division method, and bit 3 is not used with the 3-time-division
method. These bits can be used for purposes other than display. Bits 4 to 7 are fixed at 0.
LCD Drive Voltages
Split resistors for producing the LCD drive voltages can be incorporated in the mask ROM
product by mask option. Also, an LCD drive voltage can be externally supplied from the BIAS
pin to produce other LCD drive voltages. With the 1/2 bias method, the VLC1 and VLC2 pins
must be connected externally.
Pins
No Bias
1/2 Bias
1/3 Bias
VLC0
VLCD
VLCD
VLCD
VLC1
2/3 VLCD
1/2 VLCD
2/3 VLCD
VLC2
1/3 VLCD
1/2 VLCD
1/3 VLCD
Example LCD Driver
The example LCD driver uses a 4-time-division display with 1/3 bias. All 40 segments (160
pixels) are used. A 10 x 14-bit segment displays time of day (hours:minutes:seconds) or other
messages. The first segment is connected to the S0 output pin and the last segment to the S39
output pin. The time-of-day display is updated every second. Default time is 12:00:00.
10-4
LCD Controller/Driver
Flowcharts
Figures 10-4, 10-5, and 10-6 are flowcharts of the LCD application programs.
Figure 10-4. Flowcharts of Character Display and LCD Module Routines
Display a character
routine entry input:
• Code = ASCII data
• SegPtr = Display
memory address
No
Yes
Display Alphabet.
CodeW = LCD_Segment
Table (code)
Connect
Code = alphabet
(ASCII)?
Code = digit (ASCII)
?
Yes
Digit display
CodeW = LCD
Segment Table (code)
No
Display other special codes
such as *, –, +, etc.
CodeW = LCD
Segment of the code
Return
Return
LCD display module input:
• CodeW = 16-bit segment of LCD.
• SegPtr = current display
memory address.
• Store Axxx (CodeW15-12) to
display address.
• Decrement display address.
• Store Axxx (CodeW11-8) to
display address.
• Decrement display address.
• Store Axxx (CodeW7-4) to
display address.
• Decrement display address.
• Store Axxx (CodeW3-0) to
display address.
• Decrement display address.
97YL-0329C (12/97)
10-5
LCD Controller/Driver
Figure 10-5. Flowchart of Prescaler Interrupt Interval Routine
INTT3 Prescaler
interval time interrupt
entry
WTIF = 1?
No
Yes
Return
WTIF = 0
Yes
No
1 second passed?
No
Seconds++
Set 1/2-second
passed flag.
Seconds ≥ 60?
Return
Yes
Seconds = 0
Minutes++
Minutes ≥ 60?
Yes
Minutes = 0
Hours++
No
Hours ≥ 24?
Yes
Hours = 0
Days++
No
Interval_Second++
Return
97YL-0321C (12/97)
10-6
LCD Controller/Driver
Figure 10-6. Flowchart of LCD Driver Program
LCD driver entry
Initialization:
• Set "Watch operation
enabled" in timer clock select
register 2 (TCL2).
• Set watch timer mode control
register (TMC2).
• Clear display memory
(FA58h to FA7Fh).
• Set pins to be used as
segment outputs in the LCD
display control register (LCDC).
• Set display mode, operating
mode, and LCD clock in the
LCD display mode register
(LCDM).
Display "12:00:00"
Go to STOP mode.
1 second passed?
No
Yes
Update time of day
and display it.
97YL-0320C (12/97)
10-7
LCD Controller/Driver
Assembly Language: LCD Application Example
;************************************************************************
;
;
File name: LCD.ASM
;
Date: 10/29/97
;****************************************************************************
;
Description:
;
;
;The example program is an LCD driver using 4-time-division and 1/2 bias.
;The program displays the time of day: 'HOURS:MINUTES:SECONDS,'
;Default time is 12:00:00. Every 15.6 milliseconds,
;the program checks whether a second has passed. If so, it updates the display.
;
;======================================================================
;
The system has a main system clock (5 MHz) and a subsystem clock (32.768 kHz).
;
The LCD and watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock, and when a key is depressed, the
;
main system clock is activated.
;======================================================================
;
for only DDB-K0070A
;
$set (DDB)
;======================================================================
;
Equates
;======================================================================
;
;
LCD display memory
;
LCDBuffer
EQU
0FA7Fh
SegmentSize
EQU
40
HOURS_10th_Pt
HOURS_Unit_Pt
COLON1_Pt
MINUTES_10th_Pt
MINUTES_Unit_Pt
COLON2_Pt
SECONDS_10th_Pt
SECONDS_Unit_Pt
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
0FA7Fh
HOURS_10th_Pt HOURS_Unit_Pt COLON1_Pt - 4
MINUTES_10th_Pt
MINUTES_Unit_Pt
COLON2_Pt -4
SECONDS_10th_Pt
AMPM_Pt
EQU
0FA7Fh
4
4
;offset 4 segments
- 4
- 4
-4
;======================================================================
;
saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
;
;
Time of day by watch timer mode
;
Interval_Seconds: ds 1 ;Interval seconds
Seconds:
Minutes:
Hours:
Days:
ds
ds
ds
ds
1
1
1
1
;Seconds
;Minutes
;Hours
;Days
;======================================================================
;
Even boundary pair
;======================================================================
dseg
saddrp
10-8
LCD Controller/Driver
;======================================================================
;
Bit Segment
;======================================================================
bseg
HalfSecondFlag
dbit
;1/2-second toggle flag
ASecondFlag
dbit
;1 second pass
;======================================================================
;
;
Internal High RAM allocation
;
dseg
IHRAM
ds
20h
Stack:
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
org
dw
01Eh
Watch_timer
; Watch timer interval time interrupt
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
public
ResetStart
ResetStart:
di
;
;
Select register bank 0
;
sel
RB0
;
;
Oscillation mode select register
;
. Does not use divider circuit
;
mov
OSMS,#00000001b
;
;
Set stack pointer (IHMEM + 20H)
;
;;
movw
SP,#Stack
movw
SP,#0fe00h
;
;
Clear display memory (FA7Fh (SEG0)
;
movw
hl,#LCDBuffer
mov
a,#0
mov
b,#SegmentSize
clrmem:
mov
[hl],a
decw
hl
dbnz
b,$clrmem
;Disable interrupt
;Select register bank 0 for background
;Stack ptr
;Stack ptr
- FA58h (SEG39))
10-9
LCD Controller/Driver
;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 1 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 1, Select 32.768 kHz subsystem clock)
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================
mov
TCL2,#00010000b
;====================================================================
;
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch operating mode selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler operation control enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter oweration control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for Watch flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)"
)
;
;====================================================================
mov
TMC2,#01010110b
;====================================================================
;
;
LCDC - LCD display control register
;
;
1 0 0 0 0 0 1 0
;
| | | | | | | |__ LCDC.0 (= 0, Power to LCD from BIAS pin)
;
| | | | | | |____ LCDC.1 (= 1, Power to LCD from BIAS pin)
;
| | | | | |______ LCDC.2 (= 0, Reserved)
;
| | | | |________ LCDC.3 (= 0, Reserved)
;
| | | |__________ LCDC.4 (= 0, Select S24-S39)
;
| | |____________ LCDC.5 (= 0, Select S24-S39)
;
| |______________ LCDC.6 (= 0, Select S24-S39)
;
|________________ LCDC.7 (= 1, Select S24-S39)
;
;====================================================================
mov
LCDC,#10000010b
;====================================================================
;
;
LCDM - LCD display mode register
;
;
1 0 0 1 0 0 0 0
;
| | | | | | | |__ LCDM.0 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | | | |____ LCDM.1 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | | |______ LCDM.2 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | |________ LCDM.3 (= 0, Normal mode (2.7 to 5.5 V)
;
| | | |__________ LCDM.4 (= 1, LCD clock 128 Hz)
;
| | |____________ LCDM.5 (= 0, LCD clock 128 Hz)
;
| |______________ LCDM.6 (= 0, LCD clock 128 Hz)
;
|________________ LCDM.7 (= 1, Display on)
;
10-10
LCD Controller/Driver
;====================================================================
mov
LCDM,#10010000b
;
;
Clear time variables
;
mov
Seconds,#0
mov
Minutes,#0
mov
Hours,#12
mov
Days,#0
clr1
ASecondFlag
clr1
HalfSecondFlag
;
;
Enable INTP0 for DDB-K0070A
;
$if (DDB)
clr1
PMK0
$endif
;
Clear IRQ flags
clr1
TMIF3
;
Enable watch timer internal timer
clr1
TMMK3
ei
;======================================================================
;
Display current time of day
;
Default: 12:00:00
;======================================================================
;
;
Set to normal operation
;
mov
PCC,#00000000B
;
;
Go to STANDBY MODE and if wake up then
;
Check second on
;
main_loop:
nop
nop
STOP
nop
;
;
a second passed?
;
bf
ASecondFlag,$main_loop
clr1
;
;
;
ASecondFlag
Display update
call
!DisplayTOD
br
$main_loop
;======================================================================
;
;
Default time of day
;
Default:12:00:00
;
;======================================================================
DisplayTOD:
movw
hl,#HOURS_10th_Pt
mov
a,Hours
cmp
a,#10
bnc
$dtod10
;less than 10
; 0 AM to 9 AM
10-11
LCD Controller/Driver
movw
call
movw
mov
call
br
ax,#00
!DigitDisplay
hl,#HOURS_Unit_Pt
a,Hours
!DigitDisplay
dtod20
dtod10:
cmp
bnc
; 10 AM to 12 PM
movw
call
movw
mov
sub
call
br
;
13 to 23
dtod12:
; 13 hr to 21 hr
cmp
bnc
;
movw
call
movw
mov
sub
call
br
dtod14:
; 22 hr to 23 hr
movw
call
movw
mov
sub
call
br
;
dtod20:
movw
movw
call
;
;
MINUTE: xx
;
movw
a,#12+1
$dtod12
ax,#1
!DigitDisplay
hl,#HOURS_Unit_Pt
a,Hours
a,#10
!DigitDisplay
dtod20
a,#12+9
$dtod14
ax,#00
!DigitDisplay
hl,#HOURS_Unit_Pt
a,Hours
a,#12
!DigitDisplay
dtod20
ax,#1
!DigitDisplay
hl,#HOURS_Unit_Pt
a,Hours
a,#22
!DigitDisplay
dtod20
hl,#COLON1_Pt
ax,#'|'
!DisplayOther
hl,#MINUTES_10th_Pt
mov
mov
a,Minutes
x,#0
cmp
bc
sub
inc
br
a,#10
$mless10
a,#10
x
mloop
mloop:
;
mless10:
;
10-12
;less than 12
xch
a,x
A = 10th , X = unit
push
ax
call
!DigitDisplay
pop
ax
;less than 12
LCD Controller/Driver
xch
call
;
;
;
(:)
movw
movw
call
;
;
;
a,x
!DigitDisplay
hl,#COLON2_Pt
ax,#'|'
!DigitDisplay
Second: xx
movw
hl,#SECONDS_10th_Pt
mov
mov
a,Seconds
x,#0
cmp
bc
sub
inc
br
a,#10
$sless10
a,#10
x
sloop
sloop:
;
sless10:
;
xch
a,x
A = 10th , X = unit
push
ax
call
!DigitDisplay
pop
ax
xch
a,x
call
!DigitDisplay
br
DisplayOther
;======================================================================
;
Display a string to the LCD
;
Terminated either 00 or 0FFH
;
;
Input:
;
DE = String ptr
;
Return:
;
ptr = ptr++;
;======================================================================
DisplayAString:
movw
hl,#LCDBuffer
dlop:
mov
a,[de]
cmp
a,#00
bz
$ds10
;done
cmp
a,#0ffh
bz
$ds10
;done
;
push
de
call
!DisplayACharacter
pop
incw
br
de
de
dlop
ds10:
ret
;======================================================================
;
Display a character to the LCD
;
;
Input: a reg
10-13
LCD Controller/Driver
;
hl = Position
;======================================================================
DisplayACharacter:
push
hl
mov
b,a
movw
cmp
bc
hl,#SegA14
a,#30h
$achar25
cmp
bnc
a,#3Ah
$achar20
;Alphabet
;
;
;
;
Digit
sub
pop
a,#30h
hl
;
;
Digit display
;
DigitDisplay:
push
hl
movw
hl,#SegD14
br
$achar30
;
;
Check Alphabets
;
achar20:
cmp
a,#41h
bc
$achar25
cmp
a,#41H+26
;
;
Alphabet
;
sub
a,#41h
pop
hl
;
;
Alphabet display
;
AlphabetDisplay:
push
hl
br
$achar30
;
;
Not Alphabet or Digits
;
achar25:
pop
hl
;
;
;
DisplayOther:
push
hl
cmp
a,#':'
bnz
$ck10
movw
ax,#L_COLON
br
achar80
ck10:
cmp
a,#'-'
bnz
$ck20
movw
ax,#L_DASH
br
achar80
ck20:
movw
ax,#00
10-14
;Alphabet
;Digit
;blank
LCD Controller/Driver
br
;
;
;
achar30:
Read 2 bytes
clr1
rolc
mov
mov
xch
inc
mov
xch
;
;
;
;
achar80:
cy
a,1
b,a
a,[hl+b]
a,x
b
a,[hl+b]
a,x
;* 2
;a = upper, x = lower byte
a = upper byte/b = lower byte
X---h
pop
;
;
HL = data
;
AX = data
;
DisplayData:
;
X---h
push
ror
ror
ror
ror
and
mov
;
-X--h
pop
and
mov
;
--X-h
mov
push
;
achar80
ror
ror
ror
ror
and
mov
---Xh
pop
and
mov
hl
ptr
ax
a,1
a,1
a,1
a,1
a,#0fh
[hl+0],a
ax
a,#0fh
[hl+1],a
a,x
ax
a,1
a,1
a,1
a,1
a,#0fh
[hl+2],a
ax
a,#0fh
[hl+3],a
;
decw
hl
decw
hl
decw
hl
decw
hl
ret
;* ***********************************************
;*
Define COM Line #
;* ***********************************************
COM1
equ 1
COM2
equ 2
COM3
equ 4
COM4
equ 8
;*
10-15
LCD Controller/Driver
;*
;*
s16_G
s16_J
s16_L
s16_D
Segment Definitions
equ
equ
equ
equ
COM1
COM2
COM3
COM4
s16_O
s16_F
s16_E
s16_P
equ
equ
equ
equ
COM1*010h
COM2*010h
COM3*010h
COM4*010h
s16_I
s16_B
s16_C
s16_N
equ
equ
equ
equ
COM1*0100h
COM2*0100h
COM3*0100h
COM4*0100h
s16_A
equ COM1*01000h
s16_H
equ COM2*01000h
s16_K
equ COM3*01000h
s16_M
equ COM4*01000h
;* ***********************************************
;
Table for 14-Segment LCDs
;* ***********************************************
SegD14:
dw
s16_A+s16_B+s16_C+s16_D+s16_E+s16_F
dw
s16_B+s16_C
dw
s16_A+s16_B+s16_K+s16_J+s16_E+s16_D
dw
s16_A+s16_B+s16_K+s16_J+s16_C+s16_D
dw
s16_F+s16_J+s16_K+s16_B+s16_C
dw
s16_A+s16_F+s16_J+s16_K+s16_C+s16_D
dw
s16_A+s16_C+s16_D+s16_E+s16_F+s16_J+s16_K
dw
s16_A+s16_B+s16_C
dw
s16_A+s16_B+s16_C+s16_D+s16_E+s16_F+s16_J+s16_K
dw
s16_A+s16_B+s16_C+s16_D+s16_F+s16_J+s16_K
;*
;*
Alphabet
;*
SegA14:
dw
s16_F+s16_E+s16_A+s16_B+s16_C+s16_J+s16_K
dw
s16_A+s16_B+s16_C+s16_D+s16_H+s16_M+s16_K
dw
s16_A+s16_F+s16_E+s16_D
dw
s16_A+s16_B+s16_C+s16_D+s16_H+s16_M
dw
s16_A+s16_F+s16_E+s16_D+s16_J+s16_K
dw
s16_A+s16_F+s16_E+s16_J+s16_K
dw
s16_A+s16_F+s16_E+s16_D+s16_C+s16_K
dw
s16_F+s16_E+s16_J+s16_K+s16_B+s16_C
dw
s16_A+s16_H+s16_M+s16_D
dw
s16_E+s16_B+s16_C+s16_D
dw
s16_F+s16_E+s16_J+s16_I+s16_N
dw
s16_F+s16_E+s16_D
dw
s16_F+s16_E+s16_G+s16_I+s16_B+s16_C
dw
s16_F+s16_E+s16_G+s16_N+s16_B+s16_C
dw
s16_F+s16_E+s16_A+s16_B+s16_C+s16_D
dw
s16_F+s16_E+s16_A+s16_B+s16_K+s16_J
dw
s16_E+s16_F+s16_A+s16_B+s16_C+s16_D+s16_N
dw
s16_F+s16_E+s16_A+s16_B+s16_K+s16_J+s16_N
dw
s16_A+s16_F+s16_J+s16_K+s16_C+s16_D
dw
s16_A+s16_H+s16_M
dw
s16_F+s16_E+s16_D+s16_C+s16_B
dw
s16_F+s16_E+s16_L+s16_I
dw
s16_F+s16_E+s16_L+s16_N+s16_C+s16_B
dw
s16_G+s16_N+s16_I+s16_L
dw
s16_F+s16_J+s16_K+s16_B+s16_M
10-16
;0
;1
;2
;3
;4
;5
;6
;7
;8
;9
;A
;B
;C
;D
;E
;F
;G
;H
;I
;J
;K
;L
;M
;N
;O
;P
;Q
;R
;S
;T
;U
;V
;W
;X
;Y
LCD Controller/Driver
dw
s16_A+s16_I+s16_L+s16_D
;Z
L_DASH
equ
s16_J+s16_K
;dash (-)
L_UNDER
equ
s16_D
;underline (_)
L_SLASH
equ
s16_I+s16_L
;slash (/)
L_BSLASH
equ
s16_G+s16_N
;Back slash (\)
L_STAR
equ
s16_I+s16_L+s16_G+s16_N ;star (*)
R_ARROW
equ
s16_G+s16_L+s16_J
;Right arrow (->)
L_ARROW
equ
s16_I+s16_N+s16_N
;Left arrow (<-)
L_BRACK
equ
s16_I+s16_N
;<
R_BRACK
equ
s16_G+s16_L
;>
L_APOSTR
equ
s16_I
;apostrophe (')
L_COLON
equ
s16_H+s16_M
;colon (:)
;* ***********************************************
;*
7-Segment LCDs
;* ***********************************************
s7_E
equ COM1
s7_G
equ COM2
s7_F
equ COM3
s7_K
equ COM4
s7_C
equ COM1*010h
s7_B
equ COM2*010h
s7_A
equ COM3*010h
s7_D
equ COM4*010h
;* ***********************************************
;*
7-Segment LCDs
;* ***********************************************
Tab7Seg:
ds
s7_A+s7_B+s7_C+s7_D+s7_E+s7_F
;0
ds
s7_B+s7_C
;1
ds
s7_A+s7_B+s7_G+s7_E+s7_D
;2
ds
s7_A+s7_B+s7_G+s7_C+s7_D
;3
ds
s7_F+s7_G+s7_B+s7_C
;4
ds
s7_A+s7_F+s7_G+s7_C+s7_D
;5
ds
s7_A+s7_F+s7_G+s7_C+s7_D+s7_E
;6
ds
s7_A+s7_B+s7_C
;7
ds
s7_A+s7_B+s7_C+s7_D+s7_F+s7_E+s7_G
;8
ds
s7_A+s7_B+s7_C+s7_D+s7_F+s7_G
;9
ds
;
;
;
S7_S
s7_A+s7_B+s7_E+s7_F+s7_G
;P in open
Must be less than 15
equ
11
ds
S7_E
equ
S7_P
equ
s7_A+s7_C+s7_D+s7_F+s7_G
;S
s7_A+s7_D+s7_F+s7_E+s7_G
;E
ds
s7_A+s7_B+s7_F+s7_E+s7_G
;P
equ
ds
s7_G
s7_A+s7_B+s7_C+s7_D+s7_F+s7_E+s7_G
;A
ds
s7_B+s7_C
;: - colon
12
ds
dash_7
13
Colon7seg:
$ej
;======================================================================
;
Module name: INTTM3 watch timer interval time interrupt
;
;
Interrupted every 15.6 ms.
;
;
DESCRIPTION:
;
Set watch time variables
10-17
LCD Controller/Driver
;
;
OPERATION:
;
. Flip the HalfSecondFlag
;
. If HalfSecondFlag = 0, then incr. seconds
;
. If Seconds == 60, incr. Minutes
;
. If Minutes == 60, incr. Hours
;
. If Hours
== 24, incr. Days
;
;======================================================================
public
Watch_timer
Watch_timer:
;
;
Test half second flag
;
bf
WTIF,$wt20
;not yet
clr1
WTIF
;
;
1/2 second passed
;
bf
HalfSecondFlag,$wt10 ;1/2 second passed
;
Clear half-second flag
clr1
HalfSecondFlag
;
set1
ASecondFlag
;
inc
Interval_Seconds
inc
Seconds
cmp
Seconds,#60
bc
$wt20
mov
Seconds,#0
;
inc
Minutes
cmp
Minutes,#60
bc
$wt20
mov
Minutes,#0
;
inc
Hours
cmp
Hours,#24
bc
$wt20
mov
Hours,#0
;
Day
inc
Days
cmp
Days,#30
bc
$wt20
br
$wt20
set1
HalfSecondFlag
;
wt10:
wt20:
reti
;======================================================================
end
_
#pragma interrupt INTTM3 WatchTimer RB1
10-18
LCD Controller/Driver
C Language: LCD Application Examples
/*;************************************************************************
;
;
File name: LCD.C
;
Date: 10/29/97
;****************************************************************************
;
Description:
;
;
;The example program is an LCD driver using 4-time-division and 1/2 bias.
;The program displays the time of day, 'HOURS:MINUTES:SECONDS,'
;Default time is 12:00:00. Every 15.6 milliseconds,
;the program checks whether a second has passed. If so, it updates the display;
;======================================================================
;
The system has a main system clock (5 MHz) and a subsystem clock (32.768 kHz).
;
The LCD and watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock, and when a key is depressed, the
;
main system clock is activated.
;======================================================================*/
#include "define.h"
/*;======================================================================
;
Equates
;======================================================================*/
//;
//;
LCD Display Memory
//;
#define LCDBuffer
0xFA7F
#define SegmentSize
40
#define
#define
#define
#define
#define
#define
#define
#define
HOURS_10th_Pt
HOURS_Unit_Pt
COLON1_Pt
MINUTES_10th_Pt
MINUTES_Unit_Pt
COLON2_Pt
SECONDS_10th_Pt
SECONDS_Unit_Pt
#define AMPM_Pt
0xFA7F
HOURS_10th_Pt- 4
HOURS_Unit_Pt - 4
COLON1_Pt - 4
MINUTES_10th_Pt - 4
MINUTES_Unit_Pt - 4
COLON2_Pt -4
SECONDS_10th_Pt -4
//;offset 4 segments
0xFA7F
//;
//;
Time of day by Watch timer mode
//;
__sreg
Interval_Seconds;
__sreg
unsigned char Seconds
__sreg
unsigned char Minutes
__sreg
unsigned char Hours
__sreg
unsigned char Days
__sreg
unsigned char *SegPtr
__sreg
unsigned int CodeW;
bit HalfSecondFlag
bit ASecondFlag
void DisplayACharacter (unsigned char code);
void DisplayAString (char *);
void DisplayTOD (void);
void DisplayOther (unsigned char code);
void LCDDisplay (void);
void DigitDisplay (char code);
void AlphabetDisplay (char code);
;
;
;
;
;
//Seconds
//Minutes
//Hours
//Days
//Segment ptr
; // 1/2 -second toggle flag
; // 1-second pass flag
/* ;* ***********************************************
;*
Define COM Line #
;* *********************************************** */
10-19
LCD Controller/Driver
#define
#define
#define
#define
//*
//*
//*
#define
#define
#define
#define
COM1
COM2
COM3
COM4
1
2
4
8
s16_G
s16_J
s16_L
s16_D
COM1
COM2
COM3
COM4
#define
#define
#define
#define
s16_O
s16_F
s16_E
s16_P
COM1*0x10
COM2*0x10
COM3*0x10
COM4*0x10
#define
#define
#define
#define
s16_I
s16_B
s16_C
s16_N
COM1*0x100
COM2*0x100
COM3*0x100
COM4*0x100
#define
#define
#define
#define
s16_A
s16_H
s16_K
s16_M
COM1*0x1000
COM2*0x1000
COM3*0x1000
COM4*0x1000
Segment Definitions
/*;* ***********************************************
;
Table for 14-Segment LCDs
;* *********************************************** */
unsigned int const SegD14[] =
{
s16_A+s16_B+s16_C+s16_D+s16_E+s16_F
,s16_B+s16_C
,s16_A+s16_B+s16_K+s16_J+s16_E+s16_D
,s16_A+s16_B+s16_K+s16_J+s16_C+s16_D
,s16_F+s16_J+s16_K+s16_B+s16_C
,s16_A+s16_F+s16_J+s16_K+s16_C+s16_D
,s16_A+s16_C+s16_D+s16_E+s16_F+s16_J+s16_K
,s16_A+s16_B+s16_C
,s16_A+s16_B+s16_C+s16_D+s16_E+s16_F+s16_J+s16_K
,s16_A+s16_B+s16_C+s16_D+s16_F+s16_J+s16_K
};
//;*
//;*
Alphabet
//;*
const unsigned int SegA14[] =
{
s16_F+s16_E+s16_A+s16_B+s16_C+s16_J+s16_K
,s16_A+s16_B+s16_C+s16_D+s16_H+s16_M+s16_K
,s16_A+s16_F+s16_E+s16_D
,s16_A+s16_B+s16_C+s16_D+s16_H+s16_M
,s16_A+s16_F+s16_E+s16_D+s16_J+s16_K
,s16_A+s16_F+s16_E+s16_J+s16_K
,s16_A+s16_F+s16_E+s16_D+s16_C+s16_K
,s16_F+s16_E+s16_J+s16_K+s16_B+s16_C
,s16_A+s16_H+s16_M+s16_D
,s16_E+s16_B+s16_C+s16_D
,s16_F+s16_E+s16_J+s16_I+s16_N
,s16_F+s16_E+s16_D
,s16_F+s16_E+s16_G+s16_I+s16_B+s16_C
,s16_F+s16_E+s16_G+s16_N+s16_B+s16_C
10-20
// ;0
// ;1
// ;2
// ;3
// ;4
// ;5
// ;6
// ;7
//;8
//;9
//;A
//;B
//;C
//;D
//;E
//;F
//;G
//;H
//;I
//;J
//;K
//;L
//;M
//;N
LCD Controller/Driver
,s16_F+s16_E+s16_A+s16_B+s16_C+s16_D
,s16_F+s16_E+s16_A+s16_B+s16_K+s16_J
,s16_E+s16_F+s16_A+s16_B+s16_C+s16_D+s16_N
,s16_F+s16_E+s16_A+s16_B+s16_K+s16_J+s16_N
,s16_A+s16_F+s16_J+s16_K+s16_C+s16_D
,s16_A+s16_H+s16_M
,s16_F+s16_E+s16_D+s16_C+s16_B
,s16_F+s16_E+s16_L+s16_I
,s16_F+s16_E+s16_L+s16_N+s16_C+s16_B
,s16_G+s16_N+s16_I+s16_L
,s16_F+s16_J+s16_K+s16_B+s16_M
,s16_A+s16_I+s16_L+s16_D
//;O
//;P
//;Q
//;R
//;S
//;T
//;U
//;V
//;W
//;X
//;Y
//;Z
};
#define L_DASHs16_J+s16_K
#define L_COLON s16_H+s16_M
//;dash (-)
//;colon (:)
/* ;* ***********************************************
;*
7-Segment LCDs
;* *********************************************** */
#define
#define
#define
#define
#define
#define
#define
#define
s7_E
s7_G
s7_F
s7_K
s7_C
s7_B
s7_A
s7_D
COM1
COM2
COM3
COM4
COM1*0x10
COM2*0x10
COM3*0x10
COM4*0x10
/*;* ***********************************************
;*
7-Segment LCDs
;* *********************************************** */
const unsigned char Tab7Seg[] =
{
s7_A+s7_B+s7_C+s7_D+s7_E+s7_F
,s7_B+s7_C
,s7_A+s7_B+s7_G+s7_E+s7_D
,s7_A+s7_B+s7_G+s7_C+s7_D
,s7_F+s7_G+s7_B+s7_C
,s7_A+s7_F+s7_G+s7_C+s7_D
,s7_A+s7_F+s7_G+s7_C+s7_D+s7_E
,s7_A+s7_B+s7_C
,s7_A+s7_B+s7_C+s7_D+s7_F+s7_E+s7_G
,s7_A+s7_B+s7_C+s7_D+s7_F+s7_G
//;
//;
Must be less than 15
//;
,s7_A+s7_C+s7_D+s7_F+s7_G
,s7_A+s7_D+s7_F+s7_E+s7_G
,s7_A+s7_B+s7_F+s7_E+s7_G
,s7_A+s7_B+s7_C+s7_D+s7_F+s7_E+s7_G
,s7_B+s7_C
};
//;0
//;1
//;2
//;3
//;4
//;5
//;6
//;7
//;8
//;9
//;S
//;E
//;P
//;A
//;: - colon
//;======================================================================
//;
Main
//;======================================================================
void main ()
{
char i;
char *dptr;
10-21
LCD Controller/Driver
//;
//;
//;
//;
Oscillation mode select register
. Does not use divider circuit
OSMS = 0b00000001;
PMK0 = 0;
//;
//;
//;
// select 5 MHz
// for DDB BOARD - INTP0 has to be set
Clear Display Memory (FA7Fh (SEG0) - FA58h (SEG39))
dptr = LCDBuffer;
for (i=0;i<SegmentSize;i++) *dptr-- = 0;
/*;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 1 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 1, Select 32.768 kHz subsystem clock)
;
| | |____________ TCL2.5 (Buzzer Output Frequency selection)
;
| |______________ TCL2.6 (Buzzer Output Frequency selection)
;
|________________ TCL2.7 (Buzzer Output Frequency selection)
;
;====================================================================*/
TCL2= 0b00010000;
/*;====================================================================
;
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch Operating Mode Selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler Operation control enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for watch flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)
;
;====================================================================*/
TMC2 = 0b01010110;
/*;====================================================================
;
;
LCDC - LCD display control register
;
;
1 0 0 0 0 0 1 0
;
| | | | | | | |__ LCDC.0 (= 0, Power to LCD from BIAS pin)
;
| | | | | | |____ LCDC.1 (= 1, Power to LCD from BIAS pin)
;
| | | | | |______ LCDC.2 (= 0, Reserved)
;
| | | | |________ LCDC.3 (= 0, Reserved)
;
| | | |__________ LCDC.4 (= 0, Select S24-S39)
;
| | |____________ LCDC.5 (= 0, Select S24-S39)
;
| |______________ LCDC.6 (= 0, Select S24-S39)
;
|________________ LCDC.7 (= 1, Select S24-S39)
;
;====================================================================*/
LCDC = 0b10000010;
/*;====================================================================
;
;
LCDM - LCD Display mode register
;
10-22
LCD Controller/Driver
;
1 0 0 1 0 0 0 0
;
| | | | | | | |__ LCDM.0 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | | | |____ LCDM.1 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | | |______ LCDM.2 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | |________ LCDM.3 (= 0, Normal mode (2.7 to 5.5 v)
;
| | | |__________ LCDM.4 (= 1, LCD clock 128 Hz)
;
| | |____________ LCDM.5 (= 0, LCD clock 128 Hz)
;
| |______________ LCDM.6 (= 0, LCD clock 128 Hz)
;
|________________ LCDM.7 (= 1, Display on)
;
;====================================================================*/
LCDM = 0b10010000;
//;
//;
Clear time variables
//;
Seconds=0;
Minutes=0;
Hours=0;
Days= 0;
ASecondFlag = 0;
HalfSecondFlag = 0;
//;
Clear IRQ flags
TMIF3 = 0;
//;
Enable watch timer Internal timer
TMMK3 = 0;
EI ();
/*;======================================================================
;
Display current time of day
;
Default: 12:00:00
;======================================================================*/
//;
//;
Set to normal operation
//;
PCC = 0b00000000;
//;
//;
Go to STANDBY MODE and if wake up then
//;
Check Second on
//;
while (TRUE)
{
NOP ();
NOP ();
STOP ();
NOP ();
//;
//;
a second passed?
//;
if ( ASecondFlag )
{
ASecondFlag = 0;
//;
//;
Display update
//;
DisplayTOD ();
}
}
}
/*;===================================================================
;
Default Time of day
;
Default:12:00:00
;===================================================================*/
void DisplayTOD (void)
10-23
LCD Controller/Driver
{
//;
//;
//;
//;
SegPtr = HOURS_10th_Pt;
if (Hours < 10)
{
0 AM to 9 AM
DigitDisplay (0);
SegPtr = HOURS_Unit_Pt;
DigitDisplay (Hours);
}
if (Hours < 12)
{
10 AM to 12 AM
DigitDisplay (1);
SegPtr = HOURS_Unit_Pt;
DigitDisplay (Hours-10);
}
if (Hours < 21)
{
1 PM to 9 PM
DigitDisplay (0);
SegPtr = HOURS_Unit_Pt;
DigitDisplay (Hours-12);
}
if (Hours >= 22)
{
10 PM to 12 PM
DigitDisplay (1);
SegPtr = HOURS_Unit_Pt;
DigitDisplay (Hours-22);
}
// :
SegPtr = COLON1_Pt;
DisplayOther ('|');
//; minutes
SegPtr = MINUTES_10th_Pt;
DigitDisplay (Minutes/60);
SegPtr = MINUTES_Unit_Pt;
DigitDisplay (Minutes%60);
// :
SegPtr = COLON2_Pt;
DisplayOther ('|');
//; Seconds
SegPtr = SECONDS_10th_Pt;
DigitDisplay (Seconds/60);
SegPtr = SECONDS_Unit_Pt;
DigitDisplay (Seconds%60);
}
/*;======================================================================
;
Display a string to the LCD
;
Terminated either 00 or 0FFH
;
;
Input:
;
HL = String ptr
;
Return:
;
ptr = ptr++;
;======================================================================*/
void DisplayAString (char Buffer[])
{
char *dptr;
10-24
LCD Controller/Driver
SegPtr =Buffer;
while (!*dptr)
{
DisplayACharacter (*dptr++);
}
}
/*;======================================================================
;
Display a character to the LCD
;
;
Input: a reg
;
hl = Position
;======================================================================*/
void DisplayACharacter (unsigned char code)
{
if (code >= 0x30 && code <= 0x39 )
{
DigitDisplay (code*2);
}
else
{
if (code >= 0x41 && code <= 0x59 )
{
AlphabetDisplay (code*2);
}
else
DisplayOther (code);
}
}
void DigitDisplay (char code)
{
CodeW = SegD14[ (code-0x30) * 2];
LCDDisplay ();
}
void AlphabetDisplay (char code)
{
CodeW = SegA14[ (code-0x41) * 2];
LCDDisplay ();
}
void DisplayOther (unsigned char code)
{
if (code == 0)
{
CodeW = 0;
LCDDisplay ();
}
if (code == ':')
{
CodeW = L_COLON;
LCDDisplay ();
}
if (code == '-')
{
CodeW = L_DASH;
LCDDisplay ();
}
}
/*;======================================================================
;
Display a code
;
INPUT: CodeW = 16 bits
;
10-25
LCD Controller/Driver
;======================================================================*/
void LCDDisplay (void)
{
unsigned int c;
//;
X---h
c = (CodeW & 0xf000) >> 12;
c &= 0xf;
*SegPtr-- = (char)c;
//;
-X--h
c = (CodeW & 0x0f00) >> 8;
c &= 0xf;
*SegPtr-- = (char)c;
//;
--X-h
c = (CodeW & 0x00f0) >> 4;
c &= 0xf;
*SegPtr-- = (char)c;
//;
---Xh
c = (CodeW & 0x000f);
*SegPtr-- = (char)c;
}
/*;======================================================================
;
Module name: INTTM3 Watch timer Interval Time Interrupt
;
;
DESCRIPTION:
;
Set watch time variables
;
;
OPERATION:
;
. Flip the HalfSecondFlag.
;
. If HalfSecondFlag = 0, then incr. seconds
;
. If Seconds = 60, incr. Minutes
;
. If Minutes = 60, incr. Hours
;
. If Hours
= 24, incr. Days
;
;======================================================================*/
void WatchTimer ()
{
//;
//;
Test half second flag
//;
if ( !WTIF) return;
//;
WTIF = 0;
//;
//;
1/2 second passed
//;
if ( !HalfSecondFlag)
{
HalfSecondFlag = 1;
return;;
}
//;
HalfSecondFlag = 0;
//;
ASecondFlag = 1;
Interval_Seconds++;
Seconds++;
if (Seconds < 60) return;;
Seconds = 0;
Minutes++;
10-26
LCD Controller/Driver
if (Minutes < 60) return;;
Minutes = 0;
Hours++;
if (Hours < 24) return;;
Hours = 0;
Days++;
}
_
10-27
LCD Controller/Driver
10-28
11
Keyboard Input
Applicable K0 Devices
•
•
•
•
•
•
•
•
•
µPD7801xF
µPD7801xH
µPD7805x
µPD7805xF
µPD78005x
µPD7807x
µPD78070A
µPD7806x
µPD78030x
Description
The keyboard input application is one of the most useful applications in consumer products
because the user interface requires a data or command input from a keyboard. The other
important function with key input is the standby mode. Most applications are activated by a key
input, and if a key is not depressed, the system is in a standby mode to save power. In the K0
family, port 11 is designated as the key input port for the standby mode of the microcontroller.
(The µPD7801xF, µPD7801xH, µPD7805x, µPD7805xF, µPD78005x, µPD7807x, and
µPD78070A use port 4.)
The key return mode register KRM (Figure 11-1) enables/disables the standby mode release by
a key return signal. When falling-edge detection of port 11 is used, KRIF should be cleared to 0
(it is not cleared automatically).
Figure 11-1. Key Return Mode Register (KRM)
7
6
5
4
3
2
1
0
0
0
0
0
KRM3
KRM2
KRMK
KRIF
Bit(s)
Name
Description
0
KRIF
Key return signal detection flag
0 = Not detected
1 = Detected (falling edge on port 11)
1
KRMK
Standby mode control by key return signal
0 = Standby mode release enabled
1 = Standby mode release disabled
3–2
KRM3–KRM2
Selection of port 11 falling edge input
00
P117
01
P114–P117
10
P112–P117
11
P110–P117
11-1
Keyboard Input
Example Program
The example program is a module that inputs signals from a matrix of 4 x 4 keys (Figure 11-2).
The keys can be pressed successively, and two or more keys can be pressed simultaneously. In
the circuit shown in this example, the higher 4 bits of port 3 (P34–P37) are used as key scan
signals, and port 11 is used for key return signals. As the pullup resistor of port 11 for key
return, use the internal pullup resistor set by software.
Port 11 of the K0 family has a function to detect the falling edges of the eight port pins in
parallel. If port 11 is used for key return signals, therefore, the standby mode can be released
through detection of a falling edge by key input.
Figure 11-1. 4 x 4 Key Matrix
P34
P35
P36
P37
P114
P115
P116
P117
97YL-0323C (12/97)
The input keys are stored to RAM on a bit/key basis. The RAM bit corresponding to a pressed
key is set and the bit corresponding to a released key is cleared. By testing the RAM data on a
one-bit basis starting from the first bit, the key status can be checked. To absorb key
debouncing, the key is assumed to be valid when four successive key codes coincide with a
given code. For example, if a key code is sampled every 16 ms, debouncing of 48 to 64 ms can
be absorbed.
11-2
Key Number
0 = P114 + P34
1 = P114 + P35
2 = P114 + P36
3 = P114 + P37
8 = P116 + P34
9 = P116 + P35
10 = P116 + P36
11 = P116 + P37
4 = P115 + P34
5 = P115 + P35
6 = P115 + P36
7 = P115 + P37
12 = P117 + P34
13 = P117 + P35
14 = P117 + P36
15 = P117 + P37
Keyboard Input
Figure 11-1. Flowchart of Key Input Routine
Key input module
entry
Key scan entry
Initialization:
• KRM (key return
mode register) with
standby release
enabled.
• TCL2 to watch timer
by subsystem clock.
• TMC2 to 0.5-second
watch flag set
• P3 = 0
• Read P4 (or P11)
• Key-on flag = 0
• Debounce count = 3
• Key-off flag = 0FFh
Key depressed?
No
Yes
• Enable interrupts.
• Clear time variables.
• Set to Normal
operation mode (main
system clock 5 MHz
and subsystem clock
32.768 kHz).
Which row?
Key off
Row = 1, 2, 3, or 4
Key number = Row * 4
Sleep (STOP mode)
Which column?
No
Column = 1, 2, 3, or 4
Wake up?
Key number = Row x 4 +
column
Yes
Call key scan module.
Previous key =
current key?
No
Key off
Return
Yes
No
Key depressed?
Previous key = current
key
Yes
Service the key.
Decrement debounce
No
Debounce = 0?
Yes
Key-on flag = 1
Connect
97YL-0325C (12/97)
11-3
Keyboard Input
Assembly Language Program: Example of Key Matrix
;************************************************************************
;
;
File name: key.ASM
;
Date: 10/27/97
;****************************************************************************
;
Description:
;
;
;The example program is a key input module that inputs signals from a 4 x 4 key matrix.
;The keys can be pressed successively, and two or more keys can
;be pressed simultaneously. In this example, the higher 4
;bits of port 3 (P34 - P37) are used as key scan signals, and port 11 (P4 for µPD78054 or µPD78078)
;is used for key return signals. As the pullup resistor of port 11 for key return, the
;internal pullup resistor set by software is used.
;
;Port 11 of the K0 series has a function to detect the falling edges of the
;eight port pins in parallel. If port 11 is used for key return signals,
;therefore, the standby mode can be released through detection of a falling
;edge by key input.
;
;The input keys are stored to RAM on a one bit/key basis. The RAM bit
;corresponding to a pressed key is set and the bit corresponding to a released
;key is cleared. By testing the RAM data on a 1-bit basis starting
;from the first bit, the key status can be checked. To absorb key debouncing,
;the key is assumed to be valid when four successive key codes coincide with a
;given code. For example, if a key code is sampled every 16 ms, debouncing of
;48 ms to 64 ms can be absorbed.
;
; Key number:
;
0 = P114 + P34
;
1 = P114 + P35
;
2 = P114 + P36
;
3 = P114 + P37
;
;
4 = P115 + P34
;
5 = P115 + P35
;
6 = P115 + P36
;
7 = P115 + P37
;
;
8 = P116 + P34
;
9 = P116 + P35
;
10 = P116 + P36
;
11 = P116 + P37
;
;
12 = P117 + P34
;
13 = P117 + P35
;
14 = P117 + P36
;
15 = P117 + P37
;
;
Port 4 is used instead of port 11 for µPD78054 or µPD78078.
;
;======================================================================
;
The system has a main system clock (5 MHz) and a subsystem clock (32.768 kHz).
;
The LCD and watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock, but when a key is depressed,
;
the main system clock is activated.
;======================================================================
;
for only DDB-K0070A
;
$set (DDB)
$set (D054)
;======================================================================
11-4
Keyboard Input
;
DebugFlag set 1
;======================================================================
;
Equates
;======================================================================
;======================================================================
;
saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
;
;
Time of day by watch timer mode
;
Interval_Seconds:
ds
1
;Interval seconds
Seconds:
Minutes:
Hours:
Days:
ds
1
ds
ds
1
1
1
;Seconds
;Minutes
;Hours
;Days
KeyNumber:
ds
1
;Key number
;======================================================================
;
Even boundary pair
;======================================================================
dseg
saddrp
;======================================================================
;
Bit segment
;======================================================================
bseg
HalfSecondFlag
dbit
;1/2-second toggle flag
;======================================================================
;
;
Internal High RAM allocation
;
dseg
IHRAM
ds
20h
Stack:
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
org
dw
01Eh
Watch_timer
; Watch timer interval time interrupt
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
public
ResetStart
ResetStart:
di
;
;
Select register bank 0
;
sel
RB0
;Disable interrupt
;Select register bank 0 for background
11-5
Keyboard Input
;
;
;
;
Oscillation mode select register
. Does not use divider circuit
mov
;
;
;
;;
OSMS,#00000001b
Set stack pointer (IHMEM + 20H)
movw
movw
SP,#Stack
SP,#0fe00h
;Stack ptr
;Stack ptr
;====================================================================
;
Key return mode register (KRM)
;
;
0 0 0 0 0 1 0 0
;
| | | | | | | |__ KRM.0 (= 0, Not detected key return signal)
;
| | | | | | |____ KRM.1 (= 1, Standby mode release enabled)
;
| | | | | |______ KRM.2 (= 1, Select P114-P117 as key return signal port)
;
| | | | |________ KRM.3 (= 0, Select P114-P117 as key return signal port)
;
| | | |__________ KRM.4 (= 0, Reserved)
;
| | |____________ KRM.5 (= 0, Reserved)
;
| |______________ KRM.6 (= 0, Reserved)
;
|________________ KRM.7 (= 0, Reserved)
;
;
If µPD78054 or µPD78078, KRM.2 and KRM.3 cannot be defined.
;
;====================================================================
mov
KRM,#00000100b
; Set scan ports
mov
PM3,#11110000B
;P34-P37 output
mov
P3,#00000000b
;Set P34-P37 to low
; Set sense ports
$if (D054)
$else
mov
PM11,#11110000B ;P114-P117 as input
$endif
;
;
Pull-up resistor option on P11
;
$if (D054)
mov
PUOL,#00010000B
$else
mov
PUOH,#00001000B
$endif
;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 1 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 1, Select 32.768-kHz subsystem clock)
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================
mov
TCL2,#00010000b
;====================================================================
;
11-6
Keyboard Input
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch operating mode selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler operation control enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for watch flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)"
;
;====================================================================
mov
TMC2,#01010110b
;
;
Clear time variables
;
mov
Seconds,#0
mov
Minutes,#0
mov
Hours,#0
mov
Days,#0
;
;
Enable INTP0 for DDB-K0070A
;
$if (DDB)
clr1
PMK0
$endif
;
Clear IRQ flags
clr1
TMIF3
;
Enable watch timer internal timer
clr1
TMMK3
ei
;
main_loop:
;======================================================================
;
Normal operation
;
Main system clock with subsystem clock operation
;======================================================================
NormalMode:
;
;
Set to normal operation
;
mov
PCC,#00000000B
;
;
Scan keyboard - every 15.6 ms will wake it up
;
nop
nop
STOP
nop
call
!KeyScan
;
cf = 1 key detected; cf = 0 no key found
bc
$ServiceKey
;
;
no key
;
nop
br
$main_loop
;
;
Key service modules
;
ServiceKey:
nop
mov
a,KeyNumber
11-7
Keyboard Input
;
;
;
Service
br
$main_loop
;======================================================================
;
Key scan module
;
;
The key matrix is 4 x 4. There are four scan ports (P34-P37) and
;
four key return signal ports (P114-P117).
;
Debounce count is set to 4.
;
;
Key number:
;
0 = P114 + P34
;
1 = P114 + P35
;
2 = P114 + P36
;
3 = P114 + P37
;
4 = P115 + P34
;
5 = P115 + P35
;
6 = P115 + P36
;
7 = P115 + P37
;
8 = P116 + P34
;
9 = P116 + P35
;
10 = P116 + P36
;
11 = P116 + P37
;
12 = P117 + P34
;
13 = P117 + P35
;
14 = P117 + P36
;
15 = P117 + P37
;
;
Return:
;
cf = 1 if a key is depressed
;
and KeyNumber with key number
;
;
cf = 0 if no key is depressed
;
;
Registers:
;
a = Scratch
;
b = Total row or column numbers
;
c = Sense port
;
d = Row x 4 + column
;
e = Column port
;
h = Current key number
;
l = Number of debounces
;
x = Find a row
;======================================================================
KeyScan:
;
;
Find a key
;
mov
h,#0ffh
;no key flag
mov
l,#3
KeyScanLoop:
and
$if (D054)
mov
$else
mov
$endif
and
cmp
bz
;
11-8
P3,#11110000b
a,P4
a,P11
a,#11110000b
a,#11110000b
$NotFound
;mask low nibble
;all high
;no key depressed
Keyboard Input
mov
mov
mov
mov
c,a
d,#0
x,#00010000b
b,#4
;key number
;find a row
;4 rows
CheckRow:
mov
a,x
and
a,c
bz
$RowFind
; shift to left
mov
a,x
clr1
cy
rol
a,1
mov
x,a
; update row x column
mov
a,d
add
a,#4
mov
d,a
;
dbnz
b,$CheckRow
;
;
Not Found
;
NotFound:
clr1
cy
ret
;
;
Row find. Find column.
;
d = row x column
;
x = row position
;
RowFind:
mov
e,#00000001b
mov
b,#4
CheckCol:
mov
a,e
mov
p3,a
$if (D054)
mov
a,P4
$else
mov
a,P11
$endif
and
a,x
bnz
$ColFind
; shift to left
clr1
cy
mov
a,e
rol
a,1
mov
e,a
;
;
Incr. key number
;
inc
d
dbnz
b,$CheckCol
br
NotFound
;
ColFind:
mov
a,d
cmp
a,h
bz
$CheckDebounce
;
;
Restart key scan
;
mov
h,a
;
;find the row
;find a column
;4 columns
;set to high
;not found
; ok
11-9
Keyboard Input
;
Decr. debounce count
;
CheckDebounce:
dec
l
bnz
$KeyScanLoop
;
KeyFound:
mov
a,h
mov
KeyNumber,a
set1
cy
ret
$ej
;======================================================================
;
Module name: INTTM3 watch timer interval time interrupt
;
;
Interrupted every 15.6 ms
;
;
DESCRIPTION:
;
Set watch time variables
;
;
OPERATION:
;
. Flip the HalfSecondFlag.
;
. If HalfSecondFlag = 0, then incr. seconds.
;
. If Seconds = 60, incr. minutes.
;
. If Minutes = 60, incr. Hours.
;
. If Hours = 24, incr. days.
;
;======================================================================
public
Watch_timer
Watch_timer:
;
;
Test 0.5-second flag
;
bf
WTIF,$wt20
;not yet
clr1
WTIF
;
;
0.5 second passed
;
bf
HalfSecondFlag,$wt10 ;0.5 second passed
;
Clear
0.5-second flag
clr1
HalfSecondFlag
;
inc
Interval_Seconds
inc
cmp
bc
mov
Seconds
Seconds,#60
$wt20
Seconds,#0
inc
cmp
bc
mov
Minutes
Minutes,#60
$wt20
Minutes,#0
inc
cmp
bc
mov
Day
inc
cmp
bc
Hours
Hours,#24
$wt20
Hours,#0
;
;
;
11-10
Days
Days,#30
$wt20
Keyboard Input
br
$wt20
set1
HalfSecondFlag
;
wt10:
wt20:
reti
;======================================================================
end
#pragma interrupt INTTM3 WatchTimer RB1
11-11
Keyboard Input
C Language Program: Example of Key Matrix
/*;************************************************************************
;
;
File name: key.c
;
Date: 10/27/97
;****************************************************************************
;
Description:
;
;
;The example program is a key input module that inputs signals from a 4 x 4 key matrix.
;The keys can be pressed successively, and two or more keys can
;be pressed simultaneously. In this example, the higher 4
;bits of port 3 (P34 - P37) are used as key scan signals, and port 11 (P4 for µPD78054 or µPD78078)
;is used for key return signals. As the pullup resistor of port 11 for key return, the
;internal pullup resistor set by software is used.
;
;Port 11 of the K0 series has a function to detect the falling edges of the
;eight port pins in parallel. If port 11 is used for key return signals,
;therefore, the standby mode can be released through detection of a falling
;edge by key input.
;
;The input keys are stored to RAM on a bit/key basis. The RAM bit
;corresponding to a pressed key is set and the bit corresponding to a released
;key is cleared. By testing the RAM data on a 1-bit basis starting
;from the first bit, the key status can be checked. To absorb key debouncing,
;the key is assumed to be valid when four successive key codes coincide with a
;given code. For example, if a key code is sampled every 16 ms, debouncing of
;48 ms to 64 ms can be absorbed.
;
; Key number:
;
0 = P114 + P34
;
1 = P114 + P35
;
2 = P114 + P36
;
3 = P114 + P37
;
;
4 = P115 + P34
;
5 = P115 + P35
;
6 = P115 + P36
;
7 = P115 + P37
;
;
8 = P116 + P34
;
9 = P116 + P35
;
10 = P116 + P36
;
11 = P116 + P37
;
;
12 = P117 + P34
;
13 = P117 + P35
;
14 = P117 + P36
;
15 = P117 + P37
;
;
Port 4 is used instead of port 11 for µPD78054 or µPD78078.
;
;======================================================================
;
The system has a main system clock (5 MHz) and a subsystem clock (32.768 kHz).
;
The LCD and watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock, but when a key is depressed,
;
the main system clock is activated.
;======================================================================*/
#include "define.h"
#define D0541
//for µPD78054 and µPD78078
//;
//;
Time of day by watch timer mode
//;
11-12
Keyboard Input
__sreg
unsigned char Seconds; //Seconds
__sreg
unsigned char Minutes; //Minutes
__sreg
unsigned char Hours;//Hours
__sreg
unsigned char Days;//Days
__sreg
unsigned char KeyNumber;
bit HalfSecondFlag; //1/2-second toggle flag
bit KeyOnFlag; // key-on flag if it is 1
void KeyScan (void);
/*;======================================================================
;
Main
;======================================================================*/
void main ()
{
//;
//;
Oscillation mode select register
//;
. Does not use divider circuit
//;
OSMS = 0b00000001;
// select 5 MHz
PMK0 = 0;
// for DDB Board - INTP0 has to be set
/*;====================================================================
;
Key Return mode register (KRM)
;
;
0 0 0 0 0 1 0 0
;
| | | | | | | |__ KRM.0 (= 0, Not detected key return signal)
;
| | | | | | |____ KRM.1 (= 1, Standby mode release enabled)
;
| | | | | |______ KRM.2 (= 1, Select P114-P117 as key return signal port)
;
| | | | |________ KRM.3 (= 0, Select P114-P117 as key return signal port)
;
| | | |__________ KRM.4 (= 0, Reserved)
;
| | |____________ KRM.5 (= 0, Reserved)
;
| |______________ KRM.6 (= 0, Reserved)
;
|________________ KRM.7 (= 0, Reserved)
;
;
If µPD78054 or µPD78078, KRM.2 and KRM.3 cannot be defined.
;
;====================================================================*/
KRM = 0b00000100;
//; Set scan ports
PM3 = 0b11110000; //P34-P37, output
P3 = 0b00000000; //Set P34-P37 to low
//; Set sense ports
#if D054
#else
PM11 = 0b11110000; //P114-P117 as input
#endif
//;
//;
Pullup resistor option on P11
//;
#if D054
PUOL = 0b00010000;
#else
PUOH = 0b00001000;
#endif
11-13
Keyboard Input
/*;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 1 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 1, Select 32.768-kHz subsystem clock
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================*/
TCL2 = 0b00010000;
/*;====================================================================
;
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch Operating Mode Selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler operation control enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for Watch flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)
;
;====================================================================*/
TMC2 = 0b01010110;
//;
//;
Clear time variables
//;
Seconds = 0;
Minutes = 0;
Hours = 0;
Days = 0;
//;
Clear IRQ flags
TMIF3 = 0;
//;
Enable watch timer interval timer
TMMK3 = 0;
EI ();
while (TRUE)
{
//;
//;
//;
Set to normal operation
PCC = 0B00000000;
//;
//;
//;
Scan keyboard - every 15.6 ms will wake it up
NOP();
NOP();
STOP();
NOP();
KeyScan();
if (KeyOnFlag)
{
//
// Service the key (user-defined function)
11-14
Keyboard Input
//
}
}
}
/*;======================================================================
;
Key scan module
;
;
The key matrix is 4 x 4. There are four scan ports (P34-P37) and
;
four key return signal ports (P114-P117).
;
Debounce count is set to 4.
;
;
Key number:
;
0 = P114 + P34
;
1 = P114 + P35
;
2 = P114 + P36
;
3 = P114 + P37
;
4 = P115 + P34
;
5 = P115 + P35
;
6 = P115 + P36
;
7 = P115 + P37
;
8 = P116 + P34
;
9 = P116 + P35
;
10 = P116 + P36
;
11 = P116 + P37
;
12 = P117 + P34
;
13 = P117 + P35
;
14 = P117 + P36
;
15 = P117 + P37
;
;
Return:
;
cf = 1 if a key is depressed
;
and KeyNumber with key number
;
;
cf = 0 if no key is depressed
;
;
Registers:
;
a = Scratch
;
b = Total row or column numbers
;
c = Sense port
;
d = Row x 4 + column
;
e = Column port
;
h = Current key number
;
l = Number of debounces
;
x = Find a row
;======================================================================*/
void KeyScan (void)
{
#asm
$set (D054)
;
;
Find a key
;
push
ax
push
bc
push
de
push
hl
clr1
_KeyOnFlag
mov
h,#0ffh
;no key flag
mov
l,#3
KeyScanLoop:
and
$if (D054)
mov
P3,#11110000b
a,P4
11-15
Keyboard Input
$else
mov
a,P11
and
cmp
bz
a,#11110000b
a,#11110000b
$NotFound
;mask low nibble
;all high
;no key depressed
mov
mov
mov
mov
c,a
d,#0
x,#00010000b
b,#4
;key number
;find a row
;4 rows
$endif
;
CheckRow:
mov
a,x
and
a,c
bz
$RowFind
; shift to left
mov
a,x
clr1
cy
rol
a,1
mov
x,a
; update row * column
mov
a,d
add
a,#4
mov
d,a
;
dbnz
b,$CheckRow
;
;
Not Found
;
NotFound:
push
hl
push
de
push
bc
push
ax
ret
;
;
Row find. Find column.
;
d = row x column
;
x = row position
;
RowFind:
mov
e,#00000001b
mov
b,#4
CheckCol:
mov
a,e
mov
p3,a
$if (D054)
mov
a,P4
$else
mov
a,P11
$endif
and
a,x
bnz
$ColFind
; shift to left
clr1
cy
mov
a,e
rol
a,1
mov
e,a
;
;
Incr. key number
;
inc
d
dbnz
b,$CheckCol
br
NotFound
11-16
;find the row
;find a column
;4 columns
;set to high
;not found
Keyboard Input
;
ColFind:
mov
cmp
bz
;
;
;
a,d
a,h
$CheckDebounce
; ok
Restart key scan
mov
h,a
;
;
Decr. debounce count
;
CheckDebounce:
dec
l
bnz
$KeyScanLoop
;
KeyFound:
mov
a,h
mov
_KeyNumber,a
set1
_KeyOnFlag
push
hl
push
de
push
bc
push
ax
ret
#endasm
}
/*;======================================================================
;
Module name: INTTM3 Watch Timer Interval Time Interrupt
;
;
Interrupted every 15.6 ms
;
;
DESCRIPTION:
;
.Set watch time variables
;
;
OPERATION:
;
. Flip the HalfSecondFlag.
;
. If HalfSecondFlag = 0, then incr. seconds.
;
. If seconds == 60, incr. minutes.
;
. If minutes == 60, incr. hours.
;
. If hours == 24, incr. days.
;
;======================================================================*/
void WatchTimer ()
{
//;
//;
Test 0.5-second flag
//;
if ( !WTIF) return;
//;
WTIF = 0;
//;
//;
0.5 second passed
//;
if ( !HalfSecondFlag)
{
HalfSecondFlag = 1;
return;;
}
//;
HalfSecondFlag = 0;
//;
Seconds++;
if (Seconds < 60) return;;
11-17
Keyboard Input
Seconds = 0;
Minutes++;
if (Minutes < 60) return;;
Minutes = 0;
Hours++;
if (Hours < 24) return;;
Hours = 0;
Days++;
}
l
11-18
Watch Timer Function
12
Applicable K0 Devices
•
•
•
•
•
•
•
•
•
•
•
•
µPD7801xF
µPD7801xH
µPD7805x
µPD7805xF
µPD78005x
µPD7807x
µPD78070A
µPD7806x
µPD78030x
µPD7804xH
µPD7804xF
µPD78020x
Description
The watch timer of the K0 family has a function that causes the timer to overflow every 0.5 or
0.25 second by using the main system clock (4.19 MHz) or subsystem clock (32.768 kHz) as
the clock source. An interval timer function allows a user to set the interval time to check the
watch timer overflow flag (WTIF).
The watch timer function is set by timer clock select register 2 (TCL2) and the watch timer mode
control register (TMC2). Because there is no interrupt vector for a watch timer overflow
condition, the WTIF is either polled constantly or checked from the INTTM3 (watch time interval
time overflow interrupt) service routine. The watch timer function contains these registers:
•
•
Timer clock select register 2 (Figure 12-1)
Watch timer mode control register (Figure 12-2)
Figure 12-1. Timer Clock Select Register 2 (TCL2)
7
6
5
4
3
2
1
0
TCL27
TCL26
TCL25
TCL24
0
TCL22
TCL21
TCL20
Bit(s)
Name
Description
2–0
TCL22 – TCL20
Watchdog timer count clock select
4
TCL24
Watch timer count clock selection
0 = fx/27 (39.1 kHz)
1 = fxt (32.768 kHz)
7–5
TCL27 – TCL25
Buzzer output frequency selection
12-1
Watch Timer Function
Figure 12-2. Watch Timer Mode Control Register (TMC2)
7
6
5
4
3
2
1
0
0
TMC26
TMC25
TMC24
TMC23
TMC22
TMC21
TMC20
Bit(s)
Name
Description
0
TMC20
Operating mode
0 = Normal (fw/214)
1 = Fast feed (fw/25)
1
TMC21
Prescaler
0 = Clear after operation stop
1 = Operation enable
2
TMC22
5-bit counter
0 = Clear
1 = Enable
3
TMC23
WTIF flag set
0 = 214/fw (0.5 sec)
1 = 213/fw (0.25 sec)
6–4
TMC26–TMC24
Prescaler interval timer selection at fxx = 4.19 MHz
0 0 0 = 24/fw (488 µs)
0 0 1 = 25/fw (977 µs)
0 1 0 = 26/fw (1.95 ms)
0 1 1 = 27/fw (3.91 ms)
1 0 0 = 28/fw (7.82 ms)
1 0 1 = 29/fw (15.6 ms)
Other = prohibited
Example Program
The watch timer example program demonstrates the watch timer function in the K0 family.
Figure 12-3 is the program flowchart. The timer clock select register (TCL2) is set to fx/27 (39.1
kHz) as the watch timer count clock selection. The watch timer mode control register (TMC2) is
set to 15.6-ms prescaler interval time, the WTIF flag to 0.5 second, and the operating mode to
normal.
When the interval timer interrupt (INTTM3) occurs, the interrupt service routine checks the
WTIF (0.5-second overflow flag). If WTIF is set, flag and time values such as second, minute,
hour, and day are updated.
12-2
Watch Timer Function
Figure 12-3. Flowchart of Watch Timer Example Program
Watch timer function
entry
INTT3 Prescaler
interval time interrupt
entry.
Initialization:
• Set fx/27 as watch
timer count clock in
TCL2.
• Set prescaler interval
time = 15.6 ms, watch
flag set time = 0.5 second,
and normal operation
mode (flag set at fw/214).
WTIF = 1?
No
Yes
Return
WTIF = 0
Wait
here
Yes
No
1 second passed?
No
Seconds++
Set 1/2-second
passed flag.
Seconds ≥ 60?
Return
Yes
Return
Seconds = 0
Minutes++
Minutes ≥ 60?
Yes
Minutes = 0
Hours++
No
Hours ≥ 24?
Return
Yes
Hours = 0
Days++
No
Return
97YL-0324C (12/97)
12-3
Watch Timer Function
Assembly Language Program: Watch Timer Example
;****************************************************************************
;
File name: TOD.ASM
;
Date: 10/15/97
;****************************************************************************
;
Description:
;
; This program demonstrates the watch timer in the µPD78308 microcontroller.
; The watch timer control registers (TCL2 and TMC2) are used to configure
; the watch timer function.
;
; The time base resolution of the watch timer is selectable as 0.25
; or 0.5 second when the 4.19 MHz (standard: 4.194304 MHz) main system clock is
; used.
;
; Since there is no interrupt vector for the 0.5-second interval, the watch
; timer's interval timer interrupt (INTT3) should be used to check whether
; 0.5 second has passed.
;=============================================================================
; The sample program will set minute, hour, and day with the 0.5-second time base.
; The interval time is set to 15.6 ms. The interval time interrupt service
; routine is used to check the 0.5-second flag (WTIF).
;======================================================================
;
for only DDB-K0070A
;
$set (DDB)
$set (D054)
;======================================================================
;
DebugFlag set
1
;======================================================================
;
Equates
;======================================================================
;======================================================================
;
saddr Area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
;
;
Time of day by watch timer mode
;
Seconds:
ds
1
;Seconds
Minutes:
ds
1
;Minutes
Hours:
ds
1
;Hours
Days:
ds
1
;Days
;======================================================================
;
Even boundary pair
;======================================================================
dseg
saddrp
;======================================================================
;
Bit segment
;======================================================================
bseg
HalfSecondFlag
dbit
;1/2-second toggle flag
;======================================================================
;
;
Internal High RAM allocation
;
dseg
IHRAM
ds
20h
12-4
Watch Timer Function
Stack:
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
org
dw
01Eh
Watch_timer
; Watch timer interval time interrupt
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
public
ResetStart
ResetStart:
di
;Disable interrupt
;
;
Select register bank 0
;
sel
RB0
;Select register bank 0 for background
;
;
Oscillation mode select register
;
. Does not use divider circuit
;
$if (D054)
mov
OSMS,#00000001b
$endif
;
;
Set stack pointer (IHMEM + 20H)
;
;;
movw
SP,#Stack
;Stack pointer
movw
SP,#0fe00h
;Stack pointer
;
;
Init. Watch timer control register
;
;;
Call
!InitWatchTimer
;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 0 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 0, Select 4.19 MHz/27)
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================
mov
TCL2,#00000000b
;====================================================================
;
;
TMC2 - Watch timer mode control register
;
12-5
Watch Timer Function
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch Operating mode selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler operation control enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for watch flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)
;
;====================================================================
mov
TMC2,#01010110b
;
;
Clear time variables
;
mov
Seconds,#0
mov
Minutes,#0
mov
Hours,#0
mov
Days,#0
;
;
Enable INTP0 for DDB-K0070A
;
$if (DDB)
clr1
PMK0
$endif
;
Clear IRQ flags
clr1
TMIF3
;
Enable watch timer internal timer
clr1
TMMK3
ei
;
main_loop:
nop
br
$main_loop ;string received flag = 0
$ej
;======================================================================
;
Module name: INTTM3 wWtch timer interval time interrupt
;
;
DESCRIPTION:
;
Set watch time variables
;
;
OPERATION:
;
. Flip the HalfSecondFlag.
;
. If HalfSecondFlag = 0, then incr. seconds.
;
. If seconds = 60, incr. minutes.
;
. If minutes = 60, incr. hours.
;
. If hours
= 24, incr. days.
;
;======================================================================
public
Watch_timer
Watch_timer:
;
;
Test 0.5-second flag
;
bf
WTIF,$wt20
;not yet
clr1
WTIF
;
;
0.5 second passed
;
bf
HalfSecondFlag,$wt10 ;1/2 second passed
;
Clear half-second flag
12-6
Watch Timer Function
clr1
HalfSecondFlag
inc
cmp
bc
mov
Seconds
Seconds,#60
$wt20
Seconds,#0
inc
cmp
bc
mov
Minutes
Minutes,#60
$wt20
Minutes,#0
inc
cmp
bc
mov
Day
inc
cmp
bc
Hours
Hours,#24
$wt20
Hours,#0
br
$wt20
set1
HalfSecondFlag
;
;
;
;
Days
Days,#30
$wt20
;
wt10:
wt20:
reti
;======================================================================
end
_
12-7
Watch Timer Function
C Language Program: Watch Timer Example
#pragma interrupt INTTM3 WatchTimer RB1
/*;****************************************************************************
;
File name: TOD.C
;
Date: 10/15/97
;****************************************************************************
;
Description:
;
; This program demonstrates the watch timer in the µPD78308 microcontroller.
; The watch timer control registers (TCL2 and TMC2) are used to configurate
; the watch timer function.
;
; The time base resolution of the watch timer is selectable as 0.25
; or 0.5 seconds when the 4.19 MHz (standard: 4.194304 MHz) main system clock is
; used.
;
; Since there is no interrupt vector for the 0.5-second interval, the watch
; timer's interval time interrupt (INTT3) should be used to check whether
; 0.5 second has passed.
;=============================================================================
; The sample program will set minute, hour and day with the 0.5-second time base.
; The interval time is set to 15.6 ms. The interval timer is used to
; check 0.5-second flag, (WTIF).
;============================================================================*/
#include "define.h"
//;
//;
Time of day by watch timer mode
//;
__sreg
unsigned char Seconds; //Seconds
__sreg
unsigned char Minutes; //Minutes
__sreg
unsigned char Hours;
//Hours
__sreg
unsigned char Days;
//Days
bit HalfSecondFlag;
//1/2-second toggle flag
//;======================================================================
//;
Main
//;======================================================================
void main()
{
//;
//;
Oscillation mode select register
//;
. Does not use divider circuit
//;
OSMS = 0b00000001;
// select 5 MHz
PMK0 = 0;
// for DDB BOARD - INTP0 has to be set
/* ;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 0 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 0, Select 4.19 MHz/27)
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================*/
TCL2 = 0b00000000;
12-8
Watch Timer Function
/*;====================================================================
;
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch operating mode selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler operation control enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for watch flag set time)
;
| | | |__________ TMC2.4(= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| | |____________ TMC2.5(= 0, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| |______________ TMC2.6(= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
|________________ TMC2.7(Reserved = 0)"
)
;
;====================================================================*/
TMC2 = 0b01010110;
//;
//;
Clear time variables
//;
Seconds = 0;
Minutes = 0;
Hours = 0;
Days = 0;
//;
Clear IRQ flags
TMIF3 = 0;
//;
Enable watch timer interval timer
TMMK3 = 0;
EI();
//;
while (TRUE);
}
/*;======================================================================
;
Module name: INTTM3 watch timer interval time interrupt
;
;
DESCRIPTION:
;
Set watch time variables
;
;
OPERATION:
;
. Flip the HalfSecondFlag.
;
. If HalfSecondFlag = 0, then incr. seconds.
;
. If seconds = 60, incr. minutes.
;
. If minutes = 60, incr. hours.
;
. If hours
= 24, incr. days.
;
;======================================================================*/
void WatchTimer()
{
//;
//;
Test 0.5-second flag
//;
if ( !WTIF) return;
//;
WTIF = 0;
//;
//;
0.5 second passed
//;
if ( !HalfSecondFlag)
{
HalfSecondFlag = 1;
return;;
}
//;
12-9
Watch Timer Function
HalfSecondFlag = 0;
//;
Seconds++;
if (Seconds < 60) return;;
Seconds = 0;
Minutes++;
if (Minutes < 60) return;;
Minutes = 0;
Hours++;
if (Hours < 24) return;;
Hours = 0;
Days+;
}
12-10
Standby Function
13
Applicable Devices
•
•
•
•
•
•
•
•
•
•
•
•
µPD7801xF
µPD7801xH
µPD7805x
µPD7805xF
µPD78005x
µPD7807x
µPD78070A
µPD7806x
µPD78030x
µPD7804xH
µPD7804xF
µPD78020xl
Description
The standby function is designed to decrease system power consumption. The microcontroller
has two power-saving modes: HALT and STOP.
HALT Mode
The HALT mode is intended to stop the CPU operation clock while the system clock continues
oscillation. The HALT mode is valid to restart immediately upon interrupt request and to carry
out intermittent operations such as in watch applications. The HALT instruction can be used
with either the main system clock or the subsystem clock.
HALT Mode Settings and Operation Status
Parameter
Main System Clock
Clock generator
Subsystem Clock
Both main and subsystem clocks can be in oscillation.
CPU
Operation stops
Port
Status before HALT mode setting is held
16-bit timer/event
counter
Operable
Operable when watch counter timer output
with fxt is selected as count clock
8-bit timer/event
counter
Operable
Operable when TI1 and TI2 are selected
as count clock
Watch timer
Operable if fxx/27 selected as count clock
Operable if fxt selected as count clock
Watchdog timer
Operable if fxx/27 selected as count clock
Operation stops
A/D converter
Operable
Operation stops
Serial interface
Operable
Operable at external SCK
7
LCD controller/driver
Operable if fxx/2 selected as count clock
Operable if fxt selected as count clock
INTP0
Operable when a clock (fxx/25, fxx/26, fxx/
27) for the peripheral hardware is selected
as sampling clock
Operation stops
INTP1 to INTP5
Operable
13-1
Standby Function
There are four ways to clear HALT mode:
1.
2.
3.
4.
Clear upon unmasked interrupt request.
Clear upon non-maskable interrupt request.
Clear upon unmasked test input.
Clear upon RESET input.
STOP Mode
When the STOP instruction is executed, the main system clock oscillator stops. In the STOP
mode, CPU current consumption can be considerably decreased. Data memory low-voltage
hold (down to VDD = 1.8 V) is possible. Thus, the STOP mode is effective to hold data memory
contents with ultra-low current consumption. Because this mode can be cleared upon interrupt
request, it enables intermittent operations to be carried out. However, because a wait time is
necessary to secure oscillator stabilization after the STOP mode is cleared, select the HALT
mode if it is necessary to start processing immediately upon interrupt request.
The STOP mode can be used only when the system operates with the main system clock
(subsystem clock oscillation cannot be stopped). When proceeding to the STOP mode, be sure
to stop the peripheral hardware operation and execute the STOP instruction.
STOP Mode Settings and Operation Status
Parameter
With Subsystem Clock
Clock generator
CPU
Only main system clock stops oscillation
Operation stops
Port
16-bit timer/event counter
8-bit timer/event counter
Without Subsystem Clock
Operation stops
Status before STOP mode setting is held
Operable when watch timer output with fxt
is selected as count clock
Operation stops
Operable when TI1 and TI2 are selected as count clock
Watch timer
Operable if fxt is selected as count clock
Watchdog timer
Operation stops
Operation stops
A/D converter
Operation stops
Operation stop.
Serial interface
Operable at external SCK
Operable at external SCK
LCD controller/driver
Operable if Fxt is selected as count clock
INTP0
INTP1 to INTP5
Operation stops
Operation impossible
Operable
There are two ways to clear the STOP mode:
1. Release by unmasked interrupt request
2. Release by RESET input
In any mode, the contents of the register, flag, and data memory just before standby mode
setting are retained. The input/output port output latch and output buffer status are also held.
13-2
Standby Function
Standby Function Control Register
After the STOP mode is cleared upon interrupt request, wait time is controlled with the
oscillation stabilization time select register (OSTS). The default stabilization time is 26.2 ms
(MCS = 1). The wait time after STOP mode clear does not include the time from STOP mode
clear to clock oscillation start, regardless of clearance by the RESET input or by interrupt
generation.
Application Program
This program demonstrates standby functions HALT and STOP mode in the K0 family. Refer to
the control register (Figure 13-1) and the flowchart (Figure 13-2). To measure power
consumption for about 30 seconds in each mode, the program runs as follows:
1. Normal mode operation with system main clock (5.00 MHz) and subsystem clock
2. HALT mode operation with system main clock (5.00 MHz) and subsystem clock
3. STOP mode operation with subsystem clock (32.768 kHz)
Each mode runs with a toggle port to indicate the current mode of operation.
1. P1.0 = Normal mode
2. P1.1 = HALT mode
3. P1.2 = STOP mode
To run the STOP mode, a subsystem clock (32.768 kHz) must be installed.
Figure 13-1. Processor Clock Control Register (PCC) Setup for Each Mode
7
6
5
4
3
2
1
0
MCC
FRC
CLS
CSS
0
PCC2
PCC1
PCC0
Bit(s)
Name
Description
2–0
PCC2–PCC0
CPU clock
4
CSS
0 0 0 = fx (0.4 µs)
CPU clock
0 = fx (Normal, STOP)
1 = fxt (HALT)
5
CLS
Read CPU clock status
0 = Main system clock
6
FRC
Feedback resistor
0 = Internal
7
MCC
Main system clock
0 = Oscillation possible (Normal, STOP)
1 = Oscillation stopped (HALT)
13-3
Standby Function
Figure 13-2. Flowchart of the Program Example of Standby Modes
Standby mode
operation; demo
software entry.
Initialization:
• Set fx/27 as watch timer
count clock in TCL2
• Set prescaler interval
time = 15.6 ms, 0.5 second
for watch flag set time, and
normal operation mode (flag
set at fw/214).
• Set watch timer mode
register to subsystem clock.
• Set LCD mode register clock
selection to subsystem clock.
Interval_Seconds = 0
PCC = 0x00
Toggle P1.0
No
Interval_Seconds ≥
30?
Yes
Interval_Seconds = 0.
• Set PCC register to run
only with subsystem clock.
Execute HALT instruction.
Toggle P1.1
No
Interval_Seconds ≥
30?
Yes
Interval_Seconds = 0.
• Set PCC register to run
with main system clock.
Execute STOP instruction.
Toggle P1.2
No
Interval_Seconds ≥
30?
Yes
97YL-0326C (12/97)
13-4
Standby Function
Assembly Language Program: Example of Standby Modes
;****************************************************************************
;
File name: STANDBY.ASM
;
Date: 10/17/97
;****************************************************************************
;
Description:
;
; This program demonstrates the standby HALT and STOP modes
; in the K0 family.
;
; The program is set in three modes to check power consumption:
;
1. Normal operation with system main clock (5 MHz) for about 30 seconds.
;
2. HALT mode operation with system main clock (5 MHz) for about 30 seconds.
;
3. STOP mode operation with subsystem clock (32.768 kHz) for about 30 seconds.
; Each time the mode is switched, toggle a port associated with
; the mode.
;
P1.0 = Normal mode
;
P1.1 = HALT mode
;
P1.2 = STOP mode
;
;
By toggling the port, the user knows which mode is currently set to measure
;
power consumption.
;
To run the STOP mode, the subsystem clock (32.768 kHz) must be
;
operational.
;
;======================================================================
;
for only DDB-K0070A
;
$set(DDB)
$set(D054)
;======================================================================
;
DebugFlag set
1
;======================================================================
;
Equates
;======================================================================
;======================================================================
;
saddr area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
;
;
Time of day by watch timer mode
;
Interval_Seconds:
ds
1
;Interval Seconds
Seconds:
Minutes:
Hours:
Days:
ds
ds
ds
ds
1
1
1
1
;Seconds
;Minutes
;Hours
;Days
;======================================================================
;
Even boundary pair
;======================================================================
dseg
saddrp
;======================================================================
;
Bit segment
;======================================================================
bseg
HalfSecondFlag
dbit
;1/2-second toggle flag
;======================================================================
13-5
Standby Function
;
;
Internal High RAM allocation
dseg
ds
IHRAM
20h
Stack:
$ej
;======================================================================
;
Reset vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
org
dw
01Eh
Watch_timer
; Watch timer interval time interrupt
$ej
;======================================================================
;
Main
;======================================================================
Main
cseg
at 80h
public
ResetStart
ResetStart:
di
;Disable interrupt
;
;
Select register bank 0
;
sel
RB0
;Select register bank 0 for background
;
;
Oscillation mode select register
;
. Does not use divider circuit
;
mov
OSMS,#00000001b
;
;
Set stack pointer(IHMEM + 20H)
;
;;
movw
SP,#Stack
;Stack ptr
movw
SP,#0fe00h
;Stack ptr
;
;
Init. watch timer control register
;
;;
Call
!InitWatchTimer
;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 1 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 1, Select 32.768 kHz subsystem clock)
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================
mov
TCL2,#00010000b
;====================================================================
;
;
TMC2 - Watch timer mode control register
;
13-6
Standby Function
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch operating mode selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler operation control-enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for watch flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)"
)
;
;====================================================================
mov
TMC2,#01010110b
;
;
Clear time variables
;
mov
Seconds,#0
mov
Minutes,#0
mov
Hours,#0
mov
Days,#0
;
;
Enable INTP0 for DDB-K0070A
;
$if(DDB)
clr1
PMK0
$endif
;
Clear IRQ flags
clr1
TMIF3
;
Enable watch timer internal timer
clr1
TMMK3
;
;
SET P1 to all output and low
;
mov
PM1,#0
MOV
P1,#0
ei
;
main_loop:
;======================================================================
;
Normal operation
;
Main system clock with subsystem clock operation
;======================================================================
NormalMode:
mov
PCC,#00000000B
mov
Interval_Seconds,#00
;
NormalModeLoop:
cmp
Interval_Seconds,#30
bnc
$HaltMode
;run for HALT mode test
;
Toggle p1.0
mov
P1,#001b
nop
mov
P1,#000b
br
NormalModeLoop
;======================================================================
;
HALT operation
;
Running with only subsystem clock operation
;=====================================================================
HaltMode:
mov
PCC,#10010000B
mov
Interval_Seconds,#00
;
HaltModeLoop:
cmp
Interval_Seconds,#30
13-7
Standby Function
bnc
$StopMode
; halt
HALT
nop
nop
; Toggle p1.1
mov
P1,#010b
nop
mov
P1,#000b
br
HaltModeLoop
;======================================================================
;
STOP operation
;
Main system clock stopped and with subsystem clock operation
;======================================================================
StopMode:
mov
PCC,#00000000B
mov
Interval_Seconds,#00
; halt
StopModeLoop:
cmp
Interval_Seconds,#30
bnc
$Done
;done
STOP
nop
nop
;
mov
nop
mov
br
;
;
;
Done:
P1,#100b
P1,#000b
StopModeLoop
Loop back to top
br
$main_loop
$ej
;======================================================================
;
Module name: INTTM3 Watch timer Interval Time Interrupt
;
;
DESCRIPTION:
;
Set watch time variables
;
;
OPERATION:
;
. Flip the HalfSecondFlag
;
. If HalfSecondFlag = 0, then incr. seconds.
;
. If seconds = 60, incr. minutes.
;
. If minutes = 60, incr. hours.
;
. If hours
= 24, incr. days.
;
;======================================================================
public
Watch_timer
Watch_timer:
;
;
Test 0.5-second flag
;
bf
WTIF,$wt20
;not yet
clr1
WTIF
;
;
.5 second passed
;
bf
HalfSecondFlag,$wt10
;1/2 second passed
;
Clear half-second flag
13-8
Standby Function
clr1
HalfSecondFlag
inc
Interval_Seconds
inc
cmp
bc
mov
Seconds
Seconds,#60
$wt20
Seconds,#0
inc
cmp
bc
mov
Minutes
Minutes,#60
$wt20
Minutes,#0
inc
cmp
bc
mov
Day
inc
cmp
bc
Hours
Hours,#24
$wt20
Hours,#0
br
$wt20
set1
HalfSecondFlag
;
;
;
;
Days
Days,#30
$wt20
;
wt10:
wt20:
reti
;======================================================================
end
_
13-9
Standby Function
C Language Program: Example of Standby Modes
#pragma interrupt INTTM3 WatchTimer RB1
/*;****************************************************************************
;
File name: STANDBY.C
;
Date: 10/15/97
;****************************************************************************
;
Description:
;
; This program demonstrates the standby HALT and STOP modes
; in the K0 family.
;
; The program is set in three modes to check power consumption.
;
1. Normal operation with system main clock (5 MHz) for about 30 seconds.
;
2. HALT mode operation with system main clock (5 MHz) for about 30 seconds.
;
3. STOP mode operation with subsystem clock (32.768 kHz) for about 30 seconds.
; Each time the mode is switched, toggle a port associated with
; the mode.
;
P1.0 = Normal mode
;
P1.1 = HALT mode
;
P1.2 = STOP mode
;
;
By toggling the port, the user knows which mode is currently set to measure
;
power consumption.
;
To run the STOP mode, the subsystem clock (32.768 kHz) must be
;
operational.
;
;=============================================================================
;
; The sample program will set minute, hour, and day with a 0.5-second time base.
; The interval time is set to 15.6 ms. The interval timer is used to
; check the 0.5-second flag, with WTIF set. If so, increment the 0.5 second count.
;
;============================================================================*/
#include "define.h"
//;
//;
Time of day by watch timer mode
//;
__sreg
unsigned char Interval_Seconds;
//Seconds
__sreg
unsigned char Seconds;
//Seconds
__sreg
unsigned char Minutes;
//Minutes
__sreg
unsigned char Hours;
//Hours
__sreg
unsigned char Days;
//Days
bit HalfSecondFlag;
//1/2-second toggle flag
//;======================================================================
//;
Main
//;======================================================================
void main()
{
//;
//;
Oscillation mode select register
//;
. Does not use divider circuit
//;
OSMS = 0b00000001;// select 5 MHz
PMK0 = 0;
// for DDB BOARD - INTP0 has to be set
/* ;====================================================================
13-10
Standby Function
;
TCL2 - Timer clock select register 2
;
;
x x x 1 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved))
;
| | | |__________ TCL2.4 (= 1, Select 32.768 kHz subsystem clock
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================*/
TCL2 = 0b00010000;
/*;====================================================================
;
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch operating mode selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler operation control enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for watch flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms, fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)"
)
;
;====================================================================*/
TMC2 = 0b01010110;
//;
//;
Clear time variables
//;
Seconds=0;
Minutes=0;
Hours=0;
Days= 0;
//;
Clear IRQ flags
TMIF3 = 0;
//;
Enable watch timer interval timer
TMMK3 = 0;
//;
PM1 = 0X00;
P1 = 0X00;
EI();
while(TRUE)
{
//
//
Normal mode
//
Main system clock with subsystem clock operation
//
PCC = 0b00000000;
Interval_Seconds = 0;
while (Interval_Seconds < 30)
{
P1.0 = 1;
P1.0 = 0;
}
//
//
Halt Mode
//
Set to run only with subsystem clock operation
//
13-11
Standby Function
PCC = 0b10010000;
Interval_Seconds = 0;
while(Interval_Seconds < 30)
{
HALT();
NOP();
NOP();
P1.1 = 1;
P1.1 = 0;
}
//
//
//
//
STOP mode
Main system clock stopped with subsystem clock operation
PCC = 0b00000000;
Interval_Seconds = 0;
while(Interval_Seconds < 30)
{
STOP();
NOP();
NOP();
P1.2 = 1;
P1.2 = 0;
}
}
}
/*;======================================================================
;
Module name: INTTM3 watch timer interval time interrupt
;
;
DESCRIPTION:
;
Set watch time variables
;
;
OPERATION:
;
. Flip the HalfSecondFlag.
;
. If HalfSecondFlag = 0, then incr. seconds.
;
. If seconds == 60, incr. minutes.
;
. If minutes == 60, incr. hours.
;
. If hours
== 24, incr. days.
;
;======================================================================*/
void WatchTimer()
{
//;
//;
Test 0.5-second flag
//;
if (!WTIF) return;
//;
WTIF = 0;
//;
//;
0.5 second passed
//;
if (!HalfSecondFlag)
{
HalfSecondFlag=1;
return;;
}
//;
HalfSecondFlag=0;
//;
Interval_Seconds++;
Seconds++;
13-12
Standby Function
if (Seconds < 60) return;;
Seconds = 0;
Minutes++;
if (Minutes < 60) return;;
Minutes = 0;
Hours++;
if (Hours < 24) return;;
Hours = 0;
Days++;
}
_
13-13
Standby Function
13-14
Software for the LCD Demo Application
14
Description
This program, written for an imaginary application, consists of four modules, each
demonstrating one of the following functions in the µPD78P0308 and µPD78F9418
microcontrollers.
•
•
•
•
LCD display function
Keyboard function
Time-of-day function
Power-saving mode
The demo program displays the message “NEC DEMO” on the LCD when the demo PC board
is powered. The message clears after about 3 seconds, and the time-of-day is displayed
(default time is 12:00). The time is updated every minute. Figure 14-1 is the program flowchart.
Edit the Time-of-Day
To change the time-of-day, press and hold the EDIT button for about 3 seconds until the hour
field blinks. Type in the new hour and press <ENTER>. If the entry is invalid, it will be rejected
and a valid number must be entered.
Once the hour field is set, the minute field blinks. Type in the new minute and press <ENTER>.
If the entry is invalid, a valid number must be entered. When the hour and minute have been
entered successfully, the new time-of-day will be displayed.
Power-Saving Mode
If no key is pressed, after about 30 seconds the system will go into the power-saving mode. The
system will be awakened from the power-saving mode when any key is pressed.
14-1
Software for the LCD Demo Application
Figure 14-1. Flowchart of the Demo Program
LCD demo program;
power up entry.
Display "NEC DEMO"
on the LCD 3 seconds.
Display time of day
("12:00").
Set 30-second time-out
counter.
Yes
No
Key depressed?
No
Time-out counter >
30 seconds?
Key = EDIT?
No
Yes
No
No
Press and hold
the key exceeded
3 seconds?
Power
saving
mode
Yes
Blink the HOUR field.
1 minute passed?
Yes
Entry for the HOUR field.
Update the time-of-day
display.
No
Is the HOUR field
entry valid?
Yes
Blink the MINUTE field.
Entry for the MINUTE field.
No
Is the MINUTE field
valid?
Yes
Display the new
hour and minute
97YL-0327C (2/98)
14-2
Software for the LCD Demo Application
Assembly Language Program: DEMO_CLK.ASM
;************************************************************************
;
;
File name: DEMO_CLK.ASM
;
Date: 1/29/98
;****************************************************************************
;
Description:
;
;
This program is to demonstrate the following functions in the K0/K0S family:
;
LCD display function
;
Keyboard function
;
Time-of-day function
;
Power down mode (standby mode)
;
Each module is written in a file that can be used as an application
;
note.
;
;======================================================================
;
The system has a main system clock (5 MHz) and a subsystem clock (32.768 kHz).
;
The LCD and Watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock and when a key is depressed, the
;
main system clock is activated.
;======================================================================
;
for only DDB-K0070A
;
$set(DDB)
;======================================================================
;
Extern reference
;======================================================================
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
EXTRN
DIGIT_0
DIGIT_1
DIGIT_2
DIGIT_3
DIGIT_4
DIGIT_5
DIGIT_6
DIGIT_7
DIGIT_8
DIGIT_9
KEY_SET
KEY_ENTER
KEY_CLEAR
KEY_STOP
KEY_SPARE1
KEY_SPARE2
extbit ASecondFlag
extrn
extrn
extrn
extrn
extrn
Hours
Interval_timer
KeyNumber
Minutes
Seconds
extrn
extrn
extrn
extrn
extrn
extrn
extrn
ClearLCDDisplay
DisplayTOD
DisplayAString
Init_LCD
Init_Key
Init_TOD
KeyScan
14-3
Software for the LCD Demo Application
;======================================================================
;
bit Area
;
FWA = 0fe20h
;======================================================================
bseg
DoneFlag dbit
;done
;======================================================================
;
saddr Area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
public Curr_Hours
public Curr_Minutes
public Curr_Field_Number
Curr_Hours:ds
1
Curr_Minutes:ds 1
Curr_Field_Number: ds 1;Field number
HOUR_FieldEQU
0
MINUTE_FieldEQU 1
SECOND_FieldEQU 2
;======================================================================
;
Even Boundary Pair
;======================================================================
dseg
saddrp
Curr_Field_Ptr: ds 2;Current working field ptr
;======================================================================
;
;Internal High RAM allocation
;
dseg
IHRAM
ds
20h
Stack:
$ej
;======================================================================
;
Reset Vector
;======================================================================
Vector
cseg
at 0000h
dw
ResetStart
org
extrn
dw
01Eh
Watch_timer
Watch_timer; Watch timer interval time interrupt
$ej
;======================================================================
;
MAIN
;======================================================================
Main
cseg
at 80h
public
ResetStart
ResetStart:
di
;Disable interrupt
;
;
Select Register Bank 0
14-4
Software for the LCD Demo Application
;
sel
;
;
;
;
;
;
;
;Select register bank 0 for background
Oscillation mode select register
. Does not use divider circuit
mov
;
;
;
;;
RB0
OSMS,#00000001b
Set stack pointer (IHMEM + 20H)
movw
movw
SP,#Stack
SP,#0fe00h
;Stack ptr
;Stack ptr
Init.
call
call
call
!Init_Key
!Init_TOD
!Init_LCD
;
;
Enable INTP0 for DDB-K0070A
;
$if(DDB)
clr1
PMK0
$endif
;
Clear IRQ flags
clr1
TMIF3
;
Enable Watch Timer Internal Timer
clr1
TMMK3
ei
;======================================================================
;
Display current time of day
;
Default: 12:00:00
;======================================================================
;
;
Set to normal operation
;
mov
PCC,#00000000B
;
;
Display a greeting message
;
'NEC DEMO'
;
movw
de,#NEC_DEMO
call
!DisplayAString
Wait5sec:
cmp
Seconds,#5
bnz
$Wait5sec
mov
Seconds,#0
;
;
Display Default Time of day(12:00:00)
call
!ClearLCDDisplay
call
!DisplayTOD
clr1
ASecondFlag
;
;
Go to STANDBY Mode and if wake up then
;
Check Second on
;
main_loop:
;
;
a second passed?
;
bf
ASecondFlag,$main10
clr1
ASecondFlag
;
;
Display Update
14-5
Software for the LCD Demo Application
;
call
;
;
;
main10:
;
;
;
!DisplayTOD
Set to Normal Operation
Scan keyboard - every 15.6 ms will wake it up
nop
nop
STOP
nop
;
;
;
Scan keys
;
call
!KeyScan
cf = 1 key detected cf = 0 no key found
bnc
$main_loop
;
;
;
call the Key service module
call
br
!ServiceKey
main_loop
;
;
Greeting message
;
NEC_DEMO:
db
'NEC_DEMO',0
;======================================================================
;
Service a key
;
;
Input: KeyNumber
;
;
;======================================================================
public
ServiceKey
ServiceKey:
mov
a,KeyNumber
cmp
a,#KEY_SET
bz
$DoSetTOD
;
Return
ret
;======================================================================
;
Set time of day.
;
Clear the LCD display.
;
Blink the HOUR field and wait for hours set.
;
Blink the MIMUTE field and wait for minutes set.
;
After a minutes is set exit.
;
If STOP then abort an action.
;
If CLEAR then start from Hour entry.
;======================================================================
BaseTime equ
156
;15.6 ms
DoSetTOD:
;
call
!ClearLCDDisplay
Display dash(--) and blink
extrn
Display_DASH
call
!Display_DASH
;
mov
14-6
Interval_timer,#5000/BaseTime
Software for the LCD Demo Application
extrn
call
SetBlink
!SetBlink
clr1
mov
mov
mov
movw
DoneFlag
Curr_Hours,#0
Curr_Minutes,#0
Curr_Field_Number,#0
Curr_Field_Ptr,#Curr_Hours
;
;
;
Retry:
;
;
;
Wait for key released
extrn
;
NextKeyLp:
call
srv_lop:
call
bnc
;
mov
mov
cmp
bz
;
;
Service
;
call
;
;
Done?
;
bf
;
;
Blink off
;
extrn
br
;
;
;
KeyServiceTable:
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
dw
;
;
;
KeyDigit0:
KeyDigit1:
KeyDigit2:
WaitKeyReleased
!WaitKeyReleased
!KeyScan
$srv_lop
a,KeyNumber
b,a
a,#KEY_CLEAR
$Retry
;retry
!Branch
DoneFlag,$NextKeyLp
ClearBlink
ClearBlink
KeyDigit0
KeyDigit1
KeyDigit2
KeyDigit3
KeyDigit4
KeyDigit5
KeyDigit6
KeyDigit7
KeyDigit8
KeyDigit9
KeySet
KeyEnter
KeyClear
KeySpare1
KeySpare2
14-7
Software for the LCD Demo Application
KeyDigit3:
KeyDigit4:
KeyDigit5:
KeyDigit6:
KeyDigit7:
KeyDigit8:
KeyDigit9:
mov
mov
cmp
bz
inc
cmp
bz
inc
cmp
bz
inc
cmp
bz
inc
cmp
bz
inc
cmp
bz
inc
cmp
bz
inc
cmp
bz
inc
cmp
bz
inc
cmp
bz
de10:
movw
xchw
mov
; value * 10 + unit
clr1
rolc
mov
clr1
rolc
clr1
rolc
add
add
mov
ret
b,#0
a,KeyNumber
a,#DIGIT_0
$de10
b
a,#DIGIT_1
$de10
b
a,#DIGIT_2
$de10
b
a,#DIGIT_3
$de10
b
a,#DIGIT_4
$de10
b
a,#DIGIT_5
$de10
b
a,#DIGIT_6
$de10
b
a,#DIGIT_7
$de10
b
a,#DIGIT_8
$de10
b
a,#DIGIT_9
$de10
ax,Curr_Field_Ptr
ax,hl
a,[hl]
CY
a,1
c,a
CY
a,1
CY
a,1
a,c
a,b
[hl],a
KeySet:
ret
KeyEnter:
cmp
bnz
Curr_Field_Number,#HOUR_Field
$enter10
mov
mov
a,Curr_Hours
Hours,a
; set
14-8
Software for the LCD Demo Application
movw
inc
ret
Curr_Field_Ptr,#Curr_Minutes
Curr_Field_Number
mov
mov
set1
ret
a,Curr_Minutes
Minutes,a
DoneFlag
; set
enter10:
KeyClear:
ret
KeySpare1:
KeySpare2:
ret
;======================================================================
;
Branch
;
Input:
;
ax = fwa of table entry
;
b = index #
;======================================================================
public
Branch
Branch:
;
index * 2
push
ax
mov
a,b
clr1
CY
rolc
a,1
mov
b,a
pop
ax
;
xch
a,x
add
a,b
add
a,b
xch
a,x
addc
a,#0
xchw
ax,hl
mov
a,[hl]
xch
a,x
mov
a,[hl+1]
xch
a,x
br
ax
;======================================================================
end
14-9
Software for the LCD Demo Application
Assembly Language Program: DEMO_LCD.ASM
;************************************************************************
;
;
File name: DEMO_LCD.ASM
;
Date: 1/29/98
;
;****************************************************************************
;
Description:
;
;
;The example program is an LCD Driver using 4-time-division and 1/2 bias.
;The program displays the time of day, HOURS:MINUTES;SECONDS.
;Default time is 12:00:00. Every 15.6 milliseconds the program checks whether a second has passed.
;If so, the display is updated.
;
;======================================================================
;
The system has a main system clock (5 MHz) and a subsystem clock (32.768 kHz).
;
The LCD and Watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock, but when a key is depressed,
;
the main system clock is activated.
;======================================================================
;
for only DDB-K0070A
;
$set(DDB)
;======================================================================
;
Equates
;======================================================================
;
;
LCD Display Memory
;
LCDBuffer EQU
0FA7Fh
SegmentSizeEQU
40
HOURS_10th_PtEQU
0FA7Fh
HOURS_Unit_PtEQU
HOURS_10th_Pt- 4
COLON1_Pt EQU
HOURS_Unit_Pt - 4
MINUTES_10th_Pt EQUCOLON1_Pt - 4
MINUTES_Unit_Pt EQUMINUTES_10th_Pt - 4
COLON2_Pt EQU
MINUTES_Unit_Pt - 4
SECONDS_10th_Pt EQUCOLON2_Pt -4
SECONDS_Unit_Pt EQUSECONDS_10th_Pt -4
AMPM_Pt
EQU
;offset 4 segments
0FA5Fh
;======================================================================
;======================================================================
;
;
External reference
;
extrn
Branch
extrn
Curr_Hours
extrn Curr_Minutes
extrn Days
extrn Hours
extrn Minutes
extrn Seconds
;======================================================================
;
bit
;======================================================================
bseg
public BlinkFlag
public BlinkOnOffFlag
14-10
Software for the LCD Demo Application
;
BlinkFlag dbit
; blink LCD display
BlinkOnOffFlagdbit; blink on/off(1 = on)
;======================================================================
;
saddr
;======================================================================
dseg
saddr
public BlinkOnType
public BlinkOffType
;
BlinkOnType:ds 1; blink ON
BlinkOffType:ds 1; blink OFF
;======================================================================
;======================================================================
cseg
;======================================================================
;
;
Default Time of day
;
Default:12:00:00
;
;======================================================================
public DisplayTOD
DisplayTOD:
mov
a,Hours
call
!DisplayHours
movw
mov
call
;
;
;
MINUTE: xx
mov
call
;
;
;
a,Minutes
!DisplayMinutes
(:)
movw
mov
call
;
;
;
hl,#COLON1_Pt
a,#':'
!DisplayOther
hl,#COLON2_Pt
a,#':'
!DisplayOther
Second: xx
mov
br
a,Seconds
DisplaySeconds
;======================================================================
;
;
Display Dash( --:-- ) on the HOUR:MINUTE field
;
;======================================================================
public Display_DASH
Display_DASH:
;
'--'
movw
hl,#HOURS_10th_Pt
mov
a,#'-'
call
!DisplayACharacter
movw
hl,#HOURS_Unit_Pt
mov
a,#'-'
call
!DisplayACharacter
;
':'
movw
hl,#COLON1_Pt
14-11
Software for the LCD Demo Application
;
mov
call
'--'
movw
mov
call
movw
mov
br
a,#':'
!DisplayOther
hl,#MINUTES_10th_Pt
a,#'-'
!DisplayACharacter
hl,#MINUTES_Unit_Pt
a,#'-'
!DisplayACharacter
;======================================================================
;
Display a string to the LCD
;
Terminated either 00 or 0FFH
;
;
Input:
;
DE = String ptr
;
Return:
;
ptr = ptr++;
;======================================================================
public DisplayAString
DisplayAString:
;
;
Clear LCD display
;
call
!ClearLCDDisplay
;
;
;
movw
hl,#LCDBuffer
dlop:
mov
a,[de]
cmp
a,#00
bz
$ds10;done
cmp
a,#0ffh
bz
$ds10;done
;
push
de
call
!DisplayACharacter
pop
incw
br
de
de
dlop
ds10:
ret
;======================================================================
;
Display a character to the LCD
;
;
Input: a reg
;
hl= Position
;======================================================================
public DisplayACharacter
DisplayACharacter:
push
hl
mov
b,a
movw
cmp
bc
hl,#SegA14;Alphabet
a,#30h
$achar25
cmp
bnc
a,#3Ah
$achar20;Alphabet
;
;
14-12
Software for the LCD Demo Application
;
;
Digit
sub
a,#30h
pop
hl
;======================================================================
;
;
Digit display
;
;======================================================================
DigitDisplay:
push
hl
movw
hl,#SegD14;Digit
br
$achar30
;
;
check Alphabets
;
achar20:
cmp
a,#41h
bc
$achar25
cmp
a,#41H+26
;
;
Alphabet
;
sub
a,#41h
pop
hl
;======================================================================
;
;
Alphabet display
;
;======================================================================
AlphabetDisplay:
push
hl
br
$achar30
;
;
Not Alphabet or Digits
;
achar25:
pop
hl
;
;======================================================================
;
;
Input: a reg = ASCII data
;
HL = display memory address
;======================================================================
DisplayOther:
push
hl
cmp
a,#':'
bnz
$ck10
movw
ax,#L_COLON
br
achar80
ck10:
cmp
a,#'-'
bnz
$ck20
movw
ax,#L_DASH
br
achar80
ck20:
movw
ax,#00;blank
br
achar80
;
;
Read 2 Bytes
;
achar30:
clr1
cy
rolc
a,1;* 2
14-13
Software for the LCD Demo Application
mov
mov
xch
inc
mov
xch
b,a
a,[hl+b]
a,x
b
a,[hl+b]
a,x;a = upper, x = lower byte
;
;
a = upper byte/b = lower byte
;
;
X---h
achar80:
pop
hl
;
;
HL = data ptr
;
AX = data
;
DisplayData:
;
X---h
push
ax
ror
a,1
ror
a,1
ror
a,1
ror
a,1
and
a,#0fh
mov
[hl+0],a
;
-X--h
pop
ax
and
a,#0fh
mov
[hl+1],a
;
--X-h
mov
a,x
push
ax
;
ror
ror
ror
ror
and
mov
---Xh
pop
and
mov
a,1
a,1
a,1
a,1
a,#0fh
[hl+2],a
decw
decw
decw
decw
ret
hl
hl
hl
hl
ax
a,#0fh
[hl+3],a
;
;* ***********************************************
;*
Define COM Line #
;* ***********************************************
COM1
equ 1
COM2
equ 2
COM3
equ 4
COM4
equ 8
;*
;*
Segment Definitions
;*
s16_G
equ COM1
s16_J
equ COM2
s16_L
equ COM3
s16_D
equ COM4
14-14
Software for the LCD Demo Application
s16_O
s16_F
s16_E
s16_P
equ
equ
equ
equ
COM1*010h
COM2*010h
COM3*010h
COM4*010h
s16_I
s16_B
s16_C
s16_N
equ
equ
equ
equ
COM1*0100h
COM2*0100h
COM3*0100h
COM4*0100h
s16_A
s16_H
s16_K
s16_M
equ
equ
equ
equ
COM1*01000h
COM2*01000h
COM3*01000h
COM4*01000h
;* ***********************************************
;
Table for 14-Segment LCDs
;* ***********************************************
SegD14:
dw
s16_A+s16_B+s16_C+s16_D+s16_E+s16_F;1
dw
s16_B+s16_C;1
dw
s16_A+s16_B+s16_K+s16_J+s16_E+s16_D ;2
dw
s16_A+s16_B+s16_K+s16_J+s16_C+s16_D ;3
dw
s16_F+s16_J+s16_K+s16_B+s16_C ;4
dw
s16_A+s16_F+s16_J+s16_K+s16_C+s16_D ;5
dw
s16_A+s16_C+s16_D+s16_E+s16_F+s16_J+s16_K ;6
dw
s16_A+s16_B+s16_C;7
dw
s16_A+s16_B+s16_C+s16_D+s16_E+s16_F+s16_J+s16_K;8
dw
s16_A+s16_B+s16_C+s16_D+s16_F+s16_J+s16_K;9
;*
;*
Alphabet
;*
SegA14:
dw
s16_F+s16_E+s16_A+s16_B+s16_C+s16_J+s16_K;A
dw
s16_A+s16_B+s16_C+s16_D+s16_H+s16_M+s16_K;B
dw
s16_A+s16_F+s16_E+s16_D
C
dw
s16_A+s16_B+s16_C+s16_D+s16_H+s16_M;D
dw
s16_A+s16_F+s16_E+s16_D+s16_J+s16_K;E
dw
s16_A+s16_F+s16_E+s16_J+s16_K;F
dw
s16_A+s16_F+s16_E+s16_D+s16_C+s16_K;G
dw
s16_F+s16_E+s16_J+s16_K+s16_B+s16_C;H
dw
s16_A+s16_H+s16_M+s16_D ;I
dw
s16_E+s16_B+s16_C+s16_D ;J
dw
s16_F+s16_E+s16_J+s16_I+s16_N;K
dw
s16_F+s16_E+s16_D;L
dw
s16_F+s16_E+s16_G+s16_I+s16_B+s16_C;M
dw
s16_F+s16_E+s16_G+s16_N+s16_B+s16_C;N
dw
s16_F+s16_E+s16_A+s16_B+s16_C+s16_D;O
dw
s16_F+s16_E+s16_A+s16_B+s16_K+s16_J;P
dw
s16_E+s16_F+s16_A+s16_B+s16_C+s16_D+s16_N;Q
dw
s16_F+s16_E+s16_A+s16_B+s16_K+s16_J+s16_N;R
dw
s16_A+s16_F+s16_J+s16_K+s16_C+s16_D;S
dw
s16_A+s16_H+s16_M;T
dw
s16_F+s16_E+s16_D+s16_C+s16_B;U
dw
s16_F+s16_E+s16_L+s16_I ;V
dw
s16_F+s16_E+s16_L+s16_N+s16_C+s16_B;W
dw
s16_G+s16_N+s16_I+s16_L ;X
dw
s16_F+s16_J+s16_K+s16_B+s16_M;Y
dw
s16_A+s16_I+s16_L+s16_D ;Z
L_DASH
L_UNDER
L_SLASH
equ s16_J+s16_K;dash(-)
equs16_D;underline(_)
equs16_I+s16_L;slash(/)
14-15
Software for the LCD Demo Application
L_BSLASH
L_STAR
R_ARROW
L_ARROW
L_BRACK
R_BRACK
L_APOSTR
L_COLON
equs16_G+s16_N;Back slash(\)
equ s16_I+s16_L+s16_G+s16_N ;star(*)
equs16_G+s16_L+s16_J;Right arrow(->)
equs16_I+s16_N+s16_N
equs16_I+s16_N;Left arrow (<-)
equs16_G+s16_L;>
equs16_I;apostrope(')
equs16_H+s16_M;colon(:)
;* ***********************************************
;*
7-Segment LCDs
;* ***********************************************
s7_E
equ COM1
s7_G
equ COM2
s7_F
equ COM3
s7_K
equ COM4
s7_C
equ COM1*010h
s7_B
equ COM2*010h
s7_A
equ COM3*010h
s7_D
equ COM4*010h
;* ***********************************************
;*
7-Segment LCDs
;* ***********************************************
Tab7Seg:
ds
s7_A+s7_B+s7_C+s7_D+s7_E+s7_F;0
ds
s7_B+s7_C;1
ds
s7_A+s7_B+s7_G+s7_E+s7_D;2
ds
s7_A+s7_B+s7_G+s7_C+s7_D;3
ds
s7_F+s7_G+s7_B+s7_C;4
ds
s7_A+s7_F+s7_G+s7_C+s7_D;5
ds
s7_A+s7_F+s7_G+s7_C+s7_D+s7_E;6
ds
s7_A+s7_B+s7_C;7
ds
s7_A+s7_B+s7_C+s7_D+s7_F+s7_E+s7_G;8
ds
s7_A+s7_B+s7_C+s7_D+s7_F+s7_G;9
ds
;
;
;
S7_S
S7_E
S7_P
dash_7
s7_A+s7_B+s7_E+s7_F+s7_G;P in OPEN
Must be less than 15
equ
ds
equ
ds
equ
ds
equ
ds
Colon7seg:
ds
11
s7_A+s7_C+s7_D+s7_F+s7_G
12
s7_A+s7_D+s7_F+s7_E+s7_G
13
s7_A+s7_B+s7_F+s7_E+s7_G
;S
;E
;P
s7_G
s7_A+s7_B+s7_C+s7_D+s7_F+s7_E+s7_G;A
s7_B+s7_C;: - colon
;======================================================================
;
;
CLEAR DISPLAY MEMORY(FA7Fh(SEG0) - FA58h(SEG39))
;
;======================================================================
public Init_LCD
Init_LCD:
call
!ClearLCDDisplay
14-16
Software for the LCD Demo Application
;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 1 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 1, Select 32.768-kHz) subsystem clock
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================
mov
TCL2,#00010000b
;====================================================================
;
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0,Watch Operating Mode Selection)
;
| | | | | | |____ TMC2.1 (= 1,Prescaler Operation control-Enable)
;
| | | | | |______ TMC2.2 (= 1,5-bit counter operation control - enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for watch flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4 .19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)"
)
;
;====================================================================
mov
TMC2,#01010110b
;====================================================================
;
;
LCDC - LCD Display control register
;
;
1 0 0 0 0 0 1 0
;
| | | | | | | |__ LCDC.0 (= 0, Power to LCD from BIAS pin)
;
| | | | | | |____ LCDC.1 (= 1, Power to LCD from BIAS pin)
;
| | | | | |______ LCDC.2 (= 0, Reserved)
;
| | | | |________ LCDC.3 (= 0, Reserved)
;
| | | |__________ LCDC.4 (= 0, Select S24-S39)
;
| | |____________ LCDC.5 (= 0, Select s24-s39)
;
| |______________ LCDC.6 (= 0, Select s24-s39)
;
|________________ LCDC.7 (= 1, Select s24-s39)
;
;====================================================================
mov
LCDC,#10000010b
ret
;====================================================================
;
Clear LCD display
;====================================================================
public ClearLCDDisplay
ClearLCDDisplay:
push
hl
push
ax
push
bc
movw
mov
mov
hl,#LCDBuffer
a,#0
b,#SegmentSize
clrmem:
14-17
Software for the LCD Demo Application
mov
decw
dbnz
[hl],a
hl
b,$clrmem
pop
pop
pop
ret
bc
ax
hl
;======================================================================
;
Blink on
;======================================================================
public SrvBlinkOn
SrvBlinkOn:
mov
a,BlinkOnType
mov
b,a
movw
ax,#ServiceOn
br
!Branch
;======================================================================
ServiceOn:
dw
HourOn
dw
MinuteOn
;======================================================================
;
Blink off
;======================================================================
public SrvBlinkOff
SrvBlinkOff:
mov
a,BlinkOffType
mov
b,a
movw
ax,#ServiceOff
br
!Branch
;======================================================================
ServiceOff:
dw
HourOff
dw
MinuteOff
;======================================================================
;
HOUR ON
;======================================================================
public HourOn
HourOn:
movw
hl,#HOURS_10th_Pt
mov
a,Curr_Hours
cmp
a,#0
bnz
$houron10;has hours
br
Display2Dashs
houron10:
br
DisplayHours
;======================================================================
;
MINUTE ON
;======================================================================
public MinuteOn
MinuteOn:
movw
hl,#MINUTES_10th_Pt
mov
a,Curr_Minutes
cmp
a,#0
bnz
$minute10;has hours
br
Display2Dashs
minute10:
14-18
Software for the LCD Demo Application
br
DisplayMinutes
;======================================================================
;
HOUR Off
;======================================================================
public HourOff
HourOff:
movw
hl,#HOURS_10th_Pt
mov
a,#0
mov
[hl],a
decw
hl
mov
[hl],a
movw
hl,#HOURS_Unit_Pt
mov
[hl],a
decw
hl
mov
[hl],a
ret
;======================================================================
;
MINUTE Off
;======================================================================
public MinuteOff
MinuteOff:
movw
hl,#MINUTES_10th_Pt
mov
a,#0
mov
[hl],a
decw
hl
mov
[hl],a
movw
hl,#MINUTES_Unit_Pt
mov
[hl],a
decw
hl
mov
[hl],a
ret
;======================================================================
;
Display '--'
;
input: hl = display memory address
;======================================================================
public Display2Dashs
Display2Dashs:
mov
a,#'-'
call
!DisplayACharacter
mov
a,#'-'
br
DisplayACharacter
;======================================================================
;
Display hours in HOUR field
;
Input: a = hours
;======================================================================
public DisplayHours
DisplayHours:
movw
hl,#HOURS_10th_Pt
cmp
a,#10
bnc
$dtod10 ;less than 10
; 0 AM to 9 AM
push
ax
movw
ax,#00
call
!DigitDisplay
pop
ax
movw
hl,#HOURS_Unit_Pt
br
DigitDisplay
dtod10:
cmp
a,#12+1
bnc
$dtod12 ;less than 12
14-19
Software for the LCD Demo Application
; 10 AM to 12 NOON
push
ax
movw
ax,#1
call
!DigitDisplay
movw
hl,#HOURS_Unit_Pt
pop
ax
sub
a,#10
br
DigitDisplay
;
13 to 23
dtod12:
; 13 hr to 21 hr
cmp
a,#12+9
bnc
$dtod14 ;less than 12
;
push
ax
movw
ax,#00
call
!DigitDisplay
movw
hl,#HOURS_Unit_Pt
pop
ax
sub
a,#12
br
DigitDisplay
dtod14:
; 22 hr to 23 hr
push
ax
movw
ax,#1
call
!DigitDisplay
movw
hl,#HOURS_Unit_Pt
pop
ax
sub
a,#22
br
DigitDisplay
;======================================================================
;
Display minutes in MINUTE field
;
Input: a = minutes
;======================================================================
public DisplayMinutes
DisplayMinutes:
;
;
MINUTE: xx
;
movw
hl,#MINUTES_10th_Pt
br
DisplayAField
;======================================================================
;
Display seconds in SECOND field
;
Input: a = seconds
;======================================================================
public DisplaySeconds
DisplaySeconds:
movw
hl,#SECONDS_10th_Pt
br
DisplayAField
;======================================================================
;
;
;
;======================================================================
public DisplayAField
DisplayAField:
mov
x,#0
mloop:
cmp
a,#10
bc
$mless10
sub
a,#10
14-20
Software for the LCD Demo Application
inc
br
x
mloop
;
mless10:
;
xch
a,x
A = 10th , X = unit
push
ax
call
!DigitDisplay
pop
ax
xch
a,x
br
DigitDisplay
;======================================================================
end
14-21
Software for the LCD Demo Application
Assembly Language Program: DEM_TOD.ASM
;****************************************************************************
;
File name: DEM_TOD.ASM
;
Date: 1/29/98
;****************************************************************************
;
Description:
;
; This program is to demonstrate the Watch timer in the uPD78308 microcontroller.
; The watch timer control registers (TCL2 and TMC2)) are used to configure
; the watch timer function.
; The resolution of the watch timer and time base is selectable as either 0.25 second
; or 0.5 second when 4.19 MHz (standard: 4.194304 MHz) main system clock is
; used.
; Since there is no interrupt vector for 0.5-second interval, the watch
; timer's interval timer interrupt (INTT3) should be used to check whether
; 0.5 second has passed.
;=============================================================================
; The sample program will set minute, hour, and day with 0.5-second time base.
; The interval time is set to 15.6 ms. The interval time interrupt service
; routine is used to check whether the 0.5-second flag WTIF is set. If so, increment the
; 0.5-second count.
;======================================================================
;======================================================================
;
Equates
;======================================================================
public
public
public
public
public
public
public
public
public
ASecondFlag
BlinkPeriod
Days
Hours
HalfSecondFlag
Interval_timer
Minutes
Seconds
Watch_timer
extbit BlinkFlag
extbit BlinkOnOffFlag
extrn BlinkOnType
extrn BlinkOffType
extrn Curr_Field_Number
;======================================================================
;
saddr Area
;
FWA = 0fe20h
;======================================================================
dseg
saddr
;
;
Time of day by Watch timer mode
;
Interval_timer: ds1;Interval timer counter (15.6 ms)
BlinkPeriod:ds 1;blink time
Seconds:
Minutes:
Hours:
Days:
ds
ds
ds
ds
1;Seconds
1;Minutes
1;Hours
1;Days
;======================================================================
;
Even Boundary Pair
;======================================================================
14-22
Software for the LCD Demo Application
dseg
saddrp
;======================================================================
;
Bit Segment
;======================================================================
bseg
HalfSecondFlagdbit;1/2-second toggle flag
ASecondFlagdbit ;1-second pass flag
cseg
;====================================================================
;
Init. Time of day register
;====================================================================
public Init_TOD
Init_TOD:
;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 0 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 0, Select 4.1 9MHz/27)
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================
mov
TCL2,#00000000b
;====================================================================
;
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch Operating Mode Selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler Operation control-Enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control - enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for Wach flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms (fxx=4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms (fxx=4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms (fxx=4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)"
)
;
;====================================================================
mov
TMC2,#01010110b
;
;
Clear time variables
;
Default time: 12:00:00
;
mov
Seconds,#0
mov
Minutes,#0
mov
Hours,#12
mov
Days,#0
clr1
clr1
ret
HalfSecondFlag
ASecondFlag
$ej
;======================================================================
14-23
Software for the LCD Demo Application
;
Module name: INTTM3 Watch timer Interval Time Interrupt
;
;
DESCRIPTION:
;
.Set Watch time variables
;
;
OPERATION:
;
. Flip the HalfSecondFlag
;
. If HalfSecondFlag = 0 then incr. seconds
;
. If Seconds == 60 incr. minutes
;
. If Minutes == 60 incr. hours
;
. If Hours
== 24 incr. days
;
;======================================================================
Watch_timer:
;
;
decr. interval counter
;
cmp
Interval_timer,#0
bz
$watch10
;
dec
Interval_timer
bnz
$watch10
;
;
Blink on
;
bf
BlinkFlag,$watch10;No blink
;
;
reset blink period
;
mov
a,BlinkPeriod
mov
Interval_timer,a
;
bf
BlinkOnOffFlag,$bk10 ;Blink on
;
;
Blink OFF
;
clr1
BlinkOnOffFlag
extrn SrvBlinkOff
call
!SrvBlinkOff
br
watch10
;
;
Blink ON
;
bk10:
set1
BlinkOnOffFlag
extrn SrvBlinkOn
call
!SrvBlinkOn
br
watch10
;
;
Test .5 second flag
;
watch10:
bf
WTIF,$wt20;Not yet
clr1
WTIF
;
;
.5 seconds passed
;
bf
HalfSecondFlag,$wt10 ;1/2 second passed
;
Clear half seconds flag
clr1
HalfSecondFlag
set1
ASecondFlag
inc
Seconds
;
14-24
Software for the LCD Demo Application
cmp
bc
mov
Seconds,#60
$wt20
Seconds,#0
inc
cmp
bc
mov
Minutes
Minutes,#60
$wt20
Minutes,#0
inc
cmp
bc
mov
Day
inc
cmp
bc
Hours
Hours,#24
$wt20
Hours,#0
br
$wt20
set1
HalfSecondFlag
;
;
;
Days
Days,#30
$wt20
;
wt10:
wt20:
reti
;======================================================================
;
Delay 1/2 second
;
If key is depressed, then quit.
;
CY = 1 else CY = 0
;======================================================================
BaseTime equ
156;15.6 ms
public Delay500Msec
Delay500Msec:
mov
Interval_timer,#5000/BaseTime
D500mslp:
extrn CheckKeyOn
call
!CheckKeyOn
bnz
$d500msrtn;Key on
;
cmp
Interval_timer,#0
bnz
$D500mslp
clr1
CY
ret
;
;
CF = 1 if key on
;
d500msrtn:
set1
CY
ret
;======================================================================
;
Set Blink parameters
;
Input: Interval_timer
;======================================================================
public SetBlink
SetBlink:
mov
a,BlinkPeriod
mov
Interval_timer,a
set1
BlinkFlag
clr1
BlinkOnOffFlag
mov
a,Curr_Field_Number
mov
BlinkOnType,a
ret
14-25
Software for the LCD Demo Application
;======================================================================
;
;
Clear Blink parameters
;
;======================================================================
public ClearBlink
ClearBlink:
clr1
BlinkFlag
clr1
BlinkOnOffFlag
ret
;======================================================================
;======================================================================
;======================================================================
end
14-26
Software for the LCD Demo Application
Assembly Language Program: DEMO_KEY.ASM
;************************************************************************
;
;
File name: DEMO_KEY.ASM
;
Date: 1/29/98
;****************************************************************************
;
Description:
;
;
;The example program is a key input module that inputs signals from a key matrix
;of 4 x 4 keys. The keys can be pressed successively, and two or more keys can
;be pressed simultaneously. In the circuit shown in this example, the lower 4
;bits of port3 (P30 - P33) are used as key scan signals, and port 11 (P4 if µPD78054 or µPD78078) is
;used for key return signals. As the pullup resistor of port 11 for key return, the
;internal resistor set by software is used.
;
;Port 11 of the K0 family has a function to detect the falling edges of the
;eight port pins in parallel. If port 11 is used for key return signals,
;therefore, the standby mode can be released through detection of a falling
;edge, by key input.
;
;The input keys are stored to RAM on a one-key-to 1 bit basis. The RAM bit
;corresponding to a pressed key is set and the bit corresponding to a released
;key is cleared. By testing the RAM data on a 1-bit basis starting
;from the first bit, the key status can be checked. To absorb key debouncing,
;the key is assumed to be valid when four successive key codes coincide with a
;given code. For example, if a key code is sampled every 16 ms, debouncing of
;48 ms to 64 ms can be absorbed.
;
;
; Key number:
;
0 = P114 + P30
;
1 = P114 + P31
;
2 = P114 + P32
;
3 = P114 + P33
;
;
4 = P115 + P30
;
5 = P115 + P31
;
6 = P115 + P32
;
7 = P115 + P33
;
;
8 = P116 + P30
;
9 = P116 + P31
;
10 = P116 + P32 SET
;
11 = P116 + P33 ENTER
;
;
12 = P117 + P30 CLEAR/STOP
;
13 = P117 + P31 STOP
;
14 = P117 + P32
;
15 = P117 + P33
;
;
P4 is used instead of P11 if µPD78054 or µPD78078.
;
;======================================================================
;
The system has a main system clock( 5 MHz) and a subsystem clock( 32.768 kHz).
;
The LCD and Watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock and when a key is depressed, the
;
main system clock is activated.
;======================================================================
public KeyNumber
public Init_Key
14-27
Software for the LCD Demo Application
public KeyScan
;======================================================================
;
Key Assignment
;======================================================================
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
PUBLIC
DIGIT_0 EQU
DIGIT_1 EQU
DIGIT_2 EQU
DIGIT_3 EQU
DIGIT_4 EQU
DIGIT_5 EQU
DIGIT_6 EQU
DIGIT_7 EQU
DIGIT_8 EQU
DIGIT_9 EQU
KEY_SET EQU
KEY_ENTER EQU
KEY_CLEAR EQU
KEY_STOP EQU
KEY_SPARE1EQU
KEY_SPARE2EQU
DIGIT_0
DIGIT_1
DIGIT_2
DIGIT_3
DIGIT_4
DIGIT_5
DIGIT_6
DIGIT_7
DIGIT_8
DIGIT_9
KEY_SET
KEY_ENTER
KEY_CLEAR
KEY_STOP
KEY_SPARE1
KEY_SPARE2
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
;======================================================================
;======================================================================
dseg
saddr
KeyNumber:ds
1;Key number
;======================================================================
;
Even Boundary Pair
;======================================================================
dseg
saddrp
;======================================================================
;
Bit Segment
;======================================================================
bseg
;====================================================================
;
Init key return port
;====================================================================
cseg
Init_Key:
14-28
Software for the LCD Demo Application
;====================================================================
;
Key Return Mode register (KRM)
;
;
0 0 0 0 0 1 0 0
;
| | | | | | | |__ KRM.0 (= 0, Not detected key return signal)
;
| | | | | | |____ KRM.1 (= 1, Standby mode release enabled)
;
| | | | | |______ KRM.2 (= 1, Select p114-p117 as key return signal port)
;
| | | | |________ KRM.3 (= 0, Select p114-p117 as key return signal port)
;
| | | |__________ KRM.4 (= 0, Reserved)
;
| | |____________ KRM.5 (= 0, Reserved)
;
| |______________ KRM.6 (= 0, Reserved)
;
|________________ KRM.7 (= 0, Reserved)
;
;
If µPD78054 or µPD78078, KRM.2 and KRM.3 cannot be defined.
;
;====================================================================
mov
KRM,#00000100b
; Set Scan Ports
mov
PM3,#11110000B;P30-P33 Output
mov
P3,#00000000b;Set P30-P33 to Low
; Set Sense Ports
$if(D054)
$else
mov
PM11,#11110000B ;P114-P117 as input
$endif
;
;
pull-up resistor option on P11
;
$if(D054)
mov
PUOL,#00010000B
$else
mov
PUOH,#00001000B
$endif
ret
;======================================================================
;
Key scan module
;
;
The key matrix is 4 x 4. There are four scan ports (P30-P33) and
;
four key return signal ports (P114-P117).
;
Debounce count sets to 4
;
;
Key number:
;
0 = P114 + P30
;
1 = P114 + P31
;
2 = P114 + P32
;
3 = P114 + P33
;
4 = P115 + P30
;
5 = P115 + P31
;
6 = P115 + P32
;
7 = P115 + P33
;
8 = P116 + P30
;
9 = P116 + P31
;
10 = P116 + P32
;
11 = P116 + P33
;
12 = P117 + P30
;
13 = P117 + P31
;
14 = P117 + P32
;
15 = P117 + P33
;
;
Return:
;
cf = 1 if a key depressed
;
and KeyNumber with key number
14-29
Software for the LCD Demo Application
;
;
cf = 0 if no key depressed.
;
;
Registers:
;
a = Scratch
;
b = Total row or column numbers
;
c = Sense port
;
d = Row * 4 + column
;
e = Column port
;
h = Current key number
;
l = Number of debounces
;
;======================================================================
KeyScan:
;
;
Find a key
;
mov
h,#0ffh ;no key flag
mov
l,#3
KeyScanLoop:
and
P3,#11110000b
nop
nop
nop
nop
$if(D054)
mov
a,P4
$else
mov
a,P11
$endif
and
a,#11110000b; mask low nibble
cmp
a,#11110000b;all high
bz
$NotFound;no key depressed
;
mov
c,a
mov
d,#0;key number
mov
x,#00010000b;find a row
mov
b,#4;4 rows
CheckRow:
mov
a,x
and
a,c
bz
$RowFind;find the row
; shift to left
mov
a,x
clr1
cy
rol
a,1
mov
x,a
; update row * column
mov
a,d
add
a,#4
mov
d,a
;
dbnz
b,$CheckRow
;
;
Not Found
;
NotFound:
clr1
cy
ret
;
;
Row Find. Find Column
;
d = row*column
;
x = row position
14-30
Software for the LCD Demo Application
;
RowFind:
mov
mov
e,#00000001b;find a column
b,#4;4 columns
mov
mov
nop
nop
nop
nop
a,e
p3,a;set to high
mov
a,P4
mov
a,P11
CheckCol:
$if(D054)
$else
$endif
and
a,x
bnz
$ColFind
; shift to left
clr1
cy
mov
a,e
rol
a,1
mov
e,a
;
;
Incr. key number
;
inc
d
dbnz
b,$CheckCol
br
NotFound;not found
;
ColFind:
mov
a,d
cmp
a,h
bz
$CheckDebounce ; ok
;
;
Restart key scan
;
mov
h,a
;
;
Decr. debounce count
;
CheckDebounce:
dec
l
bnz
$KeyScanLoop
;
KeyFound:
mov
a,h
mov
KeyNumber,a
set1
cy
ret
;======================================================================
;
Wait for a key released
;======================================================================
public WaitKeyReleased
WaitKeyReleased:
nop
Waitlp:
call
!CheckKeyOn
bnz
$Waitlp ;key on
ret
;======================================================================
;
Check key on or off
14-31
Software for the LCD Demo Application
;
return with ZF = 1 if no key is on
;======================================================================
public CheckKeyOn
CheckKeyOn:
and
P3,#11110000b
nop
nop
nop
$if(D054)
mov
a,P4
$else
mov
a,P11
$endif
and
a,#11110000b;mask low nibble
cmp
a,#11110000b;all high
ret
;======================================================================
end
14-32
Software for the LCD Demo Application
C Language Program: DEMO.H
/******************************************************************
*
File name: DEMO.H
*
Date:11/10/97
*
Include file for definition
******************************************************************/
#define TRUE
1
#define FALSE
0
//
//
extended functions
//
#pragma sfr
// SFR
#pragma asm
// ASM
#pragma opc
// DATA INSERTION
#ifdef K0S
#pragma realregister // using in K0S compiler
#endif
#pragma
#pragma
#pragma
#pragma
#pragma
HALT
STOP
NOP
DI
EI
#pragma access
// PEEK, POKE
#define CR
13
#define LF
10
//
// DDB board used to debug
//
#define DDB
0
//
//
KEY DEFINITIONS
//
#define DIGIT_0
#define DIGIT_1
#define DIGIT_2
#define DIGIT_3
#define DIGIT_4
#define DIGIT_5
#define DIGIT_6
#define DIGIT_7
#define DIGIT_8
#define DIGIT_9
#define KEY_SET
#define KEY_ENTER
#define KEY_CLEAR
#define KEY_STOP
#define KEY_SPARE1
#define KEY_SPARE2
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define BaseTime
156//;15.6 ms
// $set(D054)
//;
//;
LCD Display Memory
//;
#define LCDBuffer
0xFA7F
#define SegmentSize
40
#define HOURS_10th_Pt
0xFA7F
14-33
Software for the LCD Demo Application
#define
#define
#define
#define
#define
#define
#define
HOURS_Unit_Pt
COLON1_Pt
MINUTES_10th_Pt
MINUTES_Unit_Pt
COLON2_Pt
SECONDS_10th_Pt
SECONDS_Unit_Pt
HOURS_10th_Pt- 4
HOURS_Unit_Pt - 4
COLON1_Pt - 4
MINUTES_10th_Pt - 4
MINUTES_Unit_Pt - 4
COLON2_Pt -4
SECONDS_10th_Pt -4
#define AMPM_Pt
0xFA5F
#define
#define
#define
#define
//*
//*
//*
#define
#define
#define
#define
COM1
COM2
COM3
COM4
1
2
4
8
s16_G
s16_J
s16_L
s16_D
COM1
COM2
COM3
COM4
#define
#define
#define
#define
s16_O
s16_F
s16_E
s16_P
COM1*0x10
COM2*0x10
COM3*0x10
COM4*0x10
#define
#define
#define
#define
s16_I
s16_B
s16_C
s16_N
COM1*0x100
COM2*0x100
COM3*0x100
COM4*0x100
#define
#define
#define
#define
s16_A
s16_H
s16_K
s16_M
COM1*0x1000
COM2*0x1000
COM3*0x1000
COM4*0x1000
Segment Definitions
#define L_DASH
#define L_COLON s16_H+s16_M
s16_J+s16_K//;dash(-)
//;colon(:)
/* ;* ***********************************************
;*
7-Segment LCDs
;* *********************************************** */
#define
#define
#define
#define
#define
#define
#define
#define
14-34
s7_E
s7_G
s7_F
s7_K
s7_C
s7_B
s7_A
s7_D
COM1
COM2
COM3
COM4
COM1*0x10
COM2*0x10
COM3*0x10
COM4*0x10
//;offset 4 segments
Software for the LCD Demo Application
C Language Program: DEMO_CLK.C
/*;************************************************************************
;
;
File name: DEMO_CLK.C
;
Date: 1/29/98
;
;
MAIN module
;****************************************************************************
;
Description:
;
;
This program demonstrate, the following functions in the K0/K0S series:
;
LCD display function
;
Keyboard function
;
Time of day function
;
Power down mode(standby mode)
;
Each module is written in a file that can be used as an application
;
note.
;
;======================================================================
;
The system has a main system clock (5 MHz) and a subsystem clock (32.768 kHz).
;
The LCD and Watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock but when a key is depressed, the
;
main system clock is activated.
;======================================================================*/
#include "DEMO.H"
/*;======================================================================
;
Extern reference
;======================================================================*/
extern
bit
extern
extern
extern
extern
extern
__sreg
__sreg
__sreg
__sreg
__sreg
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
ASecondFlag;
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
Hours;
Interval_timer;
KeyNumber;
Minutes;
Seconds;
ClearBlink();
ClearLCDDisplay();
DisplayTOD();
DisplayAString();
DoSetTOD();
Init_LCD();
Init_Key();
Init_TOD();
KeyScan();
Display_DASH();
SetBlink();
WaitKeyReleased();
Branch(int *, unsigned char);
KeyClear();
KeyDigit();
KeyEnter();
KeySet();
KeySpare();
ServiceKey();
void hdwinit();
14-35
Software for the LCD Demo Application
void exit();
//
void hdwinit()
{
}
void exit()
{
}
/*;======================================================================
;
bit Area
;
FWA = 0fe20h
;======================================================================*/
bit DoneFlag;
/*;======================================================================
;
saddr Area
;
FWA = 0fe20h
;======================================================================*/
__sreg unsigned char Curr_Hours;
__sreg unsigned char Curr_Minutes;
__sreg unsigned char Curr_Field_Number;
__sreg unsigned char digit;
__sreg unsigned char *Curr_Field_Ptr;
#define HOUR_Field
#define MINUTE_Field
#define SECOND_Field
0
1
2
/*;======================================================================
;
Even Boundary Pair
;======================================================================*/
const unsigned char NEC_DEMO[] = "NEC DEMO";
const unsigned char ConvertToDigit[] ={
DIGIT_0,
DIGIT_1,
DIGIT_2,
DIGIT_3,
DIGIT_4,
DIGIT_5,
DIGIT_6,
DIGIT_7,
DIGIT_8,
DIGIT_9
};
//;
//;
//;
const int * KeyServiceTable[] = {
KeyDigit
,
KeyDigit
,
KeyDigit
,
KeyDigit
,
KeyDigit
,
KeyDigit
,
KeyDigit
,
KeyDigit
,
KeyDigit
,
KeyDigit
,
KeySet
14-36
Software for the LCD Demo Application
,
,
,
,
KeyEnter
KeyClear
KeySpare
KeySpare
};
/*;======================================================================
;
MAIN
;======================================================================*/
void main()
{
//;
//;
Oscillation mode select register
//;
. Does not use divider circuit
//;
OSMS = 0b00000001;
//;
//;
Init.
//;
Init_Key();
Init_TOD();
Init_LCD();
//;
Clear IRQ flags
TMIF3 = 0;
//;
Enable Watch Timer Interval Timer
TMMK3 = 0;
EI();
/*;======================================================================
;
Display current time of day
;
Default: 12:00:00
;======================================================================*/
PCC=0b00000000;
//;
//;
Display a greeting message
//;
'NEC DEMO'
//;
DisplayAString("NEC DEMO");
while(Seconds < 5);
Seconds = 0;
//;
//;
Display default time of day (12:00:00)
//;
ClearLCDDisplay();
DisplayTOD();
ASecondFlag = 0;
//;
//;
Go to STANDBY MODE and if wake up then
//;
Check second on
//;
while(TRUE)
{
//;
//;
a second passed?
//;
if( ASecondFlag)
{
ASecondFlag = 0;
DisplayTOD();
}
//;
//;
//;
Scan Keyboard - every 15.6 ms will wake it up
NOP();
NOP();
14-37
Software for the LCD Demo Application
STOP();
NOP();
KeyScan();
if(KeyNumber != 0xff)
{
DI();
ServiceKey();
EI();
}
}
}
/*;======================================================================
;
Service a key
;
;
Input: KeyNumber
;
;======================================================================*/
void ServiceKey()
{
if( KeyNumber != KEY_SET) return;
/*;======================================================================
;
Set time of day.
;
Clear the LCD display.
;
Blink the HOUR field and wait for hours set.
;
Blink the MINUTE field and wait for minutes set.
;
After minutes is set, exit.
;
If STOP then abort an action
;
If CLEAR then start from Hour entry
;======================================================================*/
ClearLCDDisplay();
//;
Display dash(--) and blink
Display_DASH();
//;
Interval_timer = 5000/BaseTime;
SetBlink();
while(TRUE)
{
DoneFlag = 0;
Curr_Hours = 0;
Curr_Minutes = 0;
Curr_Field_Number = 0;
Curr_Field_Ptr = &Curr_Hours;
//;
//;
Wait for key released
//;
NextKeyLp:
WaitKeyReleased();
srv_lop:
KeyScan();
if(KeyNumber == 0) goto srv_lop;
if(KeyNumber == KEY_CLEAR) continue;
//;
//;
Service
//;
Branch( (int *)KeyServiceTable, KeyNumber);
if( !DoneFlag ) goto NextKeyLp;
//;
//;
Blink off
//;
ClearBlink();
}
}
14-38
Software for the LCD Demo Application
/*;======================================================================
*
Digit Process
*;======================================================================*/
void KeyDigit()
{
for(digit = 0 ; digit < 10; digit++)
{
if( KeyNumber == ConvertToDigit[digit]) break;
}
*Curr_Field_Ptr = (char)(*Curr_Field_Ptr * 10 + digit);
}
//
void KeySet()
{
}
void KeyEnter()
{
switch(Curr_Field_Number)
{
case HOUR_Field:
Hours = Curr_Hours;
Curr_Field_Ptr = &Curr_Minutes;
Curr_Field_Number++;
break;
case MINUTE_Field:
Minutes = Curr_Minutes;
DoneFlag = 1;
break;
}
}
void KeyClear()
{
}
void KeySpare()
{
}
/* **********************************************************************
;
Branch
*********************************************************************** */
void Branch(int *TblPtr, unsigned char IndexNumber)
{
TblPtr + IndexNumber*2;
__asm(" pop AX");
__asm(" pop HL");
__asm(" br ax ");
}
14-39
Software for the LCD Demo Application
Language Program: DEMO_LCD.C
/*;************************************************************************
;
;
File name: DEMO_LCD.C
;
Date: 1/29/98
;
;****************************************************************************
;
Description:
;
;
;The example program is an LCD Driver using 4-time-division and 1/2 bias.
;The program displays the time of day, HOURS:MINUTES;SECONDS. Default time is 12:00:00. Every 15.6
;milliseconds, the program checks whether a second has passed. If so, the display is updated.
;
;======================================================================
;
The system has a main system clock (5 MHz) and a subsystem clock (32.768 kHz).
;
The LCD and Watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock, but when a key is depressed the
;
main system clock is activated.
;======================================================================*/
#include "DEMO.H"
/*;======================================================================
;
Equates
;======================================================================*/
//;
//;
Time of day by Watch timer mode
//;
extern __sreg Interval_Seconds;
extern __sregunsigned char Seconds; //Seconds
extern __sregunsigned char Minutes; //Minutes
extern __sregunsigned char Hours;
//Hours
extern __sregunsigned char Days;
//Days
extern __sregunsigned char Curr_Hours;
extern __sregunsigned char Curr_Minutes;
bit BlinkFlag;
// blink LCD display
bit BlinkOnOffFlag; // blink on/off(1 = on)
__sreg
__sreg
__sreg
__sreg
void
void
void
void
void
void
void
void
void
void
void
void
void
unsigned int CodeW;
char *SegPtr; //Segment ptr
unsigned char BlinkOnType; //
unsigned char BlinkOffType; //
Branch( int *, unsigned char );
DisplayACharacter(unsigned char );
Display2Dashs();
DisplayAField(unsigned char );
DisplayHours(unsigned char);
DisplayMinutes(unsigned char);
DisplaySeconds(unsigned char);
DisplayAString(char *);
DisplayTOD(void);
DisplayOther(unsigned char );
LCDDisplay(void);
DigitDisplay(unsigned char );
AlphabetDisplay(unsigned char );
void
void
14-40
HourOn();
HourOff();
Software for the LCD Demo Application
void
void
void
MinuteOn();
MinuteOff();
ClearLCDDisplay();
//;======================================================================
//
Service ON
//;======================================================================
const int * ServiceOn[] = {
HourOn,
MinuteOn
};
//;======================================================================
//
Service OFF
//;======================================================================
const int * ServiceOff[] = {
HourOff,
MinuteOff
};
/* ;* ***********************************************
/* ;* ***********************************************
/* ;* ***********************************************
/* ;* ***********************************************
;*
Define COM Line #
;* *********************************************** */
/*;* ***********************************************
;
Table for 14-segment LCD
;* *********************************************** */
unsigned int const SegD14[] =
{
s16_A+s16_B+s16_C+s16_D+s16_E+s16_F// ;0
,s16_B+s16_C// ;1
,s16_A+s16_B+s16_K+s16_J+s16_E+s16_D// ;2
,s16_A+s16_B+s16_K+s16_J+s16_C+s16_D// ;3
,s16_F+s16_J+s16_K+s16_B+s16_C// ;4
,s16_A+s16_F+s16_J+s16_K+s16_C+s16_D// ;5
,s16_A+s16_C+s16_D+s16_E+s16_F+s16_J+s16_K// ;6
,s16_A+s16_B+s16_C// ;7
,s16_A+s16_B+s16_C+s16_D+s16_E+s16_F+s16_J+s16_K //;8
,s16_A+s16_B+s16_C+s16_D+s16_F+s16_J+s16_K //;9
};
//;*
//;*
Alphabet
//;*
const unsigned int SegA14[] =
{
s16_F+s16_E+s16_A+s16_B+s16_C+s16_J+s16_K//;A
,s16_A+s16_B+s16_C+s16_D+s16_H+s16_M+s16_K //;B
,s16_A+s16_F+s16_E+s16_D //;C
,s16_A+s16_B+s16_C+s16_D+s16_H+s16_M //;D
,s16_A+s16_F+s16_E+s16_D+s16_J+s16_K //;E
,s16_A+s16_F+s16_E+s16_J+s16_K //;F
,s16_A+s16_F+s16_E+s16_D+s16_C+s16_K //;G
,s16_F+s16_E+s16_J+s16_K+s16_B+s16_C //;H
,s16_A+s16_H+s16_M+s16_D //;I
,s16_E+s16_B+s16_C+s16_D //;J
,s16_F+s16_E+s16_J+s16_I+s16_N //;K
,s16_F+s16_E+s16_D //;L
,s16_F+s16_E+s16_G+s16_I+s16_B+s16_C //;M
14-41
Software for the LCD Demo Application
,s16_F+s16_E+s16_G+s16_N+s16_B+s16_C //;N
,s16_F+s16_E+s16_A+s16_B+s16_C+s16_D //;O
,s16_F+s16_E+s16_A+s16_B+s16_K+s16_J //;P
,s16_E+s16_F+s16_A+s16_B+s16_C+s16_D+s16_N //;Q
,s16_F+s16_E+s16_A+s16_B+s16_K+s16_J+s16_N //;R
,s16_A+s16_F+s16_J+s16_K+s16_C+s16_D //;S
,s16_A+s16_H+s16_M //;T
,s16_F+s16_E+s16_D+s16_C+s16_B //;U
,s16_F+s16_E+s16_L+s16_I //;V
,s16_F+s16_E+s16_L+s16_N+s16_C+s16_B //;W
,s16_G+s16_N+s16_I+s16_L //;X
,s16_F+s16_J+s16_K+s16_B+s16_M //;Y
,s16_A+s16_I+s16_L+s16_D //;Z
};
/* ;* ***********************************************
;*
7-segment LCDs
;* *********************************************** */
const unsigned char Tab7Seg[] =
{
s7_A+s7_B+s7_C+s7_D+s7_E+s7_F//;0
,s7_B+s7_C //;1
,s7_A+s7_B+s7_G+s7_E+s7_D //;2
,s7_A+s7_B+s7_G+s7_C+s7_D //;3
,s7_F+s7_G+s7_B+s7_C //;4
,s7_A+s7_F+s7_G+s7_C+s7_D //;5
,s7_A+s7_F+s7_G+s7_C+s7_D+s7_E //;6
,s7_A+s7_B+s7_C //;7
,s7_A+s7_B+s7_C+s7_D+s7_F+s7_E+s7_G //;8
,s7_A+s7_B+s7_C+s7_D+s7_F+s7_G //;9
//;
//;
Must be less than 15
//;
,s7_A+s7_C+s7_D+s7_F+s7_G //;S
,s7_A+s7_D+s7_F+s7_E+s7_G //;E
,s7_A+s7_B+s7_F+s7_E+s7_G //;P
,s7_A+s7_B+s7_C+s7_D+s7_F+s7_E+s7_G //;A
,s7_B+s7_C //;: - colon
};
//;======================================================================
//;
LCD Initialization
//;======================================================================
void Init_LCD()
{
ClearLCDDisplay();
/*;====================================================================
;
;
LCDC - LCD Display control register
;
;
1 0 0 0 0 0 1 0
;
| | | | | | | |__ LCDC.0 (= 0, Power to LCD from BIAS pin)
;
| | | | | | |____ LCDC.1 (= 1, Power to LCD from BIAS pin)
;
| | | | | |______ LCDC.2 (= 0, Reserved)
;
| | | | |________ LCDC.3 (= 0, Reserved)
;
| | | |__________ LCDC.4 (= 0, Select S24-S39)
;
| | |____________ LCDC.5 (= 0, Select S24-S39)
;
| |______________ LCDC.6 (= 0, Select S24-S39)
;
|________________ LCDC.7 (= 1, Select S24-S39)
;
;====================================================================*/
LCDC = 0b10000010;
/*;====================================================================
14-42
Software for the LCD Demo Application
;
;
LCDM - LCD Display mode register
;
;
1 0 0 1 0 0 0 0
;
| | | | | | | |__ LCDM.0 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | | | |____ LCDM.1 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | | |______ LCDM.2 (= 0, 4-time-division, 1/3 bias mode)
;
| | | | |________ LCDM.3 (= 0, Normal mode(2.7 to 5.5 v)
;
| | | |__________ LCDM.4 (= 1, LCD clock 128 Hz)
;
| | |____________ LCDM.5 (= 0, LCD clock 128 Hz)
;
| |______________ LCDM.6 (= 0, LCD clock 128 Hz)
;
|________________ LCDM.7 (= 1, Display ON)
;
;====================================================================*/
LCDM = 0b10010000;
}
/*;===================================================================
*
Clear display memory
*;===================================================================*/
void
ClearLCDDisplay()
{
unsigned char i;
char *dptr;
dptr = (char *)LCDBuffer;
for(i=0;i<SegmentSize;i++) *dptr--= 0;
}
/*;===================================================================
;
Default Time of day
;
Default:12:00:00
;===================================================================*/
void DisplayTOD(void)
{
SegPtr = (char *)(HOURS_10th_Pt);
DisplayHours(Hours);
SegPtr = (char *)(COLON1_Pt);
DisplayOther(':');
//;
//;
MINUTE: xx
//;
DisplayMinutes(Minutes);
//;
//;
(:)
//;
SegPtr = (char *)(COLON2_Pt);
DisplayOther(':');
//;
//;
Second: xx
//;
DisplaySeconds(Seconds);
}
/*;======================================================================
;
;
Display Dash( --:-- ) on the HOUR:MINUTE field
;
;======================================================================*/
void
Display_DASH()
{
//;
'--'
14-43
Software for the LCD Demo Application
//
SegPtr = (char *)(HOURS_10th_Pt);
DisplayACharacter('-');
SegPtr = (char *)(HOURS_Unit_Pt);
DisplayACharacter('-');
SegPtr = (char *)(COLON1_Pt);
DisplayOther(':');
'--'
SegPtr = (char *)(MINUTES_10th_Pt);
DisplayACharacter('-');
SegPtr = (char *)(MINUTES_Unit_Pt);
DisplayACharacter('-');
}
/*;======================================================================
;
;
Display a string to the LCD
;
Terminated either 0x00
;
;======================================================================*/
void DisplayAString( char Buffer[])
{
char *dptr;
SegPtr =Buffer;
while(!*dptr)
{
DisplayACharacter(*dptr++);
}
}
/*;======================================================================
;
Display a character to the LCD
;======================================================================*/
void DisplayACharacter(unsigned char code)
{
if(code >= 0x30 && code <= 0x39 )
{
DigitDisplay(code);
}
else
{
if(code >= 0x41 && code <= 0x59 )
{
AlphabetDisplay(code);
}
else
DisplayOther(code);
}
}
/*;======================================================================
;
Display a DIGIT( 0 to 9 or ASCII digits) to the LCD
;======================================================================*/
void DigitDisplay(unsigned char code)
{
CodeW = SegD14[ ( code & 0x0f) * 2];
LCDDisplay();
}
/*;======================================================================
;
Display an ALPHABET to the LCD
;======================================================================*/
void AlphabetDisplay(unsigned char code)
14-44
Software for the LCD Demo Application
{
CodeW = SegA14[ (code - 0x41) * 2];
LCDDisplay();
}
/*;======================================================================
;
Display a SYMBOL to the LCD
;======================================================================*/
void DisplayOther(unsigned char code)
{
if(code == 0)
{
CodeW = 0;
LCDDisplay();
}
if(code == ':')
{
CodeW = L_COLON;
LCDDisplay();
}
if(code == '-')
{
CodeW = L_DASH;
LCDDisplay();
}
}
/*;======================================================================
;
;
Display a Code
;
INPUT: CodeW = 16-bits
;
;======================================================================*/
void LCDDisplay(void)
{
unsigned int c;
//;
//;
//;
//;
X---h
*SegPtr--X--h
*SegPtr---X-h
*SegPtr----Xh
*SegPtr--
=
(unsigned char)(( (CodeW & 0xf000) >> 12 ) & 0xf);
=
(unsigned char)(( (CodeW & 0x0f00) >> 8 ) & 0xf);
=
(unsigned char)(( (CodeW & 0x00f0) >> 4 ) & 0xf);
=
(unsigned char )( CodeW & 0x000f);
}
/*;======================================================================
;
Blink on
;======================================================================*/
void SrvBlinkOn()
{
Branch( (int *)ServiceOn, BlinkOnType);
}
/*;======================================================================
;
Blink Off
;======================================================================*/
void SrvBlinkOff()
{
Branch( (int *)ServiceOff, BlinkOffType);
}
/*;======================================================================
;
HOUR On
14-45
Software for the LCD Demo Application
;======================================================================*/
void HourOn()
{
SegPtr = (char *)( HOURS_10th_Pt);
if(Curr_Hours != 0)
DisplayHours(Curr_Hours);
else
Display2Dashs();
}
/*;======================================================================
;
MINUTE On
;======================================================================*/
void MinuteOn()
{
SegPtr = (char *)( MINUTES_10th_Pt);
if(Curr_Minutes != 0)
DisplayMinutes(Curr_Minutes);
else
Display2Dashs();
}
/*;======================================================================
;
HOUR Off
;======================================================================*/
void
HourOff()
{
SegPtr = (char *)(HOURS_10th_Pt);
*SegPtr-- = 0;
*SegPtr = 0;
SegPtr = (char *)(HOURS_Unit_Pt);
*SegPtr-- = 0;
*SegPtr = 0;
}
/*;======================================================================
;
MINUTE Off
;======================================================================*/
void
MinuteOff()
{
SegPtr = (char *)(MINUTES_10th_Pt);
*SegPtr-- = 0;
*SegPtr = 0;
SegPtr = (char *)(MINUTES_Unit_Pt);
*SegPtr-- = 0;
*SegPtr = 0;
}
/*;======================================================================
;
Display '--'
;
input: hl = display memory address
;======================================================================*/
void Display2Dashs()
{
DisplayACharacter('-');
DisplayACharacter('-');
}
/*;======================================================================
;
Display an hour in HOUR field
;
Input: a = hours
;======================================================================*/
void
DisplayHours(unsigned char hrs)
{
14-46
Software for the LCD Demo Application
if(hrs < 10)
{
//; 0 AM to 9 AM
DigitDisplay(0);
SegPtr = (char *)(HOURS_Unit_Pt);
DigitDisplay(hrs);
}
if( hrs > 9 && hrs <= 12)
{
//; 10 AM to 12 NOON
DigitDisplay(1);
SegPtr = (char *)(HOURS_Unit_Pt);
DigitDisplay(hrs-10);
}
if( hrs < 12 && hrs < 21)
{
//; 1 PM to 9 PM
DigitDisplay(0);
SegPtr = (char *)(HOURS_Unit_Pt);
DigitDisplay(hrs-12);
}
if(hrs >= 22)
{
//; 10 PM to 12 MIDNIGHT
DigitDisplay(1);
SegPtr = (char *)(HOURS_Unit_Pt);
DigitDisplay(hrs-22);
}
}
/*;======================================================================
;
Display minutes in MINUTE field
;
Input: a = minutes
;======================================================================*/
void
DisplayMinutes( unsigned char min)
{
//;
//;
MINUTE: xx
//;
SegPtr = (char *)( MINUTES_10th_Pt);
DisplayAField(min);
}
/*;======================================================================
;
Display seconds in SECONDS field
;
Input: a = seconds
;======================================================================*/
void
DisplaySeconds(unsigned char sec)
{
SegPtr = (char *)(SECONDS_10th_Pt);
DisplayAField(sec);
}
/*;======================================================================
;
;======================================================================*/
void
DisplayAField(unsigned char cdata )
{
DigitDisplay( cdata/10);
DigitDisplay( cdata%10 );
}
14-47
Software for the LCD Demo Application
C Language Program: DEMO_TOD.C
#pragma interrupt INTTM3 WatchTimer RB1
/*;****************************************************************************
;
File name: DEMO_TOD.C
;
Date: 1/29/98
;****************************************************************************
;
Description:
;
; This program is to demonstrate the watch timer in the µPD78308 microcontroller.
; The watch timer control registers (TCL2, and TMC2)) are used to configure
; the watch timer function.
; The resolution of the Watch timer time base is selectable as either 0.25
; or 0.5 seconds, when 4.19 MHz (standard: 4.194304 MHz) main system clock is
; used.
; Since there is no interrupt vector for 0.5-second interval, the watch
; timer's interval time interrupt (INTT3) should be used to check if
; 0.5 second has passed.
;=============================================================================
; The sample program will set minute, hour, and day with 0.5-second time base.
; The interval time is set to 15.6 ms. The interval timer is used to
; check 0.5-second flag WTIF set. If so, increment the 0.5-second count.
;============================================================================*/
#include "DEMO.h"
char t2 = 20;
//;
//;
//;
__sreg
__sreg
__sreg
__sreg
__sreg
__sreg
Time of day by Watch timer mode
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
char
char
char
char
char
char
Seconds; //Seconds
Minutes; //Minutes
Hours;
//Hours
Days;
//Days
Interval_timer;
BlinkPeriod;
bit HalfSecondFlag; //1/2 seconds toggle flag
bit ASecondFlag;
extern
extern
bit BlinkFlag;
bit BlinkOnOffFlag;
extern __sreg unsigned char
extern __sreg unsigned char
extern __sreg unsigned char
extern
extern
extern
void
void
char
BlinkOnType;
BlinkOffType;
Curr_Field_Number;
SrvBlinkOff();
SrvBlinkOn();
CheckKeyOn();
//;======================================================================
//;
Init. Time of day
//;======================================================================
void Init_TOD()
{
14-48
Software for the LCD Demo Application
/* ;====================================================================
;
TCL2 - Timer clock select register 2
;
;
x x x 0 x x x x
;
| | | | | | | |__ TCL2.0 (Watchdog timer count clock selection)
;
| | | | | | |____ TCL2.1 (Watchdog timer count clock selection)
;
| | | | | |______ TCL2.2 (Watchdog timer count clock selection)
;
| | | | |________ TCL2.3 (Reserved)
;
| | | |__________ TCL2.4 (= 0, Select 4.19 MHz/27)
;
| | |____________ TCL2.5 (Buzzer output frequency selection)
;
| |______________ TCL2.6 (Buzzer output frequency selection)
;
|________________ TCL2.7 (Buzzer output frequency selection)
;
;====================================================================*/
TCL2 = 0b00000000;
/*;====================================================================
;
;
TMC2 - Watch timer mode control register
;
;
0 1 0 1 0 1 1 0
;
| | | | | | | |__ TMC2.0 (= 0, Watch Operating Mode Selection)
;
| | | | | | |____ TMC2.1 (= 1, Prescaler Operation control enable)
;
| | | | | |______ TMC2.2 (= 1, 5-bit counter operation control enable)
;
| | | | |________ TMC2.3 (= 0, 0.5 second for Wach flag set time)
;
| | | |__________ TMC2.4 (= 1, Prescaler interval timer - 15.6 ms (fxx =4.19 MHz)
;
| | |____________ TMC2.5 (= 0, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
| |______________ TMC2.6 (= 1, Prescaler interval timer - 15.6 ms (fxx = 4.19 MHz)
;
|________________ TMC2.7 (Reserved = 0)"
)
;
;====================================================================*/
TMC2 = 0b01010110;
//;
//;
Clear time variables
//;
Seconds=0;
Minutes=0;
Hours=0;
Days= 0;
HalfSecondFlag = 0;
ASecondFlag = 0;
}
/*;======================================================================
;
Module name: INTTM3 Watch timer Interval Time Interrupt
;
;
Description:
;
.Set Watch time variables
;
;
Operation:
;
. Flip the HalfSecondFlag
;
. If HalfSecondFlag = 0 then incr. seconds
;
. If Seconds == 60 incr. Minutes
;
. If Minutes == 60 incr. Hours
;
. If Hours
== 24 incr. Days
;
;======================================================================*/
void WatchTimer()
{
if( Interval_timer ) Interval_timer--;
if( BlinkFlag )
{
Interval_timer = BlinkPeriod;
if(BlinkOnOffFlag)
14-49
Software for the LCD Demo Application
{
//; Blink OFF
BlinkOnOffFlag = 0;
SrvBlinkOff();
}
else
{
//; Blink ON
BlinkOnOffFlag = 1;
SrvBlinkOn();
}
}
//;
//;
Test .5 second flag
//;
if( !WTIF) return;
//;
WTIF = 0;
//;
//;
.5 seconds passed
//;
if( !HalfSecondFlag)
{
HalfSecondFlag=1;
return;;
}
//;
HalfSecondFlag=0;
//;
Seconds++;
if(Seconds < 60) return;;
Seconds = 0;
Minutes++;
if(Minutes < 60) return;;
Minutes = 0;
Hours++;
if(Hours < 24) return;;
Hours = 0;
Days++;
}
/*;======================================================================
;
Delay 1/2 Seconds
;
If key is depressed then quit
;
not zero,
;======================================================================*/
char Delay500Msec()
{
Interval_timer = 5000/BaseTime;
while( !CheckKeyOn())
{
if( !Interval_timer)
return 0;
}
return 1;
}
/*;======================================================================
;
;
Set Blink Parameters
;
Input: Interval_timer
;
14-50
Software for the LCD Demo Application
;======================================================================*/
void SetBlink()
{
Interval_timer = BlinkPeriod;
BlinkOnType = Curr_Field_Number;
BlinkOnOffFlag= 0;
BlinkFlag = 1;
}
/*;======================================================================
;
;
Clear Blink Parameters
;
;======================================================================*/
void
ClearBlink()
{
BlinkOnOffFlag= 0;
BlinkFlag = 0;
}
14-51
Software for the LCD Demo Application
C Language Program: DEMO_KEY.C
/*;************************************************************************
;
;
File name: DEMO_KEY.C
;
Date: 1/29/98
;****************************************************************************
;
Description:
;
;
;The example program is a key input module that inputs signals from a key matrix
;of 4 x 4 keys. The keys can be pressed successively, and two or more keys can
;be pressed simultaneously. In the circuit shown in this example, the lower 4
;bits of port3 (P30-P33) are used as key scan signals, and port 11 (port 4 if µPD78054 or µPD78078)
;is used as key return signals. As the pull-up resister of port 11 for key return, the
;internal resistor set by software is used.
;
;Port 11 of the K0 family has a function to detect the falling edges of the
;eight port pins in parallel. If port 11 is used for key return signals,
;therefore, the standby mode can be released through detection of a falling
;edge, by key input.
;
;The input keys are stored to RAM on a bit/key basis. The RAM bit
;corresponding to a pressed key is set and the bit corresponding to a released
;key is cleared. By testing the RAM data on a 1-bit basis starting
;from the first bit, the key status can be checked. To absorb key debouncing,
;the key is assumed to be valid when four successive key codes coincide with a
;given code. For example, if a key code is sampled every 16 msec, debouncing of
;48 to 64 ms can be absorbed.
;
;
; Key number:
;
0 = P114 + P30
;
1 = P114 + P31
;
2 = P114 + P32
;
3 = P114 + P33
;
;
4 = P115 + p30
;
5 = P115 + P31
;
6 = P115 + P32
;
7 = P115 + P33
;
;
8 = P116 + P30
;
9 = P116 + P31
;
10 = P116 + P32
;
11 = P116 + P33
;
;
12 = P117 + P30
;
13 = P117 + P31
;
14 = P117 + P32
;
15 = P117 + P33
;
P4 is used instead of P11 if µPD78054 or µPD78078.
;
;================================================================== ====
;
The system has a main system clock (5 MHz) and a subsystem clock(32.768 kHz).
;
The LCD and Watch timer are run under the subsystem clock.
;
Normal operation is under the subsystem clock and when a key is depressed, the
;
main system clock is activated.
;======================================================================*/
#include "DEMO.H"
//#define D054 1 //for µPD78054 and 078
bit KeyOnFlag;
14-52
// key on flag if it is 1
Software for the LCD Demo Application
__sreg unsigned char KeyNumber;
char CheckKeyOn();
void KeyScan(void);
void Init_Key();
/*;======================================================================
;
MAIN
;======================================================================*/
void Init_Key()
{
/*;====================================================================
;
Key Return mode register(KRM)
;
;
0 0 0 0 0 1 0 0
;
| | | | | | | |__ KRM.0 (= 0, Not detected key return signal)
;
| | | | | | |____ KRM.1 (= 1, Standby mode release enabled)
;
| | | | | |______ KRM.2 (= 1, Select p114-p117 as key return signal port)
;
| | | | |________ KRM.3 (= 0, Select p114-p117 as key return signal port)
;
| | | |__________ KRM.4 (= 0, Reserved)
;
| | |____________ KRM.5 (= 0, Reserved)
;
| |______________ KRM.6 (= 0, Reserved)
;
|________________ KRM.7 (= 0, Reserved)
;
;
If µPD78054 or µPD78078 KRM.2 and KRM.3 cannot be defined.
;
;====================================================================*/
KRM = 0B00000100;
//; Set Scan Ports
PM3=0B11110000; //P30-P33 Output
P3 = 0B00000000; //Set P30-P33 to Low
//; Set Sense Ports
#ifdef D054
#else
PM11= 0b11110000; //P114-P117 as input
#endif
//;
//;
Pull-up resistor option on P11
//;
#ifdef D054
PUOL = 0b00010000;
#else
PUOH = 0b00001000;
#endif
}
/*;======================================================================
;
Key scan module
;
;
The key matrix is 4 x 4. There are four scan port (P30-P33) and
;
four key return signal ports (P114-P117).
;
Debounce count sets to 4
;
;
Key number:
;
0 = P114 + P30
;
1 = P114 + P31
;
2 = P114 + P32
;
3 = P114 + P33
;
4 = P115 + P30
;
5 = P115 + P31
;
6 = P115 + P32
14-53
Software for the LCD Demo Application
;
7 = P115 + P33
;
8 = P116 + P30
;
9 = P116 + P31
;
10 = P116 + P32
;
11 = P116 + P33
;
12 = P117 + P30
;
13 = P117 + P31
;
14 = P117 + P32
;
15 = P117 + P33
;
;
Return:
;
cf = 1 if a key depressed
;
and KeyNumber with key number
;
;
cf = 0 if no key depressed.
;
;
Registers:
;
a = Scratch
;
b = Total row or column numbers
;
c = Sense port
;
d = Row x 4 + column
;
e = Column port
;
h = Current key number
;
l = Number of debounces
;
;======================================================================*/
void KeyScan(void)
{
#asm
;
;
;
Find a key
push
push
push
push
ax
bc
de
hl
clr1
mov
mov
_KeyOnFlag
h,#0ffh ;no key flag
l,#3
KeyScanLoop:
and
$if(D054)
mov
$else
mov
$endif
and
cmp
bz
mov
mov
mov
mov
CheckRow:
mov
and
bz
; shift to left
mov
clr1
rol
14-54
P3,#11110000b
a,P4
a,P11
a,#11110000b; mask low nibble
a,#11110000b;all high
$NotFound;no key depressed
c,a
d,#0;key number
x,#00010000b;find a row
b,#4;4 rows
a,x
a,c
$RowFind;find the row
a,x
cy
a,1
Software for the LCD Demo Application
mov
x,a
; update row * column
mov
a,d
add
a,#4
mov
d,a
dbnz
b,$CheckRow
;
;
Not Found
;
NotFound:
mov
_KeyNumber,#0
push
hl
push
de
push
bc
push
ax
ret
;
;
Row Find. Find Column
;
d = row*column
;
x = row position
;
RowFind:
mov
e,#00000001b;find a column
mov
b,#4;4 columns
CheckCol:
mov
a,e
mov
P3,a;set to high
$if(D054)
mov
a,P4
$else
mov
a,P11
$endif
and
a,x
bnz
$ColFind
; shift to left
clr1
cy
mov
a,e
rol
a,1
mov
e,a
;
;
Incr. key number
;
inc
d
dbnz
b,$CheckCol
br
NotFound;not found
;
ColFind:
mov
a,d
cmp
a,h
bz
$CheckDebounce ; ok
;
;
Restart key scan
;
mov
h,a
;
;
Decr. debounce count
;
CheckDebounce:
dec
l
bnz
$KeyScanLoop
;
KeyFound:
mov
a,h
mov
_KeyNumber,a
14-55
Software for the LCD Demo Application
set1
_KeyOnFlag
push
push
push
push
ret
hl
de
bc
ax
#endasm
}
/*;======================================================================
;
Wait for a key released
;======================================================================*/
void WaitKeyReleased()
{
while( !CheckKeyOn );
}
/*;======================================================================
;
Check key on or off
;
return with ZF = 1 if no key is on
;======================================================================*/
char CheckKeyOn()
{
unsigned char i;
P3 &= 0b11110000;
NOP();
NOP();
NOP();
#ifdef D054
i = P4;
#else
i = P11;
#endif
i &= 0b11110000;
if( i == 0b11110000)
return 0;
else
return 1;
}
14-56
Some of the information contained in this document may vary from country to country. Before using any NEC product in your
application, please contact a representative from the NEC office in your country to obtain a list of authorized representatives and
distributors who can verify the following:
Device availability
Ordering information
Product release schedule
Availability of related technical literature
Development environment specifications (for example, specifications for third-party tools and components, host computers,
power plugs, AC supply voltages, and so forth)
Network requirements
In addition, trademarks, export restrictions, and other legal issues may also vary from country to country.
NEC Electronics Inc. (U.S.)
Santa Clara, California
Tel: 800-366-9782
Fax: 800-729-9288
NEC Electronics (France) S.A.
Velizy-Villacoublay, France
Tel: 01-30-67 58 00
Fax: 01-30-67 58 99
NEC Electronics Hong Kong Ltd.
Seoul Branch
Seoul, Korea
Tel: 02-528-0303
Fax: 02-528-4411
NEC Electronics (Germany) GmbH
Duesseldorf, Germany
Tel: 0211-65 03 02
Fax: 0211-65 03 490
NEC Electronics (France) S.A.
Spain Office
Madrid, Spain
Tel: 01-504-2787
Fax: 01-504-2860
NEC Electronics Singapore Pte. Ltd.
United Square, Singapore 1130
Tel: 253-8311
Fax: 250-3583
NEC Electronics (UK) Ltd.
Milton Keynes, UK
Tel: 01908-691-133
Fax: 01908-670-290
NEC Electronics (Germany) GmbH
Scandinavia Office
Taeby, Sweden
Tel: 08-63 80 820
Fax: 08-63 80 388
NEC Electronics Taiwan Ltd.
Taipei, Taiwan
Tel: 02-719-2377
Fax: 02-719-5951
NEC Electronics Italiana s.r.l.
Milano, Italy
Tel: 02-66 75 41
Fax: 02-66 75 42 99
NEC Electronics Hong Kong Ltd.
Hong Kong
Tel: 2886-9318
Fax: 2886-9022/9044
NEC do Brasil S.A.
Sao Paulo-SP, Brasil
Tel: 011-889-1680
Fax: 011-889-1689
NEC Electronics (Germany) GmbH
Benelux Office
Eindhoven, the Netherlands
Tel: 040-2445845
Fax: 040-2444580
For literature, call 1-800-366-9782 7 a.m. to 6 p.m. Pacific time
or FAX your request to 1-800-729-9288
or visit our web site at www.nec.com
NEC Electronics Inc.
CORPORATE HEADQUARTERS
2880 Scott Boulevard
Santa Clara, CA 95050-2554
TEL 408-588-6000
In North America: No part of this document may be copied or reproduced in any form or by any means without
the prior written consent of NEC Electronics Inc. (NECEL). The information in this document is subject to change
without notice. All devices sold by NECEL are covered by the provisions appearing in NECEL Terms and
Conditions of Sales only. Including the limitation of liability, warranty, and patent provisions. NECEL makes no
warranty, express, statutory, implied or by description, regarding information set forth herein or regarding the
freedom of the described devices from patent infringement. NECEL assumes no responsibility for any errors that
may appear in this document. NECEL makes no commitments to update or to keep current information
contained in this document. The devices listed in this document are not suitable for use in applications such as,
but not limited to, aircraft control systems, aerospace equipment, submarine cables, nuclear reactor control
systems and life support systems. “Standard” quality grade devices are recommended for computers, office
equipment, communication equipment, test and measurement equipment, machine tools, industrial robots,
audio and visual equipment, and other consumer products. For automotive and transportation equipment, traffic
control systems, anti-disaster and anti-crime systems, it is recommended that the customer contact the
responsible NECEL salesperson to determine the reliability requirements for any such application and any cost
adder. NECEL does not recommend or approve use of any of its products in life support devices or systems or in
any application where failure could result in injury or death. If customers wish to use NECEL devices in
applications not intended by NECEL, customer must contact the responsible NECEL sales people to determine
NECEL's willingness to support a given application.
©1998 NEC Electronics Inc./Printed in U.S.A.
U13218EU1V0AN00