Mixed Signal Embedded Programming
Mixed Signal Embedded Programming
EMBEDDED
PROGRAMMING
as a Software Engineer in Philips India in the Consumer Electronics division, he
joined Singapore Polytechnic in 1989 where he is currently a Senior Lecturer in the
School of Electrical and Electronic Engineering. Since September 2002 he is a
Visiting Senior Lecturer at the Institute of Information Sciences and Technology,
Massey University, New Zealand, and is working towards his Ph.D. in Intelligent
Control of Multi-Agent Collaborative Systems.
His current research interests are in the area of Embedded Systems, Robotics,
Real-time Vision Processing, Behavior Programming for Multi-Agent Collaboration,
and Automated Testing & Measurement Systems. He has published and present-
ed over 30 research papers in various conferences and journals. He is a member
with Field-Programmable
of IEEE.
Mixed-Signal µControllers
Ms. Moi Tin Chew got her B.Sc. (Honors) in Electrical & Electronic Engineering
from North East London Polytechnic (UK) in 1981 and M.Sc. in Information
Engineering from the City University, London (UK) in 1991. She has over twenty
years of teaching and research experience in various institutions of higher learn-
ing in different countries. From 2004 she is with Monash University (Malaysia
Campus). Her teaching and research interests include Computer and
Microprocessor Applications, Microprocessor Interfacing Techniques, Digital &
Analogue Electronics, Logic Design, and Electrical Engineering. She has super-
vised a large number of research and development projects for the industry and
academia. She is an author of several publications and research presentations
at conferences.
Ms. Moi Tin Chew is a registered Chartered Engineer (UK) and a member of the
Institution of Electrical Engineers (UK).
© 2005
To
i
Chapter 5 System Clock, Crossbar and GPIO ...……. 83
5.0 Introduction 85
5.1 Oscillator Programming Registers 86
5.2 Watchdog Timer 88
5.3 Digital Crossbar 90
5.4 GPIO 93
5.5 Crossbar and GPIO SFRs 96
5.6 Ports 4 through 7 103
5.7 Tutorial Questions 106
Chapter 6 C8051F020 C Programming ………….……109
6.0 Introduction 110
6.1 Register Definitions, Initialization and Startup Code 110
6.2 Programming Memory Models 111
6.3 C Language Control Structures 115
6.4 Functions 122
6.5 Interrupt Functions 123
6.6 Re-entrant Functions 127
6.7 Pointers 127
6.8 Summary of Data Types 129
6.9 Tutorial Questions 130
Chapter 7 Expansion Board for C8051F020 Target
Board …………………………………………. 131
7.0 Introduction 132
7.1 Starting a Project 134
7.2 Blinking Using Software Delays 135
7.3 Blinking Using a Timer 138
7.4 Programming the LCD 142
7.5 Reading Analog Signals 151
7.6 Expansion Board Pictures 153
7.7 Circuit Diagram of the Expansion Board 154
7.8 Expansion Board Physical Component Layout 155
Chapter 8 Timer Operation and Programming ….…. 157
8.0 Introduction 158
8.1 Functional Description 159
8.2 Timer Programming 160
8.3 Timer SFRs 161
8.4 Timers 0 and 1 Operating Modes 161
8.5 Timers 2, 3 & 4 Operating Modes 164
8.6 CKCON Register 170
8.7 Timers 0 and 1 SFRs 171
ii
8.8 Timer 2 SFRs 173
8.9 Timer 3 SFRs 175
8.10 Timer 4 SFRs 176
8.11 Timer 2 - C Programming Example 178
8.12 Tutorial Questions 181
Chapter 9 ADC and DAC ………………………………. 183
9.0 Introduction 185
9.1 12-Bit ADC (ADC0) 186
9.2 Data Word Conversion Map (12-bit) 188
9.3 Programming ADC0 189
9.4 ADC0 SFRs 195
9.5 8-Bit ADC (ADC1) 199
9.6 Data Word Conversion Map (8-bit) 201
9.7 Programming ADC1 201
9.8 ADC1 SFRs 206
9.9 12-Bit DACs (DAC0 and DAC1) 208
9.10 Programming the DACs 210
9.11 DAC0 SFRs 212
9.12 DAC1 SFRs 213
9.13 Tutorial Questions 214
Chapter 10 Serial Communication ……………..……… 215
10.0 Introduction 216
10.1 UART0 and UART1 217
10.2 Programming the UARTs 219
10.3 Operation Modes 220
10.4 Interrupt Flags 225
10.5 UARTx SFRs 227
10.6 Blinking LED at Different Frequencies –
C Programming Example 229
10.7 Tutorial Questions 233
Chapter 11 Interrupts ……………………………………. 235
11.0 Introduction 236
11.1 Interrupt Organization 236
11.2 Interrupt Process 239
11.3. Interrupt Vectors 239
11.4 External Interrupts 240
11.5 Interrupt Latency 241
11.6 Interrupt SFRs 241
11.7 Tutorial Questions 249
Index ………………………....………………………………. 251
iii
iv
Preface
v
Whereas, it is precisely at this stage of learning that a leaner needs to be
hand-held and guided. This is where this book comes in. It is pitched for
the novice; someone just starting to learn microcontrollers. Only the
relevant information is presented in a concise manner which is simple to
read and comprehend. All the clutter has been cut out to make learning
easy and interesting. At the same time all the knowledge that is required
to accomplish a project is covered in fair details.
vi
book we do provide some examples in assembly code but the majority
are in C. So that a reader, with no prior knowledge of C programming, is
not disadvantaged, there is a complete chapter on C programming
(Chapter 6). While beginners must definitely spend time reading this
chapter, even experienced C programmers will find it worthwhile to
browse through it as there are many peculiarities and special features of
the KeilTM C compiler which are different from the ANSI C and are related
to the hardware architecture of the C8051F020 micro-controller.
Chapter 1 gives a brief overview of the basic 8051 architecture. Readers
intending to learn more about 8051 are advised to first read another text
book; a few are listed in the Bibliography.
The Silicon Labs C8051F020 micro-controller architecture is introduced
in Chapter 2. The memory organisation and the various on-chip
peripheral devices are briefly explained to give the reader a first taste of
the features of the micro-controller.
Chapter 3 details the addressing modes and the complete instruction set
of 8051. The assembler directives are summarised in Chapter 4.
Readers not intending to program in assembly language can safely skip
reading these two chapters.
The digital crossbar of the C8051F020 micro-controller is at the heart of
the programming architecture and one must master this early to exploit
the flexibility offered by the micro-controller in configuring peripherals
and external interfaces. Chapter 5 details not only the crossbar; it also
introduces other important features like the watchdog timer and
programming the oscillator.
Chapter 6 is all about learning to write programs in C. All the programs
that are listed in the text book have been written and tested using KeilTM
C compiler. While this compiler supports most of the ANSI C features, it
is in many respects ‘closer to the hardware’. A ‘must read’ for every
reader.
In Chapter 7 we present the design of an expansion board which is used
in conjunction with the Silicon Labs Micro-Controller Development Board
C8051F020-TB. The development board has rudimentary peripherals
built on it – it has the micro-controller chip, oscillator, power supply, RS-
232 Serial communication connector and just one push-button switch
and an LED. The expansion board provides additional inputs for
ADC/DAC, a LCD display, additional LEDS and several toggle and push-
button switches. The expansion board will be very handy for learners to
vii
carry out experiments while learning the basics of embedded
programming. The complete design of the expansion board is provided
so that it can be built by anybody with some skills in PCB soldering. At
some stage, it is envisaged that the expansion board will be available
from Silicon Laboratories as a standard product.
C8051F020 has a very rich set of timers which are very handy for
advanced applications. They are also used in conjunction with ADC/DAC
and for serial communication. Timer operations and programming are
detailed in Chapter 8.
Chapter 9 introduces the on-chip ADCs and DACs and how to program
them. There are two multi-channel ADCs offering 12-bit and 8-bit
conversion resolution, and two 12-bit DACs.
Chapter 10 deals with the programming aspects of the Serial
Communication using UARTs. Different communication modes and
programming the Baud rate generator are covered in detail.
Interrupts have been immensely enhanced and extended in C8051F020
and are much more elaborate than the basic 8051 interrupts. These are
covered in Chapter 11.
viii
Acknowledgements
Several wonderful people have contributed to the successful completion
of this book and the authors wish to extend their sincere thanks to them
for their fabulous work.
Dr Chris Messom, Institute of Information and Mathematical Sciences,
Massey University, wrote Chapter 6, C8051F020 C Programming.
Ken Mercer, Institute of Information Sciences and Technology, Massey
University, wrote Chapter 7, Expansion Board for C8051F020 Target
Board. Ken also designed and built the expansion board and for this he
was ably supported by our student, Jonathan Seal. Together they have
done a wonderful job.
James Cheong, graduate of IIST, Massey University, contributed by way
of initial script typing and building the data tables.
Dr Subhas Mukhopadhyay, Institute of Information Sciences and
Technology, Massey University, made several valuable suggestions to
improve the book overall.
Dr Douglas R. Holberg, Director of Engineering, Silicon Laboratories,
for his immense enthusiasm and support for the project.
Last, but not the least, the authors gratefully acknowledge the efforts put
in by Prof. Serge Demidenko, Monash University, for pouring over the
manuscript and painstakingly editing it. His suggestions and inputs have
been invaluable.
ix
Bibliography
I. Scott MacKenzie, The 8051 Microcontroller, Upper Saddler River,
N.J.: Prentice Hall, 1999
Sencer Yeralan, Helen Emery, The 8051 cookbook for Assembly and
C : with experiments in mechatronics and robotics, Gainesville, Fla.:
Rigel Press, 2000
x
1
8051 Architecture Overview
1.0 Introduction 2
1.1 Overview of 8051 Micro-controller 2
Ports, Address Latch Enable (ALE), Reset (RST), System
Clock - Oscillator
1.2 On-Chip Memory Organization 5
General Purpose RAM, Bit-addressable RAM, Register
Banks
1.3 Special Function Registers 11
Program Status Word, The B Register, Stack Pointer, Data
Pointer, Parallel Input/Output Port Registers, Timer
Registers, Serial Communication Registers, Interrupt
Management Registers
1.4 Multiplexing Data and Address Bus 17
1.5 Tutorial Questions 19
2 Chapter 1 8051 Architecture Overview
1.0 Introduction
In 1980, Intel introduced 8051, which is the first device in the MCS-51™
family of microcontroller, to the market. There are other second source
suppliers of the ICs; these include Silicon Laboratories, Atmel, Philips,
Dallas Semiconductor and several others.
Intel 8051 has
been around
for over two Though more than 20 years have passed since its introduction, the 8051
decades but is is still as relevant today as it was in those days. In recent years some
still very
popular. companies have incorporated many different features into the basic 8051
chip and one such company is Silicon Laboratories. In 2000, Silicon
Laboratories manufactured a field programmable, mixed signal chip
(C8051F020) based on the 8051 core CPU. The chip is offered in
different combinations of clock speed, FLASH and on-chip RAM size.
They also offer different digital and analog peripherals such as:
♦ I/O ports
♦ Timers/Counters
♦ UARTs (Universal Asynchronous Receiver Transmitters)
♦ SPI and SMBus serial transceivers
♦ ADC/DAC (Analog-to-Digital Converters / Digital-to-Analog
Converters)
♦ Temperature Sensor
/INT0 /INT1 T0 T1
Other
interrupts
8051 CPU
From Crystal
Oscillator or RC ALE /PSEN P3 P2 P1 P0 TxD RxD
network (Address/data)
Ports
The 8051 consists of 4 standard Ports (0, 1, 2, and 3). The ports are
Intel 8051 has multi-purpose. In a minimum-component basic design without expansion,
four multi-
purpose they are used as general purpose I/O. For larger designs incorporating
flexible ports
which are bit- external memory, the ports function as multiplexed address and data
and byte- buses. With careful hardware design and satisfying the timing
addressable.
requirements of 8051, the external memory can be easily and
seamlessly made accessible to the programmer. In addition, the ports
may be controlled by a digital peripheral, UART or external interrupts.
The ports are both bit- and byte-addressable. For example, the pins of
Port 0 are designated as P0.0, P0.1, P0.2, etc. Figure 1.2 shows the pin
assignments of 8051.
the port lines are available for data input or output. When ALE falls,
signaling the beginning of the second phase, the address latch outputs
remain fixed and are no longer dependent on the latch input. Later in the
second phase, the Data Bus controls the state of the AD[0:7] at the time
/RD or /WR is asserted.
40 VCC
XTL2 18
39 P0.0 AD0
XTL1 19 38 P0.1 AD1
37 P0.2 AD2
36 P0.3 AD3
35 P0.4 AD4
34 P0.5 AD5
RXD P3.0 10 33 P0.6 AD6
TXD P3.1 11 32 P0.7 AD7
/INT0 P3.2 12
/INT1 P3.3 13 21 P2.0 AD8
T0 P3.4 14 8051 22 P2.1 AD9
T1 P3.5 15 23 P2.2 AD10
/WR P3.6 16 24 P2.3 AD11
/RD P3.7 17 25 P2.4 AD12
26 P2.5 AD13
27 P2.6 AD14
RST 9 28 P2.7 AD15
/EA 31 1 P1.0
to to
ALE 30
8 P1.7
/PSEN 29 20 VSS
Reset (RST)
Reset circuitry allows the 8051 to be easily placed in a predefined default
condition. On entry to the reset state, the following occur:
♦ The MCU halts program execution
♦ Special Function Registers (SFRs) are initialized to their defined
reset values
♦ External port pins are forced to a known state
♦ Interrupts and timers are disabled
Sources of reset include Power-on Reset and External Reset.
Chapter 1 8051 Architecture Overview 5
XTAL1
The on-chip
oscillator
needn’t be
driven by a
crystal; a TTL
clock source XTAL2
will suffice.
The nominal crystal frequency is 12 MHz for most ICs in the MCS-51™
family. The on-chip oscillator needn’t be driven by a crystal; it can be
replaced by a TTL clock source connected to XTAL1 instead.
FFFFH
~ ~
0FFFH 0FFFH
/EA=0 /EA=1
External Internal
0000H 0000H
/PSEN
External
0FFFFH
Internal
FFH
Special Function ~ ~
Upper 128 Registers
Indirect
addressing Direct
80H Addressing
7FH
Lower 128
/RD
Direct/Indirect
Addressing
/WR
00H 0000H
Figure 1.5 Internal & External Data memory (Random Access Memory) Organization
As shown in Figure 1.6a and 1.6b, the internal data memory space is
divided into register banks (00H-1FH), bit-addressable RAM (20H-2FH),
general purpose RAM (30H-7FH), and special function registers (80H-
FFH).
In the Lower 128 bytes of RAM, 4 banks of 8 registers each are available
to the user. The 8 registers are named R0 through R7. By programming
two bits in the Program Status Word (PSW), an appropriate register bank
can be selected.
In the Special Function Register (SFR) block (Figure 1.6b) registers
which have addresses ending with OH or 8H are byte- as well as bit-
addressable. Some registers are not bit-addressable at all. For example,
the Stack Pointer Register (SP) and Data Pointer Register (DPTR) are
not bit-addressable.
8 Chapter 1 8051 Architecture Overview
Byte
Bit Address
Address
7F
General
Purpose
RAM
30
B 2F 7F 7E 7D 7C 7B 7A 79 78
i 2E 77 76 75 74 73 72 71 70
t 2D 6F 6E 6D 6C 6B 6A 69 68
2C 67 66 65 64 63 62 61 60
A 2B 5F 5E 5D 5C 5B 5A 59 58
d 2A 57 56 55 54 53 52 51 50
d 29 4F 4E 4D 4C 4B 4A 49 48
r 28 47 46 45 44 43 42 41 40
e 27 3F 3E 3D 3C 3B 3A 39 38
s 26 37 36 35 34 33 32 31 30
s 25 2F 2E 2D 2C 2B 2A 29 28
a 24 27 26 25 24 23 22 21 20
b 23 1F 1E 1D 1C 1B 1A 19 18
l 22 17 16 15 14 13 12 11 10
e 21 0F 0E 0D 0C 0B 0A 09 08
20 07 06 05 04 03 02 01 00
1F
Bank 3
18
17
Bank 2
10
0F
Bank 1
08
07
Default Register Bank for R0 – R7
00
Byte
Bit Address
Address
FF
F0 F7 F6 F5 F4 F3 F2 F1 F0 B
E0 E7 E6 E5 E4 E3 E2 E1 E0 ACC
D0 D7 D6 D5 D4 D3 D2 - D0 PSW
B8 - - - BC BB BA B9 B8 IP
B0 B7 B6 B5 B4 B3 B2 B1 B0 P3
A8 AF - - AC AB AA A9 A8 IE
A0 A7 A6 A5 A4 A3 A2 A1 A0 P2
90 97 96 95 94 93 92 91 90 P1
MOV R1,#62H
MOV A,@R1
The first instruction uses immediate addressing to transfer the value 62H
into register R1. The second instruction uses indirect addressing to
transfer the data “pointed to by R1” into the accumulator.
Bit-addressable RAM
There are 128 general purpose bit-addressable locations at byte
addresses 20H through 2FH. For example, to clear bit 78H, the following
instructions could be used:
CLR 78H
Referring to Figure 1.6a, note that “bit address 78H” is the least
significant bit (bit 0) at “byte address 2FH”. The instruction has no effect
on the other bits at this address. The same operation can also be
performed as follows:
Chapter 1 8051 Architecture Overview 11
MOV A,2FH
ANL A,#11111110B
MOV 2FH,A
Register Banks
The bottom 32 locations of the internal memory, from location 00H to
1FH, contain the register banks. The 8051 instruction set supports 8
registers, R0 through R7. After a system reset these registers are at
addresses 00H to 07H. The following instruction reads the contents of
address 04H into the accumulator A:
SETB 0D3H
SETB 0D4H
12 Chapter 1 8051 Architecture Overview
set bit 3 and 4 in the Program Status Word (PSW.3 and PSW.4), leaving
the other bits unchanged. This will select Bank 3 for registers R0 to R7 at
address locations 18H to 1FH. Since the SETB instruction operates on
bits (not bytes), only the addressed bit is affected.
ADD A,#15
leaves a value of 00H in the accumulator and sets the carry flag in PSW
(PSW.7).
The carry flag is extensively used as a 1-bit register in Boolean
operations on bit-valued data. For example, the following instruction
Chapter 1 8051 Architecture Overview 13
ANDs bit 38H with the carry flag and places the result back in the carry
flag:
ANL C,038H
MOV R0,#2
MOV A,#8
ADD A,R0
test this bit to determine if the result is in the proper range. For 8-bit
signed numbers, the result should be in the range of +127 to –128).
The B Register
The B register, or accumulator B, is at address F0H and is used along
with the accumulator for multiplication and division operations. For
example:
MOV A,#9
MOV B,#5
MUL AB ;9 x 5 = 45 or 2DH, B=0, A=2DH
MOV A,#99
MOV B,#5
MUL AB ;99 x 5 = 495 or 1EFH, B=1, A=EFH
MOV A,#10
MOV B,#5
DIV AB ;10/5 = 2, Remainder=0 , B=0, A=2
MOV A,#99
MOV B,#5
DIV AB ;99/5=19(13H),Remainder=4,B=4,A=13H
Stack Pointer
The stack pointer (SP) is an 8-bit register and is located at address 81H.
Stack operations include “pushing” data on the stack and “popping” data
off the stack. Each time data is pushed on to the stack, SP is
Chapter 1 8051 Architecture Overview 15
MOV A,#20H
MOV SP,#6FH
PUSH ACC
.
.
.
Figure 1.7 Memory snap-shot of the Stack
Data Pointer
The data pointer register (DPTR) is used to access external code or data
memory. It is a 16-bit register located at addresses 82H (DPL, low byte)
and 83H (DPH, high byte). The following instructions load 5AH into the
external RAM location 1040H.
MOV A,#5AH
MOV DPTR,#1040H
MOVX @DPTR,A
The first instruction uses immediate addressing to load the data constant
5AH into the accumulator. The second instruction also uses immediate
addressing to load the 16-bit address constant 1040H into the data
pointer. The third instruction uses indirect addressing to move the value
in A (i.e. 5AH) to the external RAM location whose address is in the
DPTR register (i.e. 1040H). The “X” in the mnemonic “MOVX” indicates
that the move instruction accesses external data memory.
16 Chapter 1 8051 Architecture Overview
SETB P1.5
CLR P1.5
Timer Registers
The 8051
contains two
The basic 8051 contains two 16-bit timer/counters for timing intervals or
16-bit counting events. Timer 0 is located at addresses 8AH (TL0, low byte)
timer/counters
for timing and 8CH (TH0, high byte) and Timer 1 is located at addresses 8BH (TL1,
intervals and low byte) and 8DH (TH1, high byte). The Timer Mode register (TMOD),
counting
events. which is located at address 89H, and the Timer Control register (TCON),
which is located at address 88H, are used to program the timer
operations. Only TCON is bit-addressable. Timer operations and
programming details of C8051F020 are discussed in Chapter 8.
Chapter 1 8051 Architecture Overview 17
Figure 1.8a shows the normal write cycle in the execution of a 8051
instruction. Figure 1.8b shows the hardware connection to de-multiplex
the address and data lines to allow for external memory access.
Memory Cycle
A8-A15 Address
ALE
/WR
D0
D7
8051
74LS373
AD0
P0.0 A0
Latch
AD7
P0.7
A7
ALE EL /OE
P2.0 A8
P2.7 A15
/WR
Figure 1.8b Hardware connection to de-multiplex the address and data bus
Chapter 1 8051 Architecture Overview 19
2.0 Introduction
This chapter gives an overview of the Silicon Labs C8051F020 micro-
controller. On-chip peripherals like ADC and DAC, and other features like
the cross-bar and the voltage reference generator are briefly introduced.
While programming using a high level language, such as C, makes it
less important to know the intricacies of the hardware architecture of the
micro-controller, it is still beneficial to have some knowledge of the
memory organization and special function registers. Thus, these are also
covered in this chapter.
2.1 CIP-51
Silicon Labs’ mixed-signal system chips utilize the CIP-51 microcontroller
core. The CIP-51 implements the standard 8051 organization, as well as
additional custom peripherals. The block diagram of the CIP-51 is shown
in Figure 2.1.
Silicon Labs’ The CIP-51 employs a pipelined architecture and is fully compatible with
mixed-signal
system chips the MCS-51™ instruction set. The pipelined architecture greatly
utilise the CIP-
51 micro-
increases the instruction throughput over the 8051 architecture.
controller core,
which is fully With the 8051, all instructions except for MUL and DIV take 12 or 24
compatible
with 8051
system clock cycles to execute, and is usually limited to a maximum
instruction system clock of 12 MHz. By contrast, the CIP-51 core executes 70% of
sets.
its instructions in one or two system clock cycles, with no instructions
taking more than eight system clock cycles. With the CIP-51's maximum
system clock at 25 MHz, it has a peak throughput of 25 millions of
instructions per second (MIPS). The CIP-51 has a total of 109
instructions. Table 2.1 summarizes the number of instructions that
require 1 to 8 clock cycles to execute.
Chapter 2 Introduction to Silicon Labs’ C8051F020 23
DATA BUS
D8
D8
D8
D8
D8
ACCUMULATOR B REGISTER STACK POINTER
DATA BUS
TMP1 TMP2
SRAM
PSW SRAM
ADDRESS
(256 X 8)
ALU REGISTER
D8
D8
D8
D8 DATA BUS
SFR_ADDRESS
BUFFER D8
SFR_CONTROL
SFR
D8 BUS SFR_WRITE_DATA
DATA POINTER D8
INTERFACE
SFR_READ_DATA
PC INCREMENTER
DATA BUS
D8 MEM_ADDRESS
PROGRAM COUNTER (PC)
MEM_CONTROL
MEMORY
PRGM. ADDRESS REG. A16 INTERFACE MEM_WRITE_DATA
MEM_READ_DATA
PIPELINE D8
RESET CONTROL
LOGIC
SYSTEM_IRQs
CLOCK
INTERRUPT
D8
INTERFACE EMULATION_IRQ
STOP
POWER CONTROL
D8
IDLE REGISTER
Clock Cycles to
1 2 2/3 3 3/4 4 4/5 5 8
execute
Number of
26 50 5 14 7 3 1 2 1
Instructions
CROSSBAR
UART1
Port 1
AMUX
Timer 1 Port 4
System-on-a- PGA 500ksps
Chip micro- Timer 2
controller 12-Bit ADC Port 5
DAC Timer 3
+ +
Timer 4 Port 6
- -
12-Bit Port 7
DAC VOLTAGE
COMPARATORS
64 pin 100 pin
0
AV+
SMBus C
/disabled and Analog Power
AV+
AGND
SPI Bus
R P1 P1.0/AIN1.0
configured by
AGND
TCK 5 PCA
O Drv P1.7/AIN1.7
P3.7
External Latches
XTAL1
XTAL2
Oscillator o 256 byte
Crossbar
Circuit System RAM
Internal
Clock r Config.
Oscillator
4kbyte VREF1
e RAM ADC
Prog
A
M 8:1
500ksps
VREF VREF Gain U
(8-Bit) X
VREFD
DAC1
External Data Memory Bus P4.0
DAC1
(12-Bit) Bus Control C P4 Latch P4 P4.4
T DRV P4.5/ALE
DAC0 L P4.6/RD
DAC0
(12-Bit) P4.7/WR
VREF0
P5 Latch P5 P5.0/A8
AIN0.0 A DRV
AIN0.1 Address Bus d P5.7/A15
AIN0.2 A ADC d P6 Latch P6 P6.0/A0
AIN0.3 M Prog
AIN0.4 U Gain 100ksps r DRV P6.7/A7
AIN0.5
AIN0.6
X (12-Bit)
AIN0.7
D P7 Latch P7 P7.0/D0
TEMP Data Bus
SENSOR a DRV
CP0+ P7.7/D7
CP0 t
CP0-
a
CP1+
CP1
CP1-
0x1000
0x0FFF
XRAM - 4096 Bytes
(accessable using MOVX
0x0000 instruction)
Program Memory
The C8051F020’s program memory consists of 65536 bytes of FLASH,
There are two
separate of which 512 bytes, from addresses 0xFE00 to 0xFFFF, are reserved for
memory factory use. There is also a single 128 byte sector at address 0x10000 to
spaces:
program 0x1007F (Scratchpad Memory), which is useful as a small table for
memory and
data memory software program constants.
Data Memory
The C8051F020 data memory has both internal and external address
spaces. The internal data memory consists of 256 bytes of RAM. The
Special Function Registers (SFR) are accessed anytime the direct
addressing mode is used to access the upper 128 bytes of memory
locations from 0x80 to 0xFF, while the general purpose RAM are
accessed when indirect addressing is used (refer to Chapter 3 for
addressing modes). The first 32 bytes of the internal data memory are
addressable as four banks of 8 general purpose registers, and the next
16 bytes are bit-addressable or byte-addressable.
The external data memory has a 64K address space, with an on-chip 4K
byte RAM block. An external memory interface (EMIF) is used to access
the external data memory. The EMIF is configured by programming the
EMI0CN and EMI0CF SFRs. The external data memory address space
can be mapped to on-chip memory only, off-chip memory only, or a
combination of the two (addresses up to 4K directed to on-chip, above
4K directed to EMIF). The EMIF is also capable of acting in multiplexed
mode or non-multiplexed mode, depending on the state of the EMD2
(EMI0CF.4) bit.
Stack
The programmer stack can be located anywhere in the 256 byte internal
data memory. A reset initializes the stack pointer (SP) to location 0x07;
therefore, the first value pushed on the stack is placed at location 0x08,
which is also the first register (R0) of register bank 1. Thus, if more than
one register bank is to be used, the stack should be initialized to a
location in the data memory not being used for data storage. The stack
depth can extend up to 256 bytes.
28 Chapter 2 Introduction to Silicon Labs’ C8051F020
0(8)
1(9) 2(A) 3(B) 4(C) 5(D) 6(E) 7(F)
Bit
addressable
Table 2.3 SFR Memory Map
The SFRs provide control and data exchange with the C8051F020’s
resources and peripherals. The C8051F020 duplicates the SFRs found
in a typical 8051 implementation as well as implements additional SFRs
which are used to configure and access the sub-systems unique to the
microcontroller. This allows the addition of new functionalities while
retaining compatibility with the MCS-51™ instruction set. Table 2.3 lists
the SFRs implemented in the CIP-51 microcontroller.
C8051F020
duplicates the The SFR registers are accessed anytime the direct addressing mode is
SFRs of 8051 used to access memory locations from 0x80 to 0xFF. The SFRs with
and
implements addresses ending in 0x0 or 0x8 (e.g. P0, TCON, P1, SCON, IE etc.) are
additional
SFRs used to
bit-addressable as well as byte-addressable. All other SFRs are byte-
configure and addressable only. Unoccupied addresses in the SFR space are reserved
access the
microcontroller for future use. Accessing these areas will have an indeterminate effect
sub-systems and should be avoided.
Chapter 2 Introduction to Silicon Labs’ C8051F020 29
/WEAK-PULLUP
/PORT-OUTENABLE
(WEAK)
PORT
PAD
PORT-OUTPUT
PORT-INPUT
2 External
SMBus Priority Pins
2 Decoder
UART1 P0.0
P0 Highest
8
(Internal Digital Signals)
6 I/O Priority
PCA Cells P0.7
Comptr. 2
Outputs Digital
P1 P1.0
Crossbar 8
I/O
T0, T1, Cells P1.7
T2, T2EX, 8
T4,T4EX
/INT0,
/INT1 P2 P2.0
8
I/O
Cells P2.7
Lowest /SYSCLK
Priority CNVSTR
P3 P3.0
8 8
I/O Lowest
Cells P3.7 Priority
P0
(P0.0-P0.7)
P1
(P1.0-P1.7) To External
To
Port Memory
8 ADC1
Latches Interface
Input
(EMIF)
P2
(P2.0-P2.7)
P3
(P3.0-P3.7)
Analog Multiplexer
Window
Configuration, Control, and Data Window Compare
Compare
Registers Logic
Interrupt
AIN0.0 +
AIN0.1 -
Programmable Gain
AIN0.2 + Amplifier
AIN0.3 9-to-1
-
AMUX
AV+ 12-Bit
AIN0.4 +
(SE or
X + SAR 12 ADC Data
Registers
AIN0.5 - DIFF) -
AIN0.6 + ADC Conversion
AIN0.7 - Complete
TEMP Interrupt
SENSOR
Write to AD0BUSY
External VREF Start
Pin VREF Conversion Timer 3 Overflow
AGND CNVSTR
DAC0 Output
Timer 2 Overflow
3) Overflow of Timer 3, or
4) External signal input (CNVSTR).
Analog Multiplexer
Configuration, Control, and Data Registers
AIN1.0
AIN1.1
Programmable Gain
AIN1.2 Amplifier
Conversion
AIN1.3
8-to-1
AV+ 8-Bit Complete
Interrupt
AIN1.4
AMUX
X + SAR 8 ADC Data
AIN1.5 - Register
AIN1.6 ADC
AIN1.7
Write to AD1BUSY
External VREF Timer 3 Overflow
Pin VREF Start Conversion
CNVSTR Input
AV+ Timer 2 Overflow
Write to AD0BUSY
(synchronized with
ADC0)
Figure 2.8 8-Bit ADC Block Diagram
The DAC output is updated each time when there is a software write
(DACxH), or a Timer 2, 3, or 4 overflow (Figure 2.10). The DACs are
especially useful as references for the comparators or offsets for the
differential inputs of the ADC.
The comparators have software programmable hysteresis and can
generate an interrupt on its rising edge, falling edge, or both. The
comparators' output state can also be polled in software and
programmed to appear on the lower port I/O pins via the Crossbar.
More information on programming applications using the ADCs and
DACs will be presented in Chapter 9.
CP0
(Port I/O)
CROSSBAR
CP1
(Port I/O)
CP0+ +
CP0
CP0- -
CP1+ + CP0
CP1
CP1- - CP1 SFR's
CIP-51
(Data and
and Interrupt
Cntrl) Handler
REF
DAC0 DAC0
REF
DAC1 DAC1
DAC0H
Timer 3
Timer 4
Timer 2
DAC0EN
DAC0CN
DAC0MD1
DAC0MD0
DAC0DF2 REF
DAC0DF1 AV+
DAC0DF0
DAC0H
8 8
Latch
Dig. MUX
12
DAC0
DAC0
DAC0L
8 Latch 8
AGND
DAC1H
Timer 3
Timer 4
Timer 2
DAC1EN
DAC1CN
DAC1MD1
DAC1MD0
DAC1DF2 REF
DAC1DF1
DAC1DF0 AV+
DAC1H
8 8
Latch
Dig. MUX
12
DAC1
DAC1
DAC1L
8 8
Latch
AGND
REF0CN
AD0VRS
AD1VRS
TEMPE
REFBE
BIASE
ADC1
AV+
Ref
1
VREF1
VDD 0
External
Voltage R1
Reference
Circuit ADC0
DGND VREF0 Ref
0
DAC0
VREFD
Ref
DAC1 BIASE
Bias to
EN ADCs,
VREF DACs
x2 1.2V
4.7µF 0.1µF Band-Gap
REFBE
Recommended Bypass
Capacitors
This enables the use of the ADC or DAC, and the internal voltage
reference. The appropriate jumpers have to be set on the development
board to connect the internal voltage reference to the ADC or DAC
voltage reference inputs.
3.0 Introduction
A computer instruction is made up of an operation code (op-code)
followed by either zero, one or two bytes of operands information. The
op-code identifies the type of operation to be performed while the
operands identify the source and destination of the data. The operand
can be the data itself, a CPU register, a memory location or an I/O port.
If the instruction is associated with more than one operand, the format is
always:
Instruction Destination, Source
Register Addressing
The register addressing instruction involves information transfer between
registers.
Example: MOV R0,A
Chapter 3 Instruction Set 41
Direct Addressing
The instruction allows you to specify the operand by giving its actual
memory address (in Hexadecimal) or by giving its abbreviated name
(e.g. P3).
Example:
MOV A, P3 ;transfer the contents of
;Port 3 to the accumulator
MOV A, 20H ;transfer the contents of RAM
;location 20H to the
;accumulator
Indirect Addressing
This mode uses a pointer to hold the effective address of the operand.
However only registers R0, R1 and DPTR can be used as the pointer
registers. The R0 and R1 registers can hold an 8-bit address whereas
DPTR can hold a 16-bit address.
Example:
MOV @R0,A ;store the content of
;accumulator into the memory
;location pointed to by
;register R0 e.g. R0 has the
;8-bit address of 60H
Example:
Relative Addressing
This mode of addressing is used with some type of jump instructions like
SJMP (short jump) and conditional jumps like JNZ. This instruction
transfers control from one part of a program to another. The transfer
control must be within -128 and +127 bytes from the instruction address.
Example:
SJMP LOC1 ;Once this instruction is
;executed, the program will
;jump to address labeled LOC1
;which must be at a distance
;of an 8-bit offset from the
;current instruction address
Absolute Addressing
Two instructions associated with this mode of addressing are ACALL and
AJMP instructions. This is a 2-byte instruction where the absolute
address is specified by a label. The branch address must be within the
current 2K byte page of program memory.
Example:
ACALL ARRAY
Chapter 3 Instruction Set 43
Long Addressing
This mode of addressing is used with the LCALL and LJMP instructions.
It is a 3-byte instruction and the last 2 bytes specify a 16-bit destination
location where the program branches to. It allows use of the full 64K
code space. The program will always branch to the same location
irrespective of where the program starts.
Example:
LCALL TABLE ;TABLE address (of 16-bits) is
;specified in the instruction
Indexed Addressing
The Indexed addressing is useful when there is a need to retrieve data
from a look-up table (LUT). A 16-bit register (data pointer) holds the base
address and the accumulator holds an 8-bit displacement or index value.
The sum of these two registers forms the effective address for a JMP or
MOVC instruction.
Example:
MOV A,08H
MOV DPTR,#1F00H
MOVC A,@A+DPTR
After the execution of the above instructions, the program will branch to
address 1F08H (1F00+08) and transfer into the accumulator a data byte
retrieved from that location (from the look-up table).
Arithmetic Operations
With arithmetic instructions, the C8051F020 CPU has no special
knowledge of the data format, e.g. signed binary, unsigned binary, binary
coded decimal, ASCII, etc. Therefore, the appropriate status bits in the
PSW are set when specific conditions are met to manage the different
data formats. Table 3.2 lists the arithmetic instructions associated with
the C8051F020 MCU.
Mnemonic Description
ADD A, Rn A = A + [Rn]
ADD A, direct A = A + [direct memory]
ADD A,@Ri A = A + [memory pointed to by Ri]
ADD A,#data A = A + immediate data
ADDC A,Rn A = A + [Rn] + CY
ADDC A, direct A = A + [direct memory] + CY
ADDC A,@Ri A = A + [memory pointed to by Ri] + CY
ADDC A,#data A = A + immediate data + CY
SUBB A,Rn A = A - [Rn] - CY
SUBB A, direct A = A - [direct memory] - CY
SUBB A,@Ri A = A - [@Ri] - CY
SUBB A,#data A = A - immediate data - CY
INC A A=A+1
INC Rn [Rn] = [Rn] + 1
INC direct [direct] = [direct] + 1
INC @Ri [@Ri] = [@Ri] + 1
DEC A A=A-1
DEC Rn [Rn] = [Rn] - 1
DEC direct [direct] = [direct] - 1
DEC @Ri [@Ri] = [@Ri] - 1
MUL AB Multiply A & B
DIV AB Divide A by B
DA A Decimal adjust A
Table 3.2 List of Arithmetic Instructions
Note: [@Ri] means contents of memory location pointed to by Ri
register
Chapter 3 Instruction Set 45
Operation of both the instructions, ADD and ADDC, can affect the carry
flag (CY), auxiliary carry flag (AC) and the overflow flag (OV).
SUBB A,<source-byte>
SUBB subtracts the specified data byte and the carry flag together from
the accumulator, leaving the result in the accumulator.
SUBB A, R1
borrow) flag being set before the start of operation. So if the state of the
carry bit is unknown before the execution of the SUBB instruction, it must
be explicitly cleared by using CLR C instruction.
INC <byte>
Increments the data variable by 1. The instruction is used in register,
direct or register direct addressing modes.
Example:
MOV R1, #5E
INC R1
INC @R1
If R1=5E (01011110) and internal RAM location 5FH contains 20H, the
instructions will result in R1=5FH and internal RAM location 5FH to
increment by one to 21H.
DEC <byte>
The data variable is decremented by 1. The instruction is used in
accumulator, register, direct or register direct addressing modes. A data
of value 00H underflows to FFH after the operation. No flags are
affected.
INC DPTR
Increments the 16-bit data pointer by 1. DPTR is the only 16-bit register
that can be incremented.
MUL AB
Multiplies A & B and the 16-bit result stored in [B15-8], [A7-0].
Multiplies the unsigned 8-bit integers in the accumulator and the B
register. The Low order byte of the 16-bit product will go to the
accumulator and the High order byte will go to the B register. If the
product is greater than 255 (FFH), the overflow flag is set; otherwise it is
cleared. The carry flag is always cleared.
Example: MUL AB
If ACC=85 (55H) and B=23 (17H), the instruction gives the product 1955
(07A3H), so B is now 07H and the accumulator is A3H. The overflow flag
is set and the carry flag is cleared.
DIV AB
Divides A by B. The integer part of the quotient is stored in A and the
remainder goes to the B register.
Example: DIV AB
DA A
This is a decimal adjust instruction. It adjusts the 8-bit value in ACC
resulting from operations like ADD or ADDC and produces two 4-bit
digits (in packed Binary Coded Decimal (BCD) format). Effectively, this
instruction performs the decimal conversion by adding 00H, 06H, 60H or
66H to the accumulator, depending on the initial value of ACC and PSW.
If ACC bits A3-0 are greater than 9 (xxxx1010-xxxx1111), or if AC=1, then
a value 6 is added to the accumulator to produce a correct BCD digit in
the lower order nibble.
48 Chapter 3 Instruction Set
If CY=1, because the high order bits A7-4 is now exceeding 9 (1010xxxx-
1111xxxx), then these high order bits will be increased by 6 to produce a
correct proper BCD in the high order nibble but not clear the carry.
Example:
MOV R0,#38H
MOV A,#80H
ADDC A
DA A
Before carrying out the above instruction, the accumulator value was
given as ACC=80H (10000000), which also represents BCD=80, R0=
38H (00111000) representing BCD=38, and the carry flag is cleared.
After the operation of ADDC, the result in the accumulator is ACC=B8H,
which is not a BCD value. In order to do a decimal adjustment to the
value, the DA instruction needs to be incorporated. Once DA operation is
carried out, the accumulator will result in ACC=18H, indicating
BCD=18.The carry flag is set, indicating that a decimal overflow occurred
(38+80=118).
Logical Operations
Logical instructions perform Boolean operations (AND, OR, XOR, and
NOT) on data bytes on a bit-by-bit basis. Table 3.3 lists the logical
instructions associated with the C8051F020.
ANL <dest-byte>,<source-byte>
This instruction performs the logical AND operation on the source and
destination operands and stores the result in the destination variable. No
flags are affected.
Mnemonic Description
ANL A, Rn A = A & [Rn]
ANL A, direct A = A & [direct memory]
ANL A,@Ri A = A & [memory pointed to by Ri]
ANL A,#data A= A & immediate data
ANL direct,A [direct] = [direct] & A
ANL direct,#data [direct] = [direct] & immediate data
ORL A, Rn A = A OR [Rn]
ORL A, direct A = A OR [direct]
ORL A,@Ri A = A OR [@RI]
ORL A,#data A = A OR immediate data
ORL direct,A [direct] = [direct] OR A
ORL direct,#data [direct] = [direct] OR immediate data
XRL A, Rn A = A XOR [Rn]
XRL A, direct A = A XOR [direct memory]
XRL A,@Ri A = A XOR [@Ri]
XRL A,#data A = A XOR immediate data
XRL direct,A [direct] = [direct] XOR A
XRL direct,#data [direct] = [direct] XOR immediate data
CLR A Clear A
CPL A Complement A
RL A Rotate A left
RLC A Rotate A left (through C)
RR A Rotate A right
RRC A Rotate A right (through C)
SWAP A Swap nibbles
ORL <dest-byte>,<source-byte>
This instruction performs the logical OR operation on the source and
destination operands and stores the result in the destination variable. No
flags are affected.
XRL <dest-byte>,<source-byte>
This instruction performs the logical XOR (Exclusive OR) operation on
the source and destination operands and stores the result in the
destination variable. No flags are affected.
CLR A
This instruction clears the accumulator (all bits set to 0). No flags are
affected.
Example: CLR A
CPL A
This instruction logically complements each bit of the accumulator (one’s
complement). No flags are affected.
Example: CPL A
RL A
The eight bits in the accumulator are rotated one bit to the left. Bit 7 is
rotated into the bit 0 position. No flags are affected.
Example: RL A
RLC A
The instruction rotates the accumulator contents one bit to the left
through the carry flag. This means that the Bit 7 of the accumulator will
move into carry flag and the original value of the carry flag will move into
the Bit 0 position. No other flags are affected.
Example: RLC A
RR A
The eight bits in the accumulator are rotated one bit to the right. Bit 0 is
rotated into the bit 7 position. No flags are affected.
Example: RR A
52 Chapter 3 Instruction Set
RRC A
The instruction rotates the accumulator contents one bit to the right
through the carry flag. This means that the original value of carry flag will
move into Bit 7 of the accumulator and Bit 0 rotated into carry flag. No
other flags are affected.
Example: RRC A
SWAP A
This instruction interchanges the low order 4-bit nibbles (A3-0) with the
high order 4-bit nibbles (A7-4) of the ACC. The operation can also be
thought of as a 4-bit rotate instruction. No flags are affected.
Example: SWAP A
If ACC=C3H (11000011), then the instruction leaves ACC=3CH
(00111100).
Mnemonic Description
MOV @Ri, direct [@Ri] = [direct]
MOV @Ri, #data [@Ri] = immediate data
MOV DPTR, #data 16 [DPTR] = immediate data
MOVC A,@A+DPTR A = Code byte from [@A+DPTR]
MOVC A,@A+PC A = Code byte from [@A+PC]
MOVX A,@Ri A = Data byte from external ram [@Ri]
MOVX A,@DPTR A = Data byte from external ram [@DPTR]
MOVX @Ri, A External[@Ri] = A
MOVX @DPTR,A External[@DPTR] = A
PUSH direct Push into stack
POP direct Pop from stack
XCH A,Rn A = [Rn], [Rn] = A
XCH A, direct A = [direct], [direct] = A
XCH A, @Ri A = [@Rn], [@Rn] = A
XCHD A,@Ri Exchange low order digits
MOV <dest-byte>,<source-byte>
This instruction moves the source byte into the destination location. The
source byte is not affected, neither are any other registers or flags.
This instruction loads the value 1032H into the data pointer, i.e.
DPH=10H and DPL=32H.
Example: CLR A
LOC1: INC A
MOVC A,@A + PC
RET
Look_up DB 10H
DB 20H
DB 30H
DB 40H
MOVX <dest-byte>,<source-byte>
This instruction transfers data between ACC and a byte of external data
memory. There are two forms of this instruction, the only difference
between them is whether to use an 8-bit or 16-bit indirect addressing
mode to access the external data RAM.
The 8-bit form of the MOVX instruction uses the EMI0CN SFR to
determine the upper 8 bits of the effective address to be accessed and
the contents of R0 or R1 to determine the lower 8 bits of the effective
address to be accessed.
Chapter 3 Instruction Set 55
The 16-bit form of the MOVX instruction accesses the memory location
pointed to by the contents of the DPTR register.
The above example uses the 16-bit immediate MOV DPTR instruction to
set the contents of DPTR. Alternately, the DPTR can be accessed
through the SFR registers DPH, which contains the upper 8 bits of
DPTR, and DPL, which contains the lower 8 bits of DPTR.
PUSH Direct
This instruction increments the stack pointer (SP) by 1. The contents of
Direct, which is an internal memory location or a SFR, are copied into the
internal RAM location addressed by the stack pointer. No flags are
affected.
POP Direct
This instruction reads the contents of the internal RAM location
addressed by the stack pointer (SP) and decrements the stack pointer by
56 Chapter 3 Instruction Set
If SP=51H originally and internal RAM locations 4FH, 50H and 51H
contain the values 30H, 11H and 12H respectively, the instructions
above leave SP=4FH and DPTR=1211H.
POP SP
If the above line of instruction follows, then SP=30H. In this case, SP is
decremented to 4EH before being loaded with the value popped (30H).
XCH A,<byte>
This instruction swaps the contents of ACC with the contents of the
indicated data byte.
XCHD A,@Ri
This instruction exchanges the low order nibble of ACC (bits 0-3), with
that of the internal RAM location pointed to by Ri register. The high order
nibbles (bits 7-4) of both the registers remain the same. No flags are
affected.
Mnemonic Description
CLR C Clear C
CLR bit Clear direct bit
SETB C Set C
SETB bit Set direct bit
CPL C Complement c
CPL bit Complement direct bit
ANL C,bit AND bit with C
ANL C,/bit AND NOT bit with C
ORL C,bit OR bit with C
ORL C,/bit OR NOT bit with C
MOV C,bit MOV bit to C
MOV bit,C MOV C to bit
JC rel Jump if C set
JNC rel Jump if C not set
JB bit,rel Jump if specified bit set
JNB bit,rel Jump if specified bit not set
JBC bit,rel if specified bit set then clear it and jump
Table 3.5 List of Boolean Variable Instructions
CLR <bit>
This operation clears (reset to 0) the specified bit indicated in the
instruction. No other flags are affected. CLR instruction can operate on
the carry flag or any directly-addressable bit.
If Port 2 has been previously written with DCH (11011100), then the
operation leaves the port set to 5CH (01011100).
SETB <bit>
This operation sets the specified bit to 1. SETB instruction can operate
on the carry flag or any directly-addressable bit. No other flags are
affected.
Example: SETB C
SETB P2.0
If the carry flag is cleared and the output Port 2 has the value of 24H
(00100100), then the result of the instructions sets the carry flag to 1 and
changes the Port 2 value to 25H (00100101).
CPL <bit>
This operation complements the bit indicated by the operand. No other
flags are affected. CPL instruction can operate on the carry flag or any
directly-addressable bit.
ANL C,<source-bit>
This instruction ANDs the bit addressed with the Carry bit and stores the
result in the Carry bit itself. If the source bit is a logical 0, then the
instruction clears the carry flag; else the carry flag is left in its original
value. If a slash (/) is used in the source operand bit, it means that the
logical complement of the addressed source bit is used, but the source
bit itself is not affected. No other flags are affected.
Chapter 3 Instruction Set 59
If P2.0=1, P2.7=0 and OV=0 initially, then after the above instructions,
P2.1=0, CY=0 and the OV remains unchanged, i.e. OV=0.
ORL C,<source-bit>
This instruction ORs the bit addressed with the Carry bit and stores the
result in the Carry bit itself. It sets the carry flag if the source bit is a
logical 1; else the carry is left in its original value. If a slash (/) is used in
the source operand bit, it means that the logical complement of the
addressed source bit is used, but the source bit itself is not affected.
No other flags are affected.
MOV <dest-bit>,<source-bit>
The instruction loads the value of source operand bit into the destination
operand bit. One of the operands must be the carry flag; the other may
be any directly-addressable bit. No other register or flag is affected.
If P2=C5H (11000101), P3.3=0 and CY=1 initially, then after the above
instructions, P2=CCH (11001100) and CY=0.
JC rel
This instruction branches to the address, indicated by the label, if the
carry flag is set, otherwise the program continues to the next instruction.
No flags are affected.
Example: CLR C
SUBB A,R0
JC ARRAY1
MOV A,#20H
The carry flag is cleared initially. After the SUBB instruction, if the value
of A is smaller than R0, then the instruction sets the carry flag and
causes program execution to branch to ARRAY1 address, otherwise it
continues to the MOV instruction.
JNC rel
This instruction branches to the address, indicated by the label, if the
carry flag is not set, otherwise the program continues to the next
instruction. No flags are affected. The carry flag is not modified.
Example: CLR C
SUBB A,R0
JNC ARRAY2
MOV A,#20H
The above sequence of instructions will cause the jump to be taken if the
value of A is greater than or equal to R0. Otherwise the program will
continue to the MOV instruction.
Chapter 3 Instruction Set 61
JB <bit>,rel
This instruction jumps to the address indicated if the destination bit is 1,
otherwise the program continues to the next instruction. No flags are
affected. The bit tested is not modified.
Example: JB ACC.7,ARRAY1
JB P1.2,ARRAY2
JNB <bit>,rel
This instruction jumps to the address indicated if the destination bit is 0,
otherwise the program continues to the next instruction. No flags are
affected. The bit tested is not modified.
JBC <bit>,rel
If the source bit is 1, this instruction clears it and branches to the address
indicated; else it proceeds with the next instruction. The bit is not
cleared if it is already a 0. No flags are affected.
Mnemonic Description
ACALL addr11 Absolute subroutine call
LCALL addr16 Long subroutine call
RET Return from subroutine
RETI Return from interrupt
AJMP addr11 Absolute jump
LJMP addr16 Long jump
SJMP rel Short jump
JMP @A+DPTR Jump indirect
JZ rel Jump if A=0
JNZ rel Jump if A NOT=0
CJNE A,direct,rel
CJNE A,#data,rel
Compare and Jump if Not Equal
CJNE Rn,#data,rel
CJNE @Ri,#data,rel
DJNZ Rn,rel
Decrement and Jump if Not Zero
DJNZ direct,rel
NOP No Operation
ACALL addr11
This instruction unconditionally calls a subroutine indicated by the
address. The operation will cause the PC to increase by 2, then it pushes
the 16-bit PC value onto the stack (low order byte first) and increments
the stack pointer twice. The PC is now loaded with the value addr11 and
the program execution continues from this new location. The subroutine
called must therefore start within the same 2K block of the program
memory. No flags are affected.
LCALL addr16
This instruction calls a subroutine located at the indicated address. The
operation will cause the PC to increase by 3, then it pushes the 16-bit PC
value onto the stack (low order byte first) and increments the stack
pointer twice. The PC is then loaded with the value addr16 and the
program execution continues from this new location. Since it is a Long
call, the subroutine may therefore begin anywhere in the full 64KB
program memory address space. No flags are affected.
RET
This instruction returns the program from a subroutine. RET pops the
high byte and low byte address of PC from the stack and decrements the
SP by 2. The execution of the instruction will result in the program to
resume from the location just after the “call” instruction. No flags are
affected.
Example: RET
Suppose SP=0BH originally and internal RAM locations 0AH and 0BH
contain the values 30H and 02H respectively. The instruction leaves
SP=09H and program execution will continue at location 0230H.
RETI
This instruction returns the program from an interrupt subroutine. RETI
pops the high byte and low byte address of PC from the stack and
restores the interrupt logic to accept additional interrupts. SP decrements
by 2 and no other registers are affected. However the PSW is not
automatically restored to its pre-interrupt status. After the RETI, program
execution will resume immediately after the point at which the interrupt is
detected.
Example: RETI
Suppose SP=0BH originally and an interrupt is detected during the
instruction ending at location 0213H. Internal RAM locations 0AH and
0BH contain the values 14H and 02H respectively. The RETI instruction
leaves SP=09H and returns program execution to location 0234H.
AJMP addr11
The AJMP instruction transfers program execution to the destination
address which is located at the absolute short range distance (short
range means 11-bit address). The destination must therefore be within
the same 2K block of program memory.
LJMP addr16
The LJMP instruction transfers program execution to the destination
address which is located at the absolute long range distance (long range
means 16-bit address).The destination may therefore be anywhere in the
full 64K program memory address space. No flags are affected.
SJMP rel
This is a short jump instruction, which increments the PC by 2 and then
adds the relative value ‘rel’ (signed 8-bit) to the PC. This will be the new
address where the program would branch to unconditionally. Therefore,
the range of destination allowed is from -128 to +127 bytes from the
instruction.
If the label RELSRT is at program memory location 0120H and the SJMP
instruction is located at address 0100H, after executing the instruction,
PC=0120H.
JMP @A + DPTR
This instruction adds the 8-bit unsigned value of the ACC to the 16-bit
data pointer and the resulting sum is returned to the PC. Neither ACC
nor DPTR is altered. No flags are affected.
JZ rel
This instruction branches to the destination address if ACC=0; else the
program continues to the next instruction. The ACC is not modified and
no flags are affected.
If ACC originally holds 20H and CY=0, then the SUBB instruction
changes ACC to 00H and causes the program execution to continue at
the instruction identified by LABEL1; otherwise the program continues to
the DEC instruction.
JNZ rel
This instruction branches to the destination address if any bit of ACC is a
1; else the program continues to the next instruction. The ACC is not
modified and no flags are affected.
Example: DEC A
JNZ LABEL2
MOV RO, A
If ACC originally holds 00H, then the instructions change ACC to FFH
and cause the program execution to continue at the instruction identified
by LABEL2; otherwise the program continues to MOV instruction.
CJNE <dest-byte>,<source-byte>,rel
This instruction compares the magnitude of the dest-byte and the
source-byte and branches if their values are not equal. The carry flag is
set if the unsigned dest-byte is less than the unsigned integer source-
byte; otherwise, the carry flag is cleared. Neither operand is affected.
Chapter 3 Instruction Set 67
DJNZ <byte>,<rel-addr>
This instruction is ”decrement jump not zero”. It decrements the contents
of the destination location and if the resulting value is not 0, branches to
the address indicated by the source operand. An original value of 00H
underflows to FFH. No flags are affected.
If internal RAM locations 20H, 30H and 40H contain the values 01H, 5FH
and 16H respectively, the above instruction sequence will cause a jump
to the instruction at LOC2, with the values 00H, 5EH, and 15H in the 3
RAM locations. Note, the first instruction will not branch to LOC1
because the [20H] = 00H, hence the program continues to the second
instruction. Only after the execution of the second instruction (where the
location [30H] = 5FH), then the branching takes place.
NOP
This is the no operation instruction. The instruction takes one machine
cycle operation time. Hence it is useful to time the ON/OFF bit of an
output port.
MOV A,13H
MOV R2,18H
ADD A, R2
DA A
RLC A
4.0 Introduction
Assembler directives are special codes placed in the assembly language
program to instruct the assembler to perform a particular task or function.
They can be used to define symbol values, reserve and initialize storage
space for variables and control the placement of the program code. They
are not assembly language instructions as they do not generate any
machine code.
ORG
The specified format for the ORG directive is:
ORG expression
The ORG directive is used to set the location counter in the current
segment to an offset address specified by the expression. However, it
does not alter the segment address. The segment address can only be
changed by using the standard segment directives.
The ORG directive need not only be used in the code segment but can
be used in other segments too like the data segment. For example, to
Chapter 4 ASM Directives 73
USING
The specified format for the USING directive is:
USING expression
END
The specified format for the END directive is:
END
74 Chapter 4 ASM Directives
The END directive indicates the end of the source file. It informs the
assembler where to stop assembling the program. Hence any text that
appears after the END directive will be ignored by the assembler. The
END directive is a must in every source file. If it is not written at the end
of the program, the assembler will give an error message.
EQU, SET
Examples:
COUNT EQU R3
TOTAL EQU 200
AVERG SET TOTAL/5
TABLE EQU 10
VALUE SET TABLE*TABLE
Note:
Example:
The directives for memory initialization and reservation are DB, DW, DD
and DS. These directives will initialize or reserve memory storage in the
form of a byte, a word, or a double word in the code space.
76 Chapter 4 ASM Directives
DB (Define Byte)
The DB directive initializes code memory with a byte value. The directive
has the following format:
Note:
label is the starting address where the byte values are stored
expression is the byte value, it can be a character string, a symbol,
or an 8-bit constant
Example:
CSEG AT 200H
MSG: DB ‘ Please enter your password’, 0
ARRAY: DB 10H, 20H,30H,40H,50H
The above string of characters will be stored as ASCII bytes starting from
location 200H, which means location [200H]=50H, [201H]=6CH and so
on.
Notice that the DB directive is declared in a code segment. If it is defined
in a different segment, the assembler will generate an error.
DW (Define Word)
The DW directive initializes the code memory with a double byte or a 16-
bit word. The DW directive has the following format:
Example:
;2 words allocated
CNTVAL DW 1025H, 2340H
;10 values of 1234H starting from location XLOC
XLOC DW 10 DUP (1234H)
The DD directive initializes the code memory with double word or 32-bit
data value. The DD directive has the following format:
label: DD expression ,expression…
Example:
DS (Define Storage)
label: DS expression
Example:
Generic Segment
Example:
Example:
RSEG MYDATA
Chapter 4 ASM Directives 79
Absolute Segment
Example:
ORG 10H
DB 61H, 62H, 63H
DW ‘0’,’1’,’2’
5.0 Introduction
The C8051F020 micro-controller may be operated from an external
oscillator or an internal oscillator, both are included on the target board.
After any reset, the MCU operates from the internal oscillator at a typical
frequency of 2.0MHz by default but may be configured by software to
operate at other typical frequencies of 4.0Mhz, 8.0MHz or 16MHz.
Therefore, in many applications an external oscillator is not required.
However, an external 22.1184MHz crystal is installed on the target board
as shipped from the factory. It is especially useful in providing a system
clock frequency suitable for high baud rate generation for UART. Both
the oscillators are disabled when the /RST pin is held low. The oscillator
and its associated programming registers are shown in Figure 5.1.
OSCICN
MSCLKE
IOSCEN
CLKSL
IFRDY
IFCN1
IFCN0
VDD
EN
Internal Clock
opt. 2 Generator
AV+ SYSCLK
AV+
opt. 4 opt. 3 opt. 1
XTAL1 XTAL1 XTAL1 XTAL1
Input
OSC
XTAL2 XTAL2 Circuit
AGND
XOSCMD2
XOSCMD1
XOSCMD0
XTLVLD
XFCN2
XFCN1
XFCN0
OSCXCN
Bits 0 and 1 are used to select the internal oscillator frequency. Bit 2
enables or disables the internal oscillator while bit 3 selects between the
internal and external oscillator. Once the internal oscillator is enabled, it
takes a while for it to settle down and generate the desired frequency set
by IFCN1-IFCN0 (Bits 0 and 1). Bit 4 shows the status of the internal
oscillator and is set to 1 when the oscillator is running at the specified
speed. Bit 7 is to be set to 1 if missing clock detector is to be enabled. A
reset is triggered if the clock is missing for a period greater than 100µs.
Chapter 5 System Clock, Crossbar and GPIO 87
The OSCICN SFR is at address 0xB2. Upon reset, the value in this
register is set to 0001 0100. This enables the internal oscillator to
operate at a frequency of 2 MHz.
If the crystal frequency is greater than 6.7 MHz, which is indeed the case
for the on-board crystal of the target board, bits 2-0 (XFCN2-0) must be
set to 111. Bits 6-4 (XOSCMD2-0) are programmed based on the
external oscillator whether it is RC/C, crystal or CMOS clock on XTAL1.
After the external oscillator has been enabled, by setting CLKSL
(OSCICN.3) to 1, one must wait for the crystal oscillator to be stable.
This can be checked by polling bit 7 (XTLVLD) of OSCXCN.
The OSCXCN SFR is at address 0xB1. Upon reset, the value in this
register is set to 0000 0000. This turns off the crystal oscillator and the
XTAL1 pin is grounded internally.
88 Chapter 5 System Clock, Crossbar and GPIO
Example:
Bit Description
WDT Control
Writing 0xA5 both enables and reloads the WDT
7-0 Writing 0xDE followed within 4 system clocks by
0xAD disables the WDT
Writing 0xFF locks out the disable feature
Watchdog Status Bit (when Read)
Reading this bit indicates the Watchdog Timer
4 Status
0: WDT is inactive
1: WDT is active
Watchdog Timeout Interval Bits
2-0 These bits set the Watchdog Timer Interval.
When writing these bits, WDTCN.7 must be set
to 0.
Enable/Reset WDT
To enable and reset the watchdog timer, write 0xA5 to the WDTCN
register. To prevent a watchdog timer overflow, the application must
periodically write 0xA5 to WDTCN.
Disable WDT
To disable the WDT, the application must write 0xDE followed by, within
4 clock cycles, 0xAD to the WDTCN register. If 0xAD is not written with 4
cycles of writing 0xDE, the disable operation is not effective. Interrupts
must be disabled during this procedure to avoid delay between the two
writes.
90 Chapter 5 System Clock, Crossbar and GPIO
Example:
2 External
SMBus Priority Pins
2 Decoder
UART1 P0.0
P0 Highest
(Internal Digital Signals) 8
6 I/O Priority
PCA Cells P0.7
Comptr. 2
Outputs Digital
P1 P1.0
Crossbar 8
I/O
T0, T1, Cells P1.7
T2, T2EX, 8
T4,T4EX
/INT0,
/INT1 P2 P2.0
8
I/O
Cells P2.7
Lowest /SYSCLK
Priority CNVSTR
P3 P3.0
8 8
I/O Lowest
Cells P3.7 Priority
P0
(P0.0-P0.7)
P1
(P1.0-P1.7) To External
To
Port Memory
8 ADC1
Latches Interface
Input
(EMIF)
P2
(P2.0-P2.7)
P3
(P3.0-P3.7)
P0 P1 P2 P3
Crossbar Register Bits
Pin I/O 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
Tx0 ●
UART0EN: XBR0.2
Rx0 ●
SCK ● ●
MISO ● ●
SPI0EN: XBR0.1
MOSI ● ●
NSS ● ●
SDA ● ● ● ●
SMB0EN: XBR0.0
SCL ● ● ● ●
TX1 ● ● ● ● ●
UART1EN: XBR2.2
RX1 ● ● ● ● ● ●
CEX0 ● ● ● ● ● ● ●
CEX1 ● ● ● ● ● ● ● ●
CEX2 ● ● ● ● ● ● ● ● PCA0ME: XBR0.[5:3]
CEX3 ● ● ● ● ● ● ● ● ●
CEX4 ● ● ● ● ● ● ● ● ●
ECI ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ECI0E: XBR0.6
CP0 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● CP0E: XBR0.7
CP1 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● CP1E: XBR1.0
T0 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● T0E: XBR1.1
/INT0 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● INT0E: XBR1.2
T1 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● T1E: XBR1.3
/INT1 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● INT1E: XBR1.4
T2 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● T2E: XBR1.5
T2EX ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● T2EXE: XBR1.6
T4 ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● T4E: XBR2.3
T4EX ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● T4EXE: XBR2.4
/SYSCLK ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● SYSCKE: XBR1.7
CNVSTR ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● CNVSTE: XBR2.0
AIN1.2/A10
AIN1.3/A11
AIN1.4/A12
AIN1.5/A13
AIN1.6/A14
AIN1.7/A15
AIN1.0/A8
AIN1.1/A9
A10m/A2
A11m/A3
A12m/A4
A13m/A5
A14m/A6
A15m/A7
A8m/A0
A9m/A1
AD0/D0
AD1/D1
AD2/D2
AD3/D3
AD4/D4
AD5/D5
AD6/D6
AD7/D7
/WR
ALE
/RD
The output states of port pins that are allocated by the crossbar are
controlled by the digital peripheral that is mapped to those pins and
hence Writes to the Port Data registers (or associated Port bits) will have
no effect on the states of the pins. The Port pins on Port 0 to 3 that are
not allocated by the Crossbar may be accessed as General-Purpose I/O
pins by reading and writing the associated Port Data registers.
Chapter 5 System Clock, Crossbar and GPIO 93
A Read of a Port Data Register (or Port bit) will always return the logic
state present at the pin itself, regardless of whether the Crossbar has
allocated the pin for peripheral use or not.
Although the crossbar can be configured dynamically at runtime, the
crossbar registers are typically configured in the initialization code of the
application software and thereafter left alone. The peripherals are then
configured individually.
5.4 GPIO
The block diagram of the Port I/O cell is shown in Figure 5.4.
/WEAK-PULLUP
/PORT-OUTENABLE
(WEAK)
PORT
PAD
PORT-OUTPUT
PORT-INPUT
The SFRs associated with Ports 7 to 4 are P74OUT and the individual
Port Data registers, P4, P5, P6 and P7. These SFRs are described next.
void Init_Port(void);
(b) Write a function to set up the timer and UART1. The function
prototype is –
void Init_UART1_T4(void);
(You can assume that the system clock has been properly
setup by another function)
(c) Show the working of how you have calculated the Timer 4
Capture Register reload value for 9600 baud rate.
6
C8051F020 C Programming
6.0 Introduction 110
6.1 Register Definitions, Initialization and Startup
Code 110
Basic C program structure
6.2 Programming Memory Models 111
Overriding the default memory model, Bit-valued data,
Special Function Registers, Locating Variables at absolute
addresses
6.3 C Language Control Structures 115
Relational Operators, Logical Operators, Bitwise Logical
Operators, Compound Operators, Making Choices (if..else,
switch..case), Repetition (for loop, while loop), Waiting for
Events, Early Exits
6.4 Functions 122
Standard functions - Initializing System Clock, Memory Model
Used for a Function
6.5 Interrupt Functions 123
Timer 3 Interrupt Service Routine, Disabling Interrupts before
Initialization, Timer 3 Interrupt Initialization, Register Banks
6.6 Reentrant Functions 127
6.7 Pointers 127
A Generic Pointer in KeilTM C, Memory Specific Pointers
6.8 Summary of Data Types 129
6.9 Tutorial Questions 130
110 Chapter 6 C8051F020 C Programming
6.0 Introduction
This chapter introduces the KeilTM C compiler for the Silicon Labs
C8051F020 board. We assume some familiarity with the C programming
language to the level covered by most introductory courses in the C
language.
Experienced C programmers, who have little experience with the
C8051F020 architecture, should become familiar with the system. The
differences in programming the C8051F020 in C, compared to a
standard C program, are almost all related to architectural issues. These
explanations will have little meaning to those without an understanding of
the C8051F020 chip.
The KeilTM C compiler provided with the C8051F020 board does not
come with a floating point library and so the floating point variables and
functions should not be used. However if you require floating point
variables, a full license for the KeilTM C compiler can be purchased.
#include <reg51.h>
Or
These files contain all the definitions of the C8051F020 registers. The
standard initialization and startup procedures for the C8051F020 are
contained in startup.a51. This file is included in your project and will be
assembled together with the compiled output of your C program. For
custom applications, this startup file might need modification.
Chapter 6 C8051F020 C Programming 111
//--------------------------------------------------------------
// Basic blank C program that does nothing
// other than disable the watch dog timer
//--------------------------------------------------------------
// Includes
//--------------------------------------------------------------
Note: All variables must be declared at the start of a code block. You
cannot declare variables amongst the program statements.
You can test this program in the Silicon Labs IDE (Integrated
Development Environment). You won’t see anything happening on the
C8051F020 development board, but you can step through the program
using the debugger.
#pragma small
int X;
Any variable declared in this file (such as the variable X above) will be
stored in the internal memory of the C8051F020.
The choice of which memory model to use depends on the program, the
anticipated stack size and the size of data. If the stack and the data
cannot fit in the 128 Bytes of internal memory then the default memory
model should be LARGE, otherwise SMALL should be used.
Yet another memory model is the COMPACT memory model. This
memory model is not discussed in this chapter. More information on the
compact model can be found in the document Cx51 Compiler User’s
Guide for KeilTM Software.
You can test the different memory models with the Silicon Labs IDE
connected to the C8051F020-TB development board. Look at the symbol
view after downloading your program and see in which memory
addresses the compiler has stored your variables.
int data X;
char data Initial;
int xdata Y;
char xdata SInitial;
The integer variable X and character variable Initial are stored in the first
128 bytes of internal memory while the integer variable Y and character
variable SInitial are stored in the external memory overriding any default
memory model.
Chapter 6 C8051F020 C Programming 113
Bit-valued Data
Bit-valued data and bit-addressable data must be stored in the bit-
addressable memory space on the C8051F020 (0x20 to 0x2F). This
means that bit- valued data and bit-addressable data must be labeled as
such using the bit, sbit and bdata.
Bit-addressable data must be identified with the bdata language
extension:
int bdata X;
bit flag;
bdata X;
sbit X7flag = X^7; /* bit 7 of X */
/* BYTE Register */
sfr P0 = 0x80;
sfr P1 = 0x90;
Extensions of the 8051 often have the low byte of a 16 bit register
preceding the high byte. In this scenario it is possible to declare a 16 bit
special function register, sfr16, giving the address of the low byte:
The above statement locates the integer X at the memory location 0x40.
The _at_ language extension can not be used to locate bit addressable
data.
Relational Operators
Relational operators compare data and the outcome is either True or
False. The if statements, for loops and while loops can make use of C
relational operators. These are summarized in Table 6.1.
Operator Description
== Equal to
!= Not Equal to
< Less than
> Greater than
<= Less than or equal to
>= Greater than or equal to
Logical Operators
Logical operators operate on Boolean data (True and False) and the
outcome is also Boolean. The logical operators are summarized in Table
6.2.
Operator Description
&& Logical AND
|| Logical OR
! Logical NOT
Table 6.2 Logical Operators
Operator Description
& Bitwise AND
| Bitwise OR
~ Bitwise NOT
^ Bitwise XOR
Table 6.3 Bit valued logical operators
Example:
X = 0x40 | 0x21;
The above statement will assign the value 0x61 to the variable X.
Compound Operators
C language provides short cut bitwise operators acting on a single
variable similar to the +=, -=, /= and *= operators. These are summarized
in Tables 6.4 and 6.5.
Making Choices
No Is the Yes
Condition
True?
Execute Execute
Statement Block2 Statement Block 1
if (x > 10)
{ y=y+1; }
else
{ y=y-1; }
When the Condition is evaluated as True the first block is executed and if
the Condition evaluates as being False the second block is executed.
More conditions can be created using a sequence of if and else if
statements.
if (x > 10)
{ y=y+1; }
else if (x > 0)
{ y=y-1; }
else
{ y=y-2; }
switch (x)
{
case 5:
y=y+2; break;
case 4: case 3:
y=y+1; break;
case 2: case 1:
y=y-1; break;
default:
y=y-2; break;
}
When the variable x in the switch statement matches one of the case
statements, that block is executed. Only when the break statement is
reached does the flow of control break out of the switch statement. The
default block is executed when there are no matches with any of the
case statements.
If the break statements are missing from the switch-case statement
then the flow will continue within the switch-case block until a break
statement or the end of the switch-case block is reached.
Repetition
Numeric repetition of a code block for a fixed set of times is achieved
using a for loop construct.
int i;
int sum=0;
for( i = 0; i<10; i++)
{
sum = sum + i;
}
120 Chapter 6 C8051F020 C Programming
Execute Completed
the required
statement(s) within number of
the loop times?
Yes
No
Execute Is the
statement(s) condition
true?
within the loop
Yes
No
The while loop repeats the loop while the condition specified is true.
Chapter 6 C8051F020 C Programming 121
Early Exits
When executing a code block or a loop, sometimes it is necessary to exit
the current code block. The C language provides several mechanisms to
do this.
The break statement will move the flow of control outside the end of the
current loop.
int i;
int sum=0;
for( i = 0; i<10; i++)
{
sum = sum + i;
if (sum > 25) break;
}
The continue statement skips the remaining code in the current loop,
but continues from the start of the code block of the loop (after
incrementing and checking that the loop should not terminate)
int i;
int sum=0;
for( i = 0; i<10; i++)
{
if (i == 5) continue;
sum = sum + i;
}
122 Chapter 6 C8051F020 C Programming
6.4 Functions
Functions in C are declared using the return data type, the data type of
the parameters and the body of the function.
void Init_Clock(void)
{
OSCXCN = 0x67; //-- 0110 0111b
//-- External Osc Freq Control Bits (XFCN2-0) set
// to 111 because crystal frequency > 6.7 MHz
//-- Crystal Oscillator Mode (XOSCMD2-0) set to 110
int count;
Interrupt functions must not take any parameters and not return any
parameters. Interrupt functions will be called automatically when the
interrupt is generated; they should not be called in normal program code,
this will generate a compiler error.
P3_input = ~P3;
if (P3_input & 0x80) //-- if bit 7 is set,
{ // then switch is pressed
LED_count++;
if ( (LED_count % 10) == 0)
{ //-- do every 10th count
LED = ~LED; //-- change state of LED
LED_count = 0;
}
}
}
Register Banks
Normally a function uses the default set of registers. However there are 4
sets of registers available in the C8051F020. The register bank that is
currently in use can be changed for a particular function via the using
KeilTM C language extension.
int count;
6.7 Pointers
Pointers in C are a data type that stores the memory addresses. In
standard C the data type of the variable stored at that memory address
must also be declared:
int * X;
but are less efficient as the compiler needs to store what memory model
is being pointed to. This means that a generic pointer takes 3 bytes of
storage - 1 byte to store the type of memory model that is pointed to and
two bytes to store the address.
int * Y;
char * ls;
long * ptr;
You may also explicitly specify the memory location that the generic
pointer is stored in, to override the default memory model.
int * xdata Y;
char * idata ls;
long * data ptr;
int xdata * Y;
char data * ls;
long idata * ptr;
You may also specify the memory location that the memory-specific
pointer is stored in, to override the default memory model.
3. How do you override the default memory model for the storage of
a variable in your program?
10. What is the total number of interrupts that the KeilTM C compiler
can support?
12. How does the use of different register banks make interrupt calls
more efficient?
14. How much memory space does a KeilTM C generic pointer take
and why?
15. How much memory does a memory specific pointer take in KeilTM
C?
16. What is the difference between “int * xdata ptr” and “int
xdata * ptr” in KeilTM C?
7
Expansion Board for C8051F020
Target Board
7.0 Introduction 132
Expansion Board Block Diagram
7.1 Starting a Project 134
7.2 Blinking Using Software Delays 135
Watchdog Timer, Configuring the Crossbar, Port
Configuration, Software Delays, The main() Routine
7.3 Blinking Using a Timer 138
Polling Timer 3, Timer 3 Interrupts, Interrupts in General,
Changing the Clock Speed
7.4 Programming the LCD 142
LCD Controller – Overall Structure, Pin Definitions,
Instructions, Initialization Requirements, LCD Software,
Synchronization – the Busy Bit, 8-Bit Initialization Sequence,
LCD Integration
7.5 Reading Analog Signals 151
Initialization, Interrupt Service Routines, The Main Code
7.6 Expansion Board Pictures 153
7.7 Circuit Diagram of the Expansion Board 154
7.8 Expansion Board Physical Component Layout 155
132 Chapter 7 Expansion Board For C8051F020 Target Board
7.0 Introduction
The Silicon Labs C8051F020 evaluation board has pin header
connections for all 8 ports so it is not difficult to attach additional devices.
Nevertheless it is much more convenient and robust to mount switches
and displays on a printed circuit board, which can then connect using the
DIN96 connector – which also has all the ports available. The board we
have developed uses the upper four ports which leave the lower, more
versatile, ports available for other uses.
This chapter will explain the expansion board and provide a number of
example programs which are designed to help learning to program the
Silicon Labs C8051F020. Some of these will require the expansion board
(or similar hardware) while others only use the Silicon Labs C8051F020
Evaluation board itself.
P7 b2-0 Control
3 16 Character x 2 Lines
P6 Data Liquid Crystal Display
8
96 pin
P5 b7-4
DIN 4 Four LEDs
connector
to Silicon P5 b3-0
4 Four Push Button Switches
Labs
MCU P4
Board 8 DIP 8 Switches
AIN0.2
Potentiometer
AIN0.3 Temperature Sensor
DAC1
LCD Contrast (via JP1)
DAC0
Test Point 2
Temperature Sensor
Either a thermistor or a three-terminal temperature sensor (e.g. LM335)
can be used. The pull up resistor should be changed to suit the device.
LCD Contrast
JP1 selects the source of the contrast voltage for the LCD, which is
either the 10k trim pot (VR2) or the DAC1 output. Using the latter allows
software control of the LCD contrast.
Test Points
The four analog signals on the board are all available on test points
which allow an oscilloscope to be easily connected. Analog and digital
grounds, and the 3.3 V supply, are also provided.
Power Supply
A very small current is drawn from the 3.3 V supply of the development
board for biasing the potentiometer and temperature sensor. The LCD
operates from +5 V generated using a 5 V regulator chip which runs off
the unregulated supply on the Silicon Labs C8051F020 board. This can
be grounded with a push button switch (via a current limiting resistor) so
that the LCD can be reset. The LCD requires about 1.5 mA which
increases to 8 mA when the switch is pressed.
You can now proceed to write your program. It can be compiled with F7,
downloaded with Alt-D, and run with F5. To combine the compile and
download steps go to Project/Target Build Configuration and check the
Enable automatic download/connect after build check box.
The Silicon Labs C8051F020 has many internal registers which control
how it operates. These must be configured at run time – by a program as
it executes. Although this could be performed by a block of code at the
start of main() it is clearer to use a separate function – here, in Figure
7.3, called init().
Watchdog Timer
The watchdog timer (WDT) is enabled by default at system start-up. Its
purpose is to reset the microcontroller, should the running program lose
control – perhaps by entering an infinite loop. The first two lines of init()
136 Chapter 7 Expansion Board For C8051F020 Target Board
void init(void)
{
WDTCN = 0xDE; // Watchdog Timer Ctrl Register
WDTCN = 0xAD; // Disable watch dog timer
//---- Configure the XBRn Registers
XBR0 = 0x00; //
XBR1 = 0x00; // Enable the crossbar,
XBR2 = 0x40; // weak pullups enabled
To disable the WDT, two writes are needed to the watch dog timer
control register (WDTCN). These must occur within 4 clock cycles of
each other so interrupts should not be enabled at the time.
Port Configuration
With the crossbar enabled, the port pins will pull high via the internal
resistors, allowing the pin to source a few µA, when a logic 1 is written to
the pin. Internal transistors will pull the pin low in response to a logic 0
allowing it to sink up to 50 mA. The LED on P1.6 and the four LEDs on
the expansion board must be driven high to illuminate and so the port
pins that drive them need to be configured in push-pull output mode.
They can then easily source the required 10 mA for the LED. The output
Chapter 7 Expansion Board For C8051F020 Target Board 137
mode of each of the pins of the lower four ports (P0 to P3) is individually
configurable while with the upper ports (P4 to P7) they are set in groups
of four pins.
A good programming practice is to configure only those pins that are
actually needed is.
Software Delays
Because the MCU operates very fast it is necessary to slow it down if a
blinking LED is to be observed. The program in Figure 7.4 shows three
functions which provide different amount of delays when called in a
program. huge_delay() calls large_delay() which in turn calls
small_delay(). Each has a loop which counts down. Calling
small_delay(10) will give a delay of about 40 µs while huge_delay(10)
will take about 2.3 s. Of course, if the clock is different from 2.0 MHz the
delays will be different too.
While software delays can be quite accurate, if calibrated, it is difficult to
do so and they lose any time taken by interrupts. They also tie up the
processor while running, so other tasks such as reading the keyboard
are ignored.
void small_delay(char d)
{
while (d--);
}
void large_delay(char d)
{
while (d--)
small_delay(255);
}
void huge_delay(char d)
{
while (d--)
large_delay(255);
}
void main(void)
{
init();
while (1)
{
large_delay(200); // approx. 180ms delay
if (butt_37) // push button not pressed
LED_16 = !LED_16; // toggle LED
else // push button pressed
LED_16 = 1; // LED continuously illuminated
}
}
Another point to note is that while the delay is about 180 ms, the LED
flashes at about 2.8 Hz. This is because the loop must run twice for the
LED to go through one cycle.
examines the high byte of Timer 3 and uses a bit mask to determine
when the count has passed halfway.
void main(void)
{
init();
Timer3_Init(0x0000); // Init Timer3 to divide by 65536
while (1)
{
LED_16 = ((TMR3H & 0x80) == 0x80); // The high bit of
// TMR3 controls the
// LED
}
}
Timer 3 Interrupt
An interrupt can be generated when Timer 3 overflows. This causes
execution to jump to its interrupt service routine (ISR) which has priority
14, and is identified to the compiler by interrupt 14 (in Figure 7.7). The
actual ISR code is only two lines. The timer flag bit is what actually
generates the interrupt – it is set when the timer overflows and it is the
programmers responsibility to clear it. It is part of the Timer 3 control
register and is not bit addressable so an AND operation must be used
with a bit mask which has a value 0111 1111b.
Interrupts in General
Interrupts can be tricky to use. It is necessary to be very careful when
accessing data which is shared between an ISR and another function,
say, main(). This is because main() doesn’t know when it will be
interrupted; it could be partway through reading a variable when an ISR
is called that changes the same variable. Even though this sequence of
events might be very unlikely, after many thousands of interrupts, it WILL
140 Chapter 7 Expansion Board For C8051F020 Target Board
happen. This results in a program which works well almost all the time,
but occasionally does something strange. Globally disabling interrupts
(by setting the EA bit to zero) before accessing shared data from outside
an interrupt will prevent the above corruption.
void main(void)
{
init();
Timer3_Init(SYSCLK / 12 / 10); // Init Timer3 to generate
// interrupts at 10 Hz
EA = 1; // interrupts on
while (1); // main spins forever
}
indicates the crystal has stabilized. Only at that point does the operation
switch to the external oscillator.
There are two things to note in the new Timer 3 ISR shown in Figure 7.9.
The first is that with the faster oscillator the LED will flash too fast and
appear to be continuously illuminated. To make it flash slow enough to
be visible, an additional byte is used within the ISR to divide the blinking
rate, in this case, by five. Four out of five times the ISR is exited
prematurely; on the fifth the switch statement is executed.
The second feature shows a simple finite state machine. State machines
are useful when a sequence of actions or events must be detected or
created. In this case the four states loop in numerical order but they can
become much more complex in some scenarios.
00h 39h
Line 1
40h 79h
Line 2
2 rows of 16
characters visible
Figure 7.11 2 Line x 16 Character LCD Window
The characters in the first row start at address 00h and the second row
starts at 40h. The value in the DDRAM Address Counter is where the
next character will be written. It can be set to any address. Normally the
module is configured so that subsequent characters go into the next
highest location (DDRAM is incremented). This results in writing from left
to right on the display. The simplest approach is to leave the display
window at 00h.
The Character Generator RAM (CGRAM) holds user defined characters.
Programming these is not covered in this text.
Pin Definitions
Figure 7.12 shows the pin out of the LCD module. Three pins are used
for the power supply, ground and contrast adjustment. HD22780S
modules require a +5V supply, however the HD44780U controller can
operate on a range of supplies, down to 2.7V. The expansion board
includes a 5V regulator so the S variant may be used too.
There are 11 signal lines altogether. These include the 8-bit bidirectional
The C8051F020
port pins are data bus and three control lines which are write-only. They require clean
also tolerant of digital signals which would normally be 0 or 5V. However they are
5V!
tolerant of 3.3V systems.
Be aware that the data bus is bidirectional, so at times the LCD controller
will want to drive the pins high or low. A connected microcontroller must
not attempt to drive the bus at the same time, except through pull-up
144 Chapter 7 Expansion Board For C8051F020 Target Board
Pin Full
Signal Function
Number Name
VSS 1 Ground 0V common connection
Supply
VDD 2 +5V supply
Voltage
When varied between 0 and VSS
VO 3 Contrast
changes the optimum viewing angle.
↑ (low to high transaction) The LCD
controller reads the state of RS
and RW
Note: to write from the LCD (e.g. the
E 6 Enable
busy bit – see later) E should
remain high.
↓ (high to low transaction) The LCD
controller reads the data bus
Register 0: Instruction Register
RS 4 Select 1: Data Register
Read or 0: Write to LCD
RW 5 Write 1: Read from LCD
8-bit Data To convey instructions or data to the
D[0..7] 7 - 14 Bus LCD controller
15,16 No Connection
Instructions
Instructions are used for configuring the LCD controller, to pass it data
which will be displayed, and to read status information back from it.
Figure 7.13 shows the instructions in numerical order.
Chapter 7 Expansion Board For C8051F020 Target Board 145
Initialization Requirements
When the power is first applied to a HD44780 based module it will self
initialize provided the power supply rises at the correct rate. Interestingly
the default wakeup state has the display off! With a normal power supply,
146 Chapter 7 Expansion Board For C8051F020 Target Board
LCD Software
Communication with the LCD can generally be divided into either data
which is to be displayed, or commands which affect how it operates. The
difference is caused by the state of the two control lines, RS and RW.
Figure 7.14 shows the two functions for writing either data or a command
byte.
char lcd_dat(char dat)
{
lcd_busy_wait();
LCD_CTRL_PORT = LCD_CTRL_PORT | RS_MASK; // RS = 1
LCD_CTRL_PORT = LCD_CTRL_PORT & ~RW_MASK; // RW = 0
LCD_DAT_PORT = dat;
pulse_E();
return 1;
}
These functions rely on several #defines and a macro for pulsing the
enable line which are shown in Figure 7.15. The MASK values reflect the
bits the control lines are connected to.
void lcd_busy_wait(void)
{
LCD_DAT_PORT = 0xFF; // allow port pins to float
LCD_CTRL_PORT = LCD_CTRL_PORT & ~RS_MASK; // RS = 0
LCD_CTRL_PORT = LCD_CTRL_PORT | RW_MASK; // RW = 1
small_delay(1);
LCD_CTRL_PORT = LCD_CTRL_PORT | E_MASK; // E = 1
do { // wait for busy flag to drop
small_delay(1);
} while ((LCD_DAT_PORT & 0x80) != 0);
}
↑↓ 0 0 0 0 0 0 0 0 0 1 01
Delay at least 37 µs, or use busy bit
Control Data Data Description
E RS RW B7 B6 B5 B4 B3 B2 B1 B0 Hex Display on/off
ctrl. Display on,
↑↓ 0 0 0 0 0 0 1 1 1 0 0E curser on, No
blink.
150 Chapter 7 Expansion Board For C8051F020 Target Board
LCD Integration
While it is nice to be able to write a character to the display, it is much
more convenient to write entire strings – especially if they can be
formatted. Astute readers may have noticed that the function
lcd_dat() in Figure 7.14 returned char which appeared unnecessary.
It does so to take advantage of a feature of the KeilTM compiler which has
the ability to redefine built-in library functions.
This can be done by renaming lcd_dat() as putchar(), which is an
ANSI C function in the stdio library. KeilTM have written putchar() to
send characters to the serial port. By replacing it with lcd_dat() they
now go to the LCD.
Replacing one function with another doesn’t appear very helpful. The
beauty of this approach is that other standard functions call putchar()
to achieve their low level output. One of the more useful I/O functions is
printf() which can now send formatted output to the LCD! This can
be seen in Figure 7.18.
void main(void)
{
int ctr;
init();
P5 = 0x0F;
lcd_init();
while (1)
{
printf("Hello World %4d ", ctr++);
huge_delay(3);
}
}
Figure 7.18 Writing a string to the LCD
This will quickly write past the end of the display and, after 64 characters,
wrap around to the second line, eventually coming back to overwrite the
first line. A function called lcd_goto() is also very useful and is shown in
Figure 7.19. To write to the start of the first line use lcd_goto(0), the
second line would use lcd_goto(0x40);
void main(void)
{
init();
lcd_init();
Timer3_Init(SYSCLK / SAMPLE_RATE); // initialize Timer3 to
// overflow at SAMPLE_RATE
ADC0_Init(); // init ADC
AD0EN = 1; // enable ADC
EA = 1; // Enable global interrupts
while (1)
{
if (adc_ready)
{
EA = 0; // Disable interrupts
adc_ready = 0;
printf("ADC value %4u ", adc_result);
EA = 1; // Enable interrupts
lcd_goto(0x00);
}
}
}
The key points to observe in main() are calling the various initialization
routines, activating the interrupts, and the way the flag adc_ready is
used to determine that a conversion is ready for display. In particular,
note that interrupts are switched off while accessing adc_result. This is
necessary to prevent the ADC ISR from changing the value half way
through printing it. All the same it is a poor practice to switch interrupts
off for a significant time (remember the LCD is quite slow). A better
Chapter 7 Expansion Board For C8051F020 Target Board 153
approach is to use a second buffer to copy the result into, before printing
it. This is left as an exercise for the reader.
RS 173-675 AIN0.2
P5.0 R19 SW1
VCC 100
DAC1 Test Point 1
VCC Pot1
+3VD2 (+3.3VDC) DAC0 Test Point 2 0.5 AGND DGND
VCC 100k P5.1 R20 SW2
C1 AIN0.2 Test Point 3 Modified to R17 R18 AIN0.3 100
DGND (Digital Gnd) 100nF pull up to +5V 1k 1k
AIN0.3 Test Point 4
DGND TR1 DGND
Res Thermal R21
t°
Pot2
0.5 DGND DGND
10k
KPT-1105D
U1 +5V LCD1 S1
VUNREG R23 DGND +5V VSS P4.0 R1 1 16
Vin Vout VSS R2
100 VDD P4.1 2 15
GND C4 VDD R3
C2 C3 VO P4.2 3 14
SW5 4.7uF VO R4
100nF 100nF RS P4.3 4 13
RS R5
R/W P4.4 100 5 12
R/W R6
EN P4.5 6 11
E R7
DB0 P4.6 7 10
DB0 R8
DB1 P4.7 8 9
DB1
LCD Reset Sw DGND DB2
DB2 100
DB3 SW DIP-8
DB3
DB4 DGND
DB4 R13
DB5 P5.7
DB5
DB6 330
Power Reg DB7
NC1
DB6
DB7
LED1
NC R14
NC2 P5.6
NC
330
LCD, 16-PIN LED2
8.0 Introduction
One of the many tasks that are normally performed by a CPU is to time
internal and external events. The microprocessor usually provides the
timing functions such as timeout delays and event counting by means of
software. Many a times, these functions are implemented using loops
within the software. This effectively takes a lot of CPU’s processing time.
A timer/counter is useful in the sense that it is able to handle various
timing applications independently; hence it frees the CPU of such tasks,
allowing it to do other urgent functions.
A timer/counter consists of a series of divide-by-two flip-flops (FF). Each
FF is clocked by the Q output of the previous FF, as shown in Figure 8.1.
Each stage, starting from the LSB F/F to the MSB F/F, generates an
output signal which is half the frequency of its own clock input. Thus a 3-
bit timer in Figure 8.1 will divide the input clock frequency by 8 (23).
Normally a timer/counter has added features like producing an interrupt
at the end of a count. By adding the timer overflow F/F to the counter, it
will aid to generate such an interrupt signal. Figure 8.1 shows that the
output of the last stage (MSB) clocks a timer overflow flag. The counter
will count from 000b to 111b and set the overflow flag on the transition
from 111b to 000b.The timing diagram is shown in Figure 8.2.
Timer
3 bit Timer Flip Overflow
Flops F/F or
VCC Flag
VCC
J J J J
Q Q Q Q
K K K K
QN QN QN QN
Clock CLK CLK CLK CLK
JKFF JKFF JKFF JKFF
LSB MSB
Figure 8.1 Schematic of a 3-Bit Timer
Chapter 8 Timer Operations and Programming 159
Clock
LSB
M SB
0 1 2 3 4 5 6 7 0
Count
Flag
Timer 0 and Timer 1 are nearly identical and have four primary modes of
operation. Timer 2 offers additional capabilities not available in Timers 0
and 1. Timer 3 is similar to Timer 2, but without the capture or Baud rate
generation modes. Timer 4 is identical to Timer 2, except it supplies
baud rate generation capabilities to UART1 instead. The main Timer
operation modes are discussed in the following sections.
The timers are fully independent, and each may operate in a different
mode. Timers 1, 2 and 4 may be used for UART baud rate generation in
mode 2. Chapter 10 has more information on baud rate generation.
B. For Timer 3:
1. Write the auto-reload value into the auto-reload registers
(TMR3RLL and TMR3RLH)
2. Write the starting value for count up sequence into the
count registers (TMR3L and TMR3H)
3. Select the desired clock source (T3XCLK) and frequency
(T3M), set the control bits (TR3) and turn on Timer 3
(TMR3CN)
Chapter 8 Timer Operations and Programming 161
Starting the timer by setting TRx (TCON.4 and TCON.6 – refer to Figure
8.3 and Table 8.6) does not reset the count register. The count register
should be initialized to the desired value before enabling the timer. If an
interrupt service routine is required, the interrupt flag is enabled and an
interrupt is generated whenever the timer overflows. This applies to all
timer modes, for Timers 0 to 4.
Chapter 8 Timer Operations and Programming 163
CKCON TMOD
TTTT G C T T G C T T
4 2 1 0 A / 1 1 A / 0 0
MMMM T T MM T T MM
E 1 1 0 E 0 1 0
1 0
12 0
SYSCLK 0
T0 TF1
TCLK TL0 TR1
Crossbar TF0 Interrupt
(8 bits) TR0
IE1
TCON
/INT0 TR0 IT1
IE0
IT0
GATE0
TH0 Reload
(8 bits)
The timer low byte (TLx) operates as an 8-bit timer while the timer high
byte (THx) holds a reload value. When the count in TLx overflows from
FFH to 00H, the timer flag is set and the value in THx is loaded into TLx.
Counting continues from the reload value up to the next FFH overflow,
and so on.
This mode is convenient as the timer overflows at specific periodic
intervals once TMOD and THx are initialized. TLx must be initialized to
the desired value before enabling the timer for the first count to be
correct.
Timer 1 can be used as an 8-bit baud rate generator for UART0 and/or
UART1 in mode 2.
164 Chapter 8 Timer Operations and Programming
CKCON TMOD
TT TT G C T T G C T T
4 2 1 0 A / 1 1 A / 0 0
MMMM T T MM T T MM
E 1 1 0 E 0 1 0
1 0
12 0
TR1 TH0
SYSCLK TF1 Interrupt
(8 bits) TR1
TF0 Interrupt
1 TR0
0 IE1
TCON
IT1
IE0
IT0
T0
TL0
Crossbar
(8 bits)
/INT0 TR0
GATE0
Timers 2 & 4
As mentioned before, Timer 4 is identical to Timer 2. This mode is
selected by clearing the CP/RLz bit (Refer to Figure 8.5, Table 8.7 for
T2CON and Table 8.10 for T4CON).
NOTE: z = 2 or 4
The count register reload occurs on an FFFFH to 0000H transition and
sets the TFz timer overflow flag. An interrupt will occur if enabled. On
overflow, the 16 bit value held in the two capture registers (RCAPzH and
RCAPzL) is automatically loaded into the count registers (TLz and THz)
and the timer is restarted.
Setting TRz to 1 enables and starts the timer. The timers can use either
the system clock or transitions on an external input pin (Tz) as the clock
source (counter mode), specified by the C/Tz bit. If EXENz is set to 1, a
high-to-low transition on TzEX will also cause a Timer z reload, and a
Timer z interrupt if enabled. If EXENz is 0, transitions on TzEX will be
ignored.
The appropriate crossbars have to be configured to enable the input
pins. TLz and THz must be initialized to the desired value before
enabling the timer for the first count to be correct.
CKCON
TTTT
4 2 1 0
MMMM
12 0
SYSCLK
1 0
Example:
Timer 3
Timer 3 is always configured as an auto-reload timer, with the reload
value held in TMR3RLL and TMR3RLH. The operation is essentially the
same as for Timers 2 and 4, except for slight differences in register
names and clock sources (refer to Figure 8.6). TMR3CN is the only SFR
required to configure Timer 3.
T3XCLK
External
8 (to ADC)
Oscillator Source
1
TCLK TMR3L TMR3H TF3 Interrupt
12 0
SYSCLK 0
1 TR3 TMR3CN
TR3
T3M
(from SMBus) TOE Reload T3XCLK
T3M TMR3RLL TMR3RLH
SCL Crossbar
CKCON
T TTT
4 2 1 0
MMMM
12 0
SYSCLK
1 0
T2CON
EXEN2
TCLK0
RCLK0
T2EX EXF2 Interrupt
Capture TF2
RCAP2L RCAP2H
EXEN2
The timers can use either SYSCLK, SYSCLK divided by 12, or high-to-
low transitions on the Tz input pin as the clock source when operating in
Capture mode. Clearing the C/Tz bit selects the system clock as the
input for the timer (divided by 1 or 12 as specified by TzM). When C/Tz is
set to 1, a high-to-low transition at the Tz input pin increments the
counter register.
168 Chapter 8 Timer Operations and Programming
C/T2
SYSCLK 2 0
RCLK0
Timer 2
Overflow
T2 Crossbar 1 TCLK TL2 TH2 0
16 RX0 Clock
TR2
PCON Reload 1
SS SS S I
MS MS TD RCAP2L RCAP2H
OT OT OL
DA DA PE
0 T 1 T
0 1 0
16 TX0 Clock
2 0
1
Timer 1
Overflow
CP/RL2 TCLK0
1 C/T2
TR2
T2CON
EXEN2
TCLK0
EXEN2 RCLK0
EXF2 Interrupt
TF2
T2EX Crossbar
Figure 8.8 Block Diagram of Timer 2 in Baud Rate Generation Mode (Mode 2)
Chapter 8 Timer Operations and Programming 169
In Baud Rate Generator mode, the Timer z time base is the system clock
divided by two. When selected as the UARTx baud clock source, Timer z
defines the UARTx baud rate as follows:
SYSCLK
BaudRate =
(65536 − [ RCAPzH , RCAPzL ]) × 32
If a different time base is required, setting the C/Tz bit to 1 will allow the
time base to be derived from the external input pin Tz. In this case, the
baud rate for the UART is calculated as:
FCLK
BaudRate =
(65536 − [ RCAPzH , RCAPzL ]) × 16
where FCLK is the frequency of the signal (TCLK) supplied to Timer z and
[RCAPzH, RCAPzL] is the 16 bit value held in the capture registers.
Figure 8.9 Block Diagram of Timer 4 in Baud Rate Generation Mode (Mode 2)
170 Chapter 8 Timer Operations and Programming
Example:
;----------------------------------------------------
; Using Timer 4 in Mode 2 to generate a baud rate of
; 2400 for UART1. System clock = 22.1184 MHz external
; oscillator
;----------------------------------------------------
ORL CKCON, #40h ; Timer 4 uses system clock
MOV RCAP4L, #0E0h ; Auto-reload value=FEE0
MOV RCAP4H, #0FEh
MOV TL4, RCAP4L ; Initialize count registers
MOV TH4, RCAP4H
MOV T4CON, #00110100b ; Set Timer 4 in mode 2 and
; start timer
TMOD
The TMOD register contains two groups of 2 bits each (T0M1-T0M0 and
T1M1-T1M0) that set the operating mode for Timer 0 and 1 (Table 8.4
and Table 8.5).
TMOD is not bit addressable. Generally, it is loaded once by software at
the beginning of a program to initialize the timer modes. Thereafter, the
timer can be stopped, started and so on by accessing the other timer
SFRs.
M1 M0 Mode Description
0 0 0 13 bit Counter/Timer
0 1 1 16 bit Counter/Timer
8 bit Counter/Timer with Auto-
1 0 2
reload
Timer 1: Inactive
1 1 3
Timer 0: Two 8 bit Counter/Timers
Table 8.5 Timer Modes
TCON
The TCON register contains status and control bits for Timer 0 and 1
(Table 8.6). The upper four bits in TCON are used to turn the timers on
and off (TR0, TR1) or to signal a timer overflow (TF0, TF1). The lower
four bits in TCON have nothing to do with the timers as such. They are
used to detect and initiate external interrupts. Please refer to Chapter 11
for more details on interrupts.
The other 4 registers associated with Timers 0 and 1 are TL0, TL1, TH0
and TH1. These enable access to the timers as two separate bytes.
T2CON
The operating mode of Timer 2 is selected by setting the configuration
bits in T2CON (Table 8.7 and Table 8.8).
The RCAP2L and RCAP2H registers capture the low and high byte of
Timer 2 respectively when Timer 2 is configured in capture mode. If
Timer 2 is configured in auto-reload mode, these registers hold the low
and high byte of the reload value. TL2 and TH2 are used to access
Timer 2 as two separate bytes.
TMR3CN
Timer 3 is always configured as an auto-reload timer, with the 16-bit
reload value held in the TMR3RLL (low byte) and TMR3RLH (high byte)
registers.
TMR3L and TMR3H are the low and high bytes of Timer 3. TMR3CN is
used to select the clock source and is the only SFR used to configure
Timer 3 (Table 8.9).
T4CON
The operating mode of Timer 4 is selected by setting the configuration
bits in T4CON (Table 8.10 and Table 8.11). The T4CON functions are
identical to T2CON.
The RCAP4L and RCAP4H registers capture the low and high byte of
Timer 4 respectively when Timer 4 is configured in capture mode. If
Timer 4 is configured in auto-reload mode, the registers hold the low and
high byte of the reload value. TL4 and TH4 are used to access Timer 4
as two separate bytes.
#include <c8051f020.h>
void main(void)
{
unsigned char blink_speed = 10;
Init_Port();
LED = 0;
Init_Timer2(SYSCLK/12/blink_speed);
//-- Initialize Timer3 to generate interrupts
In the main() function, the Watchdog timer is disabled, the Crossbar and
I/O ports are configured and the Timer 2 is initialized. The endless while
loop makes the program go on forever.
Chapter 8 Timer Operations and Programming 179
T2CON = 0x00;
// T2CON.1 = 0 --> T2 set for Timer function
// (C/T2) i.e. incremented by clock defined by T2M
// T2CON.0 = 0 --> Allow Auto-reload on Timer2
// overflow (CP/RL2)
// T2CON.3 = 0 --> High-to-Low transitions on
// T2EX ignored (EXEN2)
// T2CON.2 = 0 --> Disable Timer2
The above code segment initializes the Timer 2 in the desired mode of
operation.
180 Chapter 8 Timer Operations and Programming
P3_input = ~P3;
if (P3_input & 0x80) // if bit 7 is set,then the switch
// is pressed
LED = ~LED; // change state of LED
}
The above code segment will be executed each time the Timer 2
overflows.
The definition of LED is given below. The LED is connected to pin 6 of
Port 0.
9.0 Introduction
A fully integrated control system with both analog and digital capabilities
is the emerging trend in the technological industry. There is currently a
demand for sophisticated control systems with high-speed precision
digital and analog performance. Signals in the real world are analog and
have to be digitized for processing.
This chapter will introduce the analog and digital peripherals of the
C8051F020. The chip contains one 8 bit and one 12 bit analog-to-digital
converters (ADCs) and two 12 bit digital-to-analog converters (DACs).
The C8051F020 also contains programmable gain amplifiers (PGAs),
analog multiplexer (8 channel and 9 channel), two comparators, a
precision voltage reference, and a temperature sensor to support analog
applications. These are shown in Figure 9.1. The following sections will
discuss the operation of these peripherals, as well as the SFRs used to
configure them. A voltage reference has to be used when operating the
ADC and DAC. Please refer to Section 2.8 for more details on setting the
Voltage Reference.
VDD
VDD
Port I/O
Config.
VDD Digital Power
DGND
UART0
DGND
DGND 8 UART1
P0
Drv
P0.0
P0.7
0
AV+
AV+ Analog Power SMBus C
AGND
AGND SPI Bus
R P1 P1.0/AIN1.0
TCK
Boundary Scan
5 PCA
O
S
Drv P1.7/AIN1.7
TMS JTAG
TDI
TDO
Logic Debug HW 1 SFR Bus
Timers 0,
1, 2, 4
S
B
P2 P2.0
P3.7
External Latches
XTAL1
XTAL2
Oscillator o 256 byte
Crossbar
Circuit System RAM
Internal
Clock r Config.
Oscillator
4kbyte VREF1
e RAM ADC
Prog
A
M 8:1
500ksps
VREF VREF Gain U
(8-Bit) X
VREFD
DAC1
External Data Memory Bus P4.0
DAC1
(12-Bit) Bus Control C P4 Latch P4 P4.4
T DRV P4.5/ALE
DAC0 L P4.6/RD
DAC0
(12-Bit) P4.7/WR
VREF0
P5 Latch P5 P5.0/A8
AIN0.0 A DRV
AIN0.1 Address Bus d P5.7/A15
AIN0.2 A ADC d P6 Latch P6 P6.0/A0
AIN0.3 M Prog
AIN0.4 U Gain 100ksps r DRV P6.7/A7
AIN0.5
AIN0.6
X (12-Bit)
AIN0.7
D P7 Latch P7 P7.0/D0
TEMP Data Bus
SENSOR a DRV
CP0+ P7.7/D7
CP0 t
CP0-
a
CP1+
CP1
CP1-
AIN0 + AV+ 12
SYSCLK
REF
AIN1 - AD0EN
AIN2 +
ADC0H
AV+
AIN3 9-to-1
-
AMUX 12-Bit
AIN4 +
(SE or
X + SAR 12
AIN5 - DIFF) -
AIN6 +
AGND
ADC
ADC0L
AIN7 -
TEMP
AD0CM
SENSOR 00 AD0BUSY (W)
AD0BUSY
11 Timer 2 Overflow
AD0WINT
AD0LJST
AIN67IC
AIN45IC
AIN23IC
AIN01IC
AD0CM1
AD0CM0
AD0SC4
AD0SC3
AD0SC2
AD0SC1
AD0SC0
AD0INT
AD0TM
AD0EN
AD0CM
AMX0CF AMX0SL ADC0CF ADC0CN
ADC0H[3:0]:ADC0L[7:0], if AD0LJST = 0
(ADC0H[7:4] will be the sign-extension of ADC0H.3 for a differential
reading, otherwise = 0000b).
ADC0H[7:0]:ADC0L[7:4], if AD0LJST = 1
(ADC0L[3:0] = 0000b).
Example:
If the ADC0 output data word = FFFH (111111111111b) & AD0LJST = 0:
ADC0H:ADC0L = 0FFFH (0000111111111111)
If AD0LJST = 1:
ADC0H:ADC0L = FFF0H (1111111111110000b)
188 Chapter 9 ADC and DAC
Gain n
ADC 0Code = Vin × ×2
VREF
where n= 12 for single-ended and n = 11 for differential inputs.
Example:
AIN0 is used as the input in single-ended mode (AMX0CF=00H and
AMXSL=00H). Gain is set to 1.
Example:
AIN0 and AIN1 are used as the inputs in differential mode
(AMX0CF=01H and AMXSL=00H). Gain is set to 1.
Chapter 9 ADC and DAC 189
The next multiplexer input channel (Step 3) can be selected in the ADC0
ISR after the current channel has been converted and the AD0INT bit
cleared. The newly selected channel will then be converted in the next
conversion cycle. When initiating conversions by setting AD0BUSY to 1,
the AD0INT bit (ADC0CN.5) may be polled to determine when a
conversion has completed. The recommended polling procedure is:
190 Chapter 9 ADC and DAC
1. Clear AD0INT to 0
2. Set AD0BUSY to 1
3. Poll AD0INT for 1
4. Process ADC0 data
Example:
;----------------------------------------------------
; Vref setup:
; Enable internal bias generator and internal
; reference buffer, and select ADC0 reference from
; VREF0 pin.
;----------------------------------------------------
;----------------------------------------------------
; System clock = 16 MHz internal oscillator.
;----------------------------------------------------
;----------------------------------------------------
; Configure ADC0 to use AIN0 as single-ended input
; only. Other inputs are not used.
;----------------------------------------------------
#include <c8051f020.h>
//--------------------------------------------------------------
// 16-bit SFR Definitions for C8051F020
//--------------------------------------------------------------
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
sfr16 ADC0 = 0xbe; // ADC0 data
//--------------------------------------------------------------
// Global CONSTANTS
//--------------------------------------------------------------
#define SYSCLK 22118400 //-- External Crystal Oscillator @22MHz
Init_Clock();
Init_Port();
Init_ADC0();
LED = 0; //-- turn off the LED
//--------------------------------------------------------------
void Init_Clock(void)
{
OSCXCN = 0x67; //-- 0110 0111b
//-- External Osc Freq Control Bits (XFCN2-0) set to 111
// because crystal frequency > 6.7 MHz
// Crystal Oscillator Mode (XOSCMD2-0) set to 110
//--------------------------------------------------------------
void Init_Port(void) //-- Configures the Crossbar and GPIO ports
{
XBR1 = 0x00;
XBR2 = 0x40; //-- Enable Crossbar and weak pull-ups
// (globally)
P1MDOUT |= 0x40; //-- Enable P1.6 (LED) as push-
// pull output
}
//--------------------------------------------------------------
//-- Configure Timer3 to auto-reload and generate an interrupt
// at interval specified by <counts> using SYSCLK/12 as its
// time base.
void Init_Timer3 (unsigned int counts)
{
TMR3CN = 0x00; //-- Stop Timer3; Clear TF3;
//-- use SYSCLK/12 as timebase
//--------------------------------------------------------------
void Init_ADC0(void)
{
REF0CN = 0x07; //--Enable internal bias generator and
// internal reference buffer
// Select ADC0 reference from VREF0 pin
// Internal Temperature Sensor ON
ADC0CF = 0x81; //--SAR0 conversion clock=1.3MHz
// approx., Gain=2
//--------------------------------------------------------------
//-- Interrupt Service Routine
The ADC initialization code and the corresponding ISR are shown below:
//-- ADC0_Temp_ISR.C
//--------------------------------------------------------------
void Init_ADC0(void)
{
REF0CN = 0x07; //-- Enable internal bias generator and
// internal reference buffer
// Select ADC0 reference from VREF0 pin
// Internal Temperature Sensor ON
//--------------------------------------------------------------
void ADC0_ISR(void) interrupt 15
{
AD0INT = 0; //-- clear ADC0 conversion complete
// interrupt flag
ADC0_reading = ADC0;
}
Chapter 9 ADC and DAC 195
SYSCLK
AD0SC = −1
CLK SAR 0
ADC0 Internal Amplifier Gain (PGA)
000: Gain = 1
001: Gain = 2
2-0 AMP0GN2-0 010: Gain = 4
011: Gain = 8
10x: Gain = 16
11x: Gain = 0.5
Table 9.4 ADC0CF: ADC0 Configuration Register
SYSCLK
CLK SAR 0 =
AD0SC + 1
If the System Clock Frequency is 16 MHz and AD0SC4-0 is set to
10000b, then the SAR0 conversion frequency is 16MHz/17 = 941.176
KHz. Hence if the value loaded in ADC0CF is 10000000, then the SAR0
conversion frequency will be 941 KHz approximately and the PGA0 gain
will be set to 1.
198 Chapter 9 ADC and DAC
The ADC0H and ADC0L registers are used to store the MSB and LSB of
the ADC0 data word respectively.
The ADC0GTH, ADC0GTL, ADC0LTH and ADC0LTL registers are the
ADC0 Greater-Than and Less-Than registers respectively. These
registers are used in the ADC0 Programmable Window Detector mode to
store the 16 bit limits for the ADC0 output. The Programmable Window
Detector mode is used to save code space and CPU bandwidth to
deliver faster system response times. An interrupt is generated when an
out-of-bound condition is detected.
AV+
REF
AD1EN
AIN1.0 (P1.0)
AIN1.1 (P1.1) AV+
AIN1.2 (P1.2)
8-Bit
AIN1.3 (P1.3)
X + SAR
ADC1
8-to-1 8
AIN1.4 (P1.4) AMUX -
AIN1.5 (P1.5) AGND
ADC
AIN1.6 (P1.6)
000 Write to AD1BUSY
AIN1.7 (P1.7)
001 Timer 3 Overflow
AD1CM
Start Conversion
010 CNVSTR
011 Timer 2 Overflow
1xx Write to AD0BUSY
(synchronized with
AMX1AD2
AMX1AD1
AMX1AD0
AMP1GN1
AMP1GN0
AD1BUSY
ADC0)
AD1CM2
AD1CM1
AD1CM0
AD1SC4
AD1SC3
AD1SC2
AD1SC1
AD1SC0
AD1INT
AD1CM
AD1TM
AD1EN
Example:
1. Clear AD1INT to 0
2. Set AD1BUSY to 1
3. Poll AD1INT for 1
4. Process ADC1 data
Example:
;----------------------------------------------------
; Vref setup:
; Enable internal bias generator and internal
; reference buffer, and select ADC1 reference from
; VREF1 pin.
;----------------------------------------------------
;----------------------------------------------------
; System clock = 16 MHz internal oscillator.
;----------------------------------------------------
;----------------------------------------------------
#include <c8051f020.h>
//--------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//--------------------------------------------------------------
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
//--------------------------------------------------------------
// Global CONSTANTS
//--------------------------------------------------------------
#define SYSCLK 16000000 //-- Internal Osc. 16MHz
void main(void)
{
EA = 0; //-- disable global interrupts
Init_Clock();
Init_Port();
Init_ADC1();
LED = 0; //-- turn off the LED
}
204 Chapter 9 ADC and DAC
//--------------------------------------------------------------
// Initialises the clock source
void Init_Clock(void)
{
OSCICN = 0x87; //-- 10000111b
//-- Enable 16 MHz Internal Oscillator
//-- and use it as System Clock
//-- Missing Clock Detector Enabled
//--------------------------------------------------------------
// Configures the Crossbar and GPIO ports
void Init_Port(void)
{
XBR1 = 0x00;
XBR2 = 0x40; //-- Enable Crossbar and weak pull-ups
// (globally)
P1MDIN = 0xFE; //-- P1.0 configured as analog input
// 11111110b, rest all output
P1MDOUT |= 0x40; //-- Enable P1.6 (LED) as push-pull
// output
P1 |= 0x01; //-- Disable ouput driver for P1.0 by
// setting P1.0=1
}
//--------------------------------------------------------------
//--------------------------------------------------------------
// Configure Timer3 to auto-reload and generate an interrupt
// at interval specified by <counts> using SYSCLK/12 as its
// time base.
//--------------------------------------------------------------
void Init_ADC1(void)
{
REF0CN = 0x03; //-- Enable internal bias generator and
// internal reference buffer
// Select ADC1 reference from VREF1 pin
ADC1CF = 0x81; //-- SAR1 conversion clock=941KHz
// approx., Gain=1
AMX1SL = 0x00; //-- Select AIN1.0 input
ADC1CN = 0x82; //-- enable ADC1, Continuous Tracking
// Mode, Conversion initiated on Timer
// 3 overflow
}
//--------------------------------------------------------------
//--------------------------------------------------------------
// Interrupt Service Routine
SYSCLK
AD1SC = −1
CLK SAR1
2 - UNUSED. Read=0, Write=don’t care
ADC1 Internal Amplifier Gain (PGA)
00: Gain = 0.5
1-0 AMP1GN1-0 01: Gain = 1
10: Gain = 2
11: Gain = 4
Table 9.7 ADC1CF: ADC1 Configuration Register
DAC0EN
DAC0CN
DAC0MD1
DAC0MD0
DAC0DF2 REF
DAC0DF1 AV+
DAC0DF0
DAC0H
8 8
Latch
Dig. MUX
12
DAC0
DAC0
DAC0L
8 8
Latch
AGND
DAC1H
Timer 3
Timer 4
Timer 2
DAC1EN
DAC1CN
DAC1MD1
DAC1MD0
DAC1DF2 REF
DAC1DF1
DAC1DF0 AV+
DAC1H
8 8
Latch
Dig. MUX
12
DAC1
DAC1
DAC1L
8 8
Latch
AGND
Output Scheduling
The DACs have four modes of output scheduling:
1) Output on Demand (Writing to high byte of DACx data word
register, DACxH)
2) Timer 2 Overflow
3) Timer 3 Overflow
4) Timer 4 Overflow
NOTE: x = 0 or 1
The Output on Demand mode is the default mode. In this mode, the DAC
output is updated when DACxH is written to.
Writes to DACxL are held and have no effect on the DACx output until
DACxH is written to. Therefore, to write a 12 bit data word at full
resolution to DACx, the write sequence should be DACxL, followed by
DACxH.
The DACs can be used in 8 bit mode by initializing DACxL to the desired
value (typically 00H) and writing data to only DACxH. See section on
Output Scaling.
In the Timer Overflow modes, the DAC outputs are updated by a timer
overflow independently of the processor. Writes to both DAC data
registers (DACxL and DACxH) are held until an associated timer
overflow event occurs. The DACxH:DACxL contents are then copied to
the DAC input latches, allowing the DAC output to change to the new
value.
Timer Overflow Modes are useful for scheduling outputs at periodic
intervals, e.g. waveform generation at a defined output frequency.
210 Chapter 9 ADC and DAC
Output Scaling
The format of the 12 bit data word in the DACxH and DACxL registers
can be configured by setting the appropriate DACxDF bits
(DACxCN.[2:0]). The five data word orientations are shown in Figure 9.5.
DACxDF2-0 = 000:
DACxH DACxL
MSB LSB
001:
DACxH DACxL
MSB LSB
010:
DACxH DACxL
MSB LSB
011:
DACxH DACxL
MSB LSB
1xx:
DACxH DACxL
MSB LSB
Figure 9.5 DAC Data Format
Example:
;----------------------------------------------------
; Vref setup:
; Enable internal bias generator and internal
; reference buffer. Pins 1-2 of J22 on the C8051F020
; development board must be connected to use the
; internal voltage reference generated as input to
; VREFD
;----------------------------------------------------
;----------------------------------------------------
; DAC0 Setup
;----------------------------------------------------
;----------------------------------------------------
; Timer 4 Setup
; NOTE: System clock = 22.1184 MHz external
; oscillator
;----------------------------------------------------
DAC0H and DAC0L are used to store the most significant and least
significant DAC0 data word respectively.
Chapter 9 ADC and DAC 213
DAC1H and DAC1L are used to store the most significant and least
significant DAC1 data word respectively.
214 Chapter 9 ADC and DAC
10.0 Introduction
With serial communication, data is transferred one bit at a time. An
interface device converts the CPU’s parallel data and transmits it across
a single link to another device. This data has to be reconstructed again
before it can be understood by the device.
There are 2 types of serial communication – asynchronous and
synchronous.
With asynchronous communication, the transmitter and receiver do not
share a common clock. The transmitter shifts the data onto the serial line
using its own clock. The transmitter also adds the start, stop and parity
check bits as shown in Figure 10.1. The receiver will extract the data
using its own clock and convert the serial data back to the parallel form
after stripping off the start, stop and parity bits.
D0 D1 D2 D3 D4 D5 D6 D7
1 Asynchronous Byte
Sync Sync Header Header Data Data Data Check Check Sync Sync
Char Char Byte Byte Char 1 Char 2 Char n Byte Byte Char Char
Tx Tx
External
CPU UART TTL to Service
RS-232C Device
Rx Level Shifter Rx
Parallel
Data (a) (b)
(a) TTL output from UART (b) Serial output, RS-232C levels
buffer while a second is being received. If the CPU reads the first
character before the second has been fully received, data are not lost. A
Receive Overrun bit indicates when new received data is latched into the
receiver buffer before the previous received byte is read.
NOTE: x = 0 or 1. The two UARTs are functionally identical.
The UART block diagram is shown in Figure 10.4. Each UART is
accessed by two SFRs, SBUFx and SCONx. The Serial Port Buffer
(SBUFx) is essentially two buffers - writing loads data to be transmitted
and reading accesses received data. These are two separate and
distinct buffers (registers): the transmit write-only buffer and the receive
read-only register.
The Serial Port Control register (SCONx) contains status and control
bits. The control bits set the operating mode for the serial port, and
status bits indicate the end of the character transmission or reception.
The status bits are tested in software (polling) or programmed to cause
an interrupt.
The serial port frequency of operation, or baud rate, can be fixed
(derived from the on-chip oscillator) or variable. If a variable baud rate is
used, Timer 1 supplies the baud rate clock and must be programmed
accordingly.
In the following sections we will discuss the operational modes of the
UARTs and the steps required to configure them for use.
Chapter 10 Serial Communication 219
SFR Bus
Write to
SBUF
TB8
D
SET
Q
SBUF
(Transmit Shift) TX
CLR
Crossbar
Zero Detector
Start Tx Control
Tx Clock Send
Tx IRQ
UART SCON TI
S S S R T R T R Serial Port
Baud Rate (UART0/1)
M M M E B B I I
Generation 0 1 2 N 8 8 Interrupt
Logic RI
EN Rx IRQ
Rx Clock Load
SBUF
Rx Control
Address
Match
Start
Shift 0x1FF Port I/O
SADDR
SBUF Match Detect
(Receive Latch) SADEN
Read
SBUF
SFR Bus
RX
Crossbar
Example:
TXx CLK
C8051F020 Shift Register
RXx Data
8 Extra Outputs
Eight data bits are transmitted or received on the RXx pin with the LSB
first, and the TIx, Transmit Interrupt Flag (SCONx.1) is set at the end of
the 8th bit time. The baud rate is fixed at
SYSCLK
12
Data transmission begins when an instruction writes a data byte to the
SBUFx register. Data are shifted out on RXx with clock pulses sent out
TXx (Figure 10.6). Each transmitted bit is valid on the RXx pin for 1
machine cycle.
Data reception begins when the RENx Receive Enable bit (SCONx.4) is
set to 1 and the RIx Receive Interrupt Flag (SCONx.0) is cleared. One
cycle after the eighth bit is shifted in, the RIx flag is set and reception
stops until software clears the RIx bit. An interrupt will occur if enabled
when either TIx or RIx are set.
The general rule is to set RENx at the beginning of a program to initialize
the UART and then clear RIx to begin a data input operation. When RIx
is cleared, clock pulses are written out to TXx, beginning the next
machine cycle and data are clocked in from RXx.
RXx is used for both data input and output and TXx serves as the clock.
The clocking of data into the UART occurs on the rising edge of TXx.
Mode 0 Transmit
Mode 0 Receive
SYSCLK
BaudRate = for Timer 2 or 4
32 × (65536 − [RCAPzH , RCAPzL ])
Bit Times
Bit Sampling
If a valid start bit was detected, character reception continues. The start
bit is skipped, the 8 data bits are stored in SBUFx, the stop bit is stored
in RB8x and the RIx flag is set. However, these only occur if the following
conditions exist:
1. RIx = 0
2. SM2x = 0 (stop bit ignored) or SM2x = 1 and the received stop bit = 1
If these conditions are not met, SBUFx and RB8x will not be loaded and
the RIx flag will not be set. An interrupt will occur if enabled when either
TIx or RIx is set. The requirement that RIx = 0 ensures that software has
read the previous character (and cleared RIx).
224 Chapter 10 Serial Communication
Example:
⎛ SYSCLK ⎞
BaudRate = 2SMODx × ⎜
⎝ 64 ⎟⎠
Mark Start
Bit D0 D1 D2 D3 D4 D5 D6 D7 D8 Stop
Space Bit
Bit Times
Bit Sampling
The receive and transmit instruction sequences above are usually part of
standard input character and output character subroutines. The following
example illustrates a subroutine called OUTCHR which transmits the 7-
bit ASCII code in the accumulator out UART0, with odd parity as the 8th
bit.
Example:
The other registers associated with the UARTs are SBUFx, SADDRx and
SADENx. SBUFx accesses 2 registers, a transmit shift register and a
receive latch register. When data is written to SBUFx, it goes to the
transmit shift register and is held for serial transmission. Writing a byte to
SBUFx initiates transmission. A read of SBUFx returns the contents of
the receive latch. SADDRx and SADENx deal with slave addresses and
will not be discussed here.
The user may click on the desired radio button and click the Send button
to send the command to the target board. The command sent is a one
byte data – 0x01 for slow, 0x02 for medium and 0x03 for fast blinking
speed respectively. The serial communication is at a baud rate of
115200. The baud rate is generated using Timer 1. Each time a new
command is received by the program running on C8051F020, the
blinking speed of the LED is altered accordingly. The program code is
given below:
230 Chapter 10 Serial Communication
#include <c8051f020.h>
//--------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//--------------------------------------------------------------
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
//--------------------------------------------------------------
// Global CONSTANTS
//--------------------------------------------------------------
#define BLINKCLK 2000000
void Init_Clock(void)
{
OSCXCN = 0x67; //-- 0110 0111b
//-- External Osc Freq Control Bits (XFCN2-0) set to 111
// because crystal frequency > 6.7 MHz
//-- Crystal Oscillator Mode (XOSCMD2-0) set to 110
//--------------------------------------------------------------
void Init_UART0(void)
{
//-- set up Timer 1 to generate the baude rate (115200)
// for UART0
CKCON |= 0x10; //-- T1M=1; Timer 1 uses the system clock
// 22.11845 MHz
TMOD = 0x20; //-- Timer 1 in Mode 2 (8-bit auto-
// reload)
TH1 = 0xF4; //-- Baud rate = 115200
TR1 = 1; //-- start Timer 1 (TCON.6 = 1)
T2CON &= 0xCF; //-- Timer 1 overflows used for receive &
// transmit clock (RCLK0=0, TCLK0=0)
//-- Set up the UART0
PCON |= 0x80; //-- SMOD0=1 (UART0 baud rate divide-by-2
// disabled)
SCON0 = 0x50; //-- UART0 Mode 1, Logic level of stop
// bit ignored and Receive enabled
//--------------------------------------------------------------
//-- Configure Timer3 to auto-reload and generate an interrupt
// at interval specified by <counts> using SYSCLK/12 as its
// time base.
//-- This routine changes the state of the LED whenever Timer3
// overflows.
void Timer3_ISR (void) interrupt 14
{
TMR3CN &= ~(0x80); //-- clear TF3
LED_count++;
if ( (LED_count % 10) == 0) //-- do every 10th count
{
LED = ~LED; //-- change state of LED
LED_count = 0;
}
}
//--------------------------------------------------------------
void UART0_ISR(void) interrupt 4
{
//-- pending flags RI0 (SCON0.0) and TI0(SCON0.1)
if ( RI0 == 1) //-- interrupt caused by received byte
{
received_byte = SBUF0; //-- read the input buffer
RI0 = 0; //-- clear the flag
new_cmd_received=1;
}
}
//--------------------------------------------------------------
void main(void)
{
blink_speed = 10; received_byte = 2;
new_cmd_received = 0; LED_count = 0; LED = 0;
EA = 0; //-- disable global interrupts
WDTCN = 0xDE; //-- disable watchdog timer
WDTCN = 0xAD;
Init_Clock(); Init_Port();
Init_Timer3(BLINKCLK/12/blink_speed); Init_UART0();
EA = 1; //-- enable global interrupts
while(1) //-- go on forever
{
if (new_cmd_received == 1)
{
switch (received_byte)
{
case 1 : blink_speed = 1; break; // slow
case 2 : blink_speed = 10; break; // medium
case 3 : blink_speed = 50; break; // fast
default : blink_speed = 10; break;
}
EA = 0;
Init_Timer3(BLINKCLK/12/blink_speed);
EA = 1; //-- enable interrupts
new_cmd_received = 0;
}
}
}
Chapter 10 Serial Communication 233
11.0 Introduction
Interrupt Handler
Each interrupt source can be individually enabled or disabled through the
use of associated interrupt enable bit in the SFRs IE, EIE1 and EIE2
(Tables 11.2, 11.4, and 11.5). However one must set the global
enable/disable bit, EA (IE.7), to logic 1 before any individual interrupt is
enabled. If the EA bit is ‘0’, none of the interrupt sources will be
recognized by the CPU regardless of their interrupt enable settings.
Chapter 11 Interrupts 237
Example:
If interrupts are enabled and the interrupt pending (status) flag remains
set after the CPU completes the RETI instruction, a new interrupt request
will be generated immediately and the CPU will re-enter the ISR after the
completion of the next instruction.
If interrupts are disabled, the interrupt-pending flag is ignored by the
hardware and program execution continues as normal.
Interrupt
Interrupt
Pending
Control
Priority
Priority
Source
Enable
Vector
Order
Flag
Flag
Always
Reset 0000 Top None Always Enabled
Highest
External
Interrupt 0 0003 0 IE0 (TCON.1) EX0 (IE.0) PX0 (IP.0)
(/INT0)
Timer 0
000B 1 TF0 (TCON.5) ET0 (IE.1) PT0 (IP.1)
Overflow
External
Interrupt 1 0013 2 IE1 (TCON.3) EX1 (IE.2) PX1 (IP.2)
(/INT1)
Timer 1
001B 3 TF1 (TCON.7) ET1 (IE.3) PT1 (IP.3)
Overflow
RI0 (SCON0.0)
UART0 0023 4 ES0 (IE.4) PS0 (IP.4)
TI0 (SCON0.1)
Timer 2
002B 5 TF2 (T2CON.7) ET2 (IE.5) PT2 (IP.5)
Overflow
Serial
PSPI0
Peripheral 0033 6 SPIF (SPI0CN.7) ESPI0 (EIE1.0)
(EIP1.0)
Interface
SMBus ESMB0 PSMB0
003B 7 SI (SMB0CN.3)
Interface (EIE1.1) (EIP1.1)
ADC0 Window AD0WINT EWADC0 PWADC0
0043 8
Comparator (ADC0CN.2) (EIE1.2) (EIP1.2)
CF (PCA0CN.7)
Programmable PPCA0
004B 9 CCFn EPCA0 (EIE1.3)
Counter Array (EIP1.3)
(PCA0CN.n)
Comparator 0 CP0FIF PCP0F
0053 10 ECP0F (EIE1.4)
Falling Edge (CPT0CN.4) (EIP1.2)
Comparator 0 CP0RIF ECP0R PCP0R
005B 11
Rising Edge (CPT0CN.5) (EIE1.5) (EIP1.5)
Comparator 1 CP1FIF PCP1F
0063 12 ECP1F (EIE1.6)
Falling Edge (CPT1CN.4) (EIP1.6)
Comparator 1 CP1RIF ECP1R PCP1F
006B 13
Rising Edge (CPT1CN.5) (EIE1.7) (EIP1.7)
Timer 3
0073 14 TF3 (TMR3CN.7) ET3 (EIE2.0) PT3 (EIP2.0)
Overflow
ADC0 End of AD0INT EADC0 PADC0
007B 15
Conversion (ADC0CN.5) (EIE2.1) (EIP2.1)
Timer 4
0083 16 TF4 (T4CON.7) ET4 (EIE2.2) PT4 (EIP2.2)
Overflow
ADC1 End of AD1INT EADC1 PADC1
008B 17
Conversion (ADC1CN.5) (EIE2.3) (EIP2.3)
External
0093 18 IE6 (PRT3IF.5) EX6 (EIE2.4) PX6 (EIP2.4)
Interrupt 6
External
009B 19 IE7 (PRT3IF.6) EX7 (EIE2.5) PX7 (EIP2.5)
Interrupt 7
RI1 (SCON1.0)
UART1 00A3 20 ES1 (EIE2.6) PS1 (EIP2.6)
TI1 (SCON1.1)
External
XTLVLD PXVLD
Crystal OSC 00AB 21 EXVLD (EIE2.7)
(OSCXCN.7) (EIP2.7)
Ready
The execution of ISR proceeds until the RETI (Return from Interrupt)
instruction is encountered. The RETI instruction informs the CPU that the
interrupt subroutine has finished. The top two bytes from the stack are
then popped and loaded into the Program Counter (PC). The CPU will
continue executing the instruction from this PC address, which is the
place where the execution of the main program was left off in order to
invoke the ISR. Some interrupt pending flags are automatically cleared
by the hardware when the CPU vectors to the ISR. This has an
advantage of preventing a further interrupt within an interrupt. However,
if the interrupt flag is not cleared by the hardware, then it is the
programmer’s responsibility to clear it, using some software means, upon
entering the ISR. If an interrupt pending flag remains set after the CPU
completes the RETI instruction, a new interrupt request will be generated
immediately and the CPU will re-enter the ISR after the completion of the
next instruction.
Example:
CSEG AT 0
LJMP MAIN
TIMER4INT: .
. ; Timer 4 ISR Code
.
RETI ; Return to main program
must then deactivate the interrupt request before execution of the ISR
completes otherwise another interrupt request will be generated.
The other 2 external interrupts (External Interrupts 6 & 7) are edge-
sensitive inputs and can be configured to trigger on a positive or negative
edge. The interrupt-pending flags and configuration bits for these
interrupts are in the Port 3 Interrupt Flag Register (Table 11.8).
EMBEDDED
PROGRAMMING
as a Software Engineer in Philips India in the Consumer Electronics division, he
joined Singapore Polytechnic in 1989 where he is currently a Senior Lecturer in the
School of Electrical and Electronic Engineering. Since September 2002 he is a
Visiting Senior Lecturer at the Institute of Information Sciences and Technology,
Massey University, New Zealand, and is working towards his Ph.D. in Intelligent
Control of Multi-Agent Collaborative Systems.
His current research interests are in the area of Embedded Systems, Robotics,
Real-time Vision Processing, Behavior Programming for Multi-Agent Collaboration,
and Automated Testing & Measurement Systems. He has published and present-
ed over 30 research papers in various conferences and journals. He is a member
with Field-Programmable
of IEEE.
Mixed-Signal µControllers
Ms. Moi Tin Chew got her B.Sc. (Honors) in Electrical & Electronic Engineering
from North East London Polytechnic (UK) in 1981 and M.Sc. in Information
Engineering from the City University, London (UK) in 1991. She has over twenty
years of teaching and research experience in various institutions of higher learn-
ing in different countries. From 2004 she is with Monash University (Malaysia
Campus). Her teaching and research interests include Computer and
Microprocessor Applications, Microprocessor Interfacing Techniques, Digital &
Analogue Electronics, Logic Design, and Electrical Engineering. She has super-
vised a large number of research and development projects for the industry and
academia. She is an author of several publications and research presentations
at conferences.
Ms. Moi Tin Chew is a registered Chartered Engineer (UK) and a member of the
Institution of Electrical Engineers (UK).
© 2005