+ All Categories
Home > Documents > A Microprocessor Laboratory Using the ADuC841

A Microprocessor Laboratory Using the ADuC841

Date post: 10-Dec-2016
Category:
Upload: vandieu
View: 240 times
Download: 2 times
Share this document with a friend
136
A Microprocessor Laboratory Using the ADuC841 Shlomo Engelberg 1 December 13, 2010 1 Copyright c 2002-2009 by Shlomo Engelberg
Transcript

A Microprocessor Laboratory Using theADuC841

Shlomo Engelberg1

December 13, 2010

1Copyright c©2002-2009 by Shlomo Engelberg

2

Contents

1 The ADuC841 Microprocessor 11

2 The Microprocessor 13

2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.2 The Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.3 The Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.4 Machine Language and Assembly Language . . . . . . . . . . 15

2.5 The Memory—A Programmer’s Perspective . . . . . . . . . . 16

2.5.1 Internal Data Memory . . . . . . . . . . . . . . . . . . 16

2.5.2 Program Memory . . . . . . . . . . . . . . . . . . . . . 17

2.5.3 External Data Memory . . . . . . . . . . . . . . . . . . 17

2.5.4 Bit Addressable Memory . . . . . . . . . . . . . . . . . 17

2.6 Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.7 Logical Operations . . . . . . . . . . . . . . . . . . . . . . . . 19

2.8 Bitwise Operations . . . . . . . . . . . . . . . . . . . . . . . . 19

2.9 Flow Control . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

3 The Assembler 23

3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.2 The Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.3 The Assembler as Translator . . . . . . . . . . . . . . . . . . . 24

3.4 Telling the Assembler Where it is . . . . . . . . . . . . . . . . 25

3.5 Header Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3.6 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

3.7 The Last Directive . . . . . . . . . . . . . . . . . . . . . . . . 28

3.8 Running the Compiler . . . . . . . . . . . . . . . . . . . . . . 28

3.9 Downloading the Program . . . . . . . . . . . . . . . . . . . . 28

3.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

3

4 CONTENTS

4 Interrupts 314.1 An Introduction to Interrupts . . . . . . . . . . . . . . . . . . 314.2 The Interrupts—in Brief . . . . . . . . . . . . . . . . . . . . . 324.3 Why We Use Interrupts . . . . . . . . . . . . . . . . . . . . . 334.4 Enabling Interrupts . . . . . . . . . . . . . . . . . . . . . . . . 344.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

5 A Philosophical View of the Special Function Registers 355.1 Two Types of SFRs . . . . . . . . . . . . . . . . . . . . . . . . 355.2 Bit Addressable SFRs . . . . . . . . . . . . . . . . . . . . . . 355.3 An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

6 An Introduction to Reusable Code 37

7 An Introduction to the ADuC841 397.1 A General Introduction . . . . . . . . . . . . . . . . . . . . . . 39

7.1.1 The Assembler . . . . . . . . . . . . . . . . . . . . . . 407.1.2 Some Important Commands . . . . . . . . . . . . . . . 407.1.3 Looping . . . . . . . . . . . . . . . . . . . . . . . . . . 41

7.2 Introduction to µVision3 . . . . . . . . . . . . . . . . . . . . . 417.3 Compiling and Downloading a Program . . . . . . . . . . . . . 427.4 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 43

7.4.1 Part I . . . . . . . . . . . . . . . . . . . . . . . . . . . 437.4.2 Part II . . . . . . . . . . . . . . . . . . . . . . . . . . . 437.4.3 Part III . . . . . . . . . . . . . . . . . . . . . . . . . . 437.4.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . 43

7.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

8 The Hardware Stack 478.1 When and Why the Stack is Used . . . . . . . . . . . . . . . . 478.2 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

9 Interrupts 499.1 A General Introduction . . . . . . . . . . . . . . . . . . . . . . 49

9.1.1 Enabling Interrupts . . . . . . . . . . . . . . . . . . . . 499.1.2 Some Facts about the External Interrupt Pins . . . . . 50

9.2 Bounce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 50

9.3.1 Part I . . . . . . . . . . . . . . . . . . . . . . . . . . . 509.3.2 PartII . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

CONTENTS 5

9.3.3 The Report . . . . . . . . . . . . . . . . . . . . . . . . 519.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

10 The Timer Interrupts 5310.1 A General Introduction . . . . . . . . . . . . . . . . . . . . . . 5310.2 Controlling the Timer . . . . . . . . . . . . . . . . . . . . . . 54

10.2.1 The TMOD SFR . . . . . . . . . . . . . . . . . . . . . 5410.2.2 The TCON SFR . . . . . . . . . . . . . . . . . . . . . 5410.2.3 The Timer as an Interrupt . . . . . . . . . . . . . . . . 55

10.3 How to Set-up the Timer/Counters . . . . . . . . . . . . . . . 5510.4 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 5610.5 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5610.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

11 The Integrated Development Environment (IDE) 5711.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5711.2 Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5711.3 Writing the Assembly Language File . . . . . . . . . . . . . . 5811.4 Debugging the Program . . . . . . . . . . . . . . . . . . . . . 5911.5 An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5911.6 Other Helpful Features . . . . . . . . . . . . . . . . . . . . . . 60

11.6.1 Running the Program in the Debugger . . . . . . . . . 6011.6.2 Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . 6011.6.3 Peripherals . . . . . . . . . . . . . . . . . . . . . . . . 6011.6.4 Watchlists . . . . . . . . . . . . . . . . . . . . . . . . . 6011.6.5 The Logic Analyzer Window . . . . . . . . . . . . . . . 61

11.7 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 6111.8 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6111.9 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

12 Using the Onboard UART 6312.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 6312.2 The Onboard UART . . . . . . . . . . . . . . . . . . . . . . . 6412.3 Writing a String to the UART . . . . . . . . . . . . . . . . . . 6512.4 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 6512.5 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6612.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

13 Using the Onboard UART—Printing a Preprogrammed String 6713.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 6713.2 The New Commands and Techniques . . . . . . . . . . . . . . 67

6 CONTENTS

13.2.1 Reading from the Code Segment . . . . . . . . . . . . . 6713.2.2 Some Assembler Directives . . . . . . . . . . . . . . . . 6813.2.3 Writing a String to the Serial Port . . . . . . . . . . . 6913.2.4 Forcing an Interrupt . . . . . . . . . . . . . . . . . . . 69

13.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 6913.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7013.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

14 Timer 3 7114.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7114.2 Using Timer 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . 7114.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 7214.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

15 Using the Parallel Ports 7315.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 7315.2 How the Parallel Ports Operate . . . . . . . . . . . . . . . . . 73

15.2.1 The Connection between the Registers and the Pins . . 7315.2.2 Parallel Ports 0, 2, and 3 as Outputs . . . . . . . . . . 7315.2.3 The Registers P0, P2, and P3 . . . . . . . . . . . . . . . 7515.2.4 Ports 0, 2, and 3 as Inputs . . . . . . . . . . . . . . . . 7515.2.5 Port 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 7615.2.6 Alternate Functions . . . . . . . . . . . . . . . . . . . . 7615.2.7 Using the Ports . . . . . . . . . . . . . . . . . . . . . . 76

15.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 7715.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7715.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

16 A Serial Port Controlled Clock 7916.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 7916.2 Timer 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

16.2.1 T2CON . . . . . . . . . . . . . . . . . . . . . . . . . . . 7916.2.2 Printing a Variable String . . . . . . . . . . . . . . . . 8016.2.3 More about Interrupts . . . . . . . . . . . . . . . . . . 80

16.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 8116.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8116.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

17 A Counter 8317.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 8317.2 Using a Timer/Counter as a Counter . . . . . . . . . . . . . . 83

CONTENTS 7

17.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 83

17.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

17.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

18 Interfacing a Keypad 85

18.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 85

18.2 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 85

18.3 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

18.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

19 Digital to Analog Converters 89

19.1 A General Introduction . . . . . . . . . . . . . . . . . . . . . . 89

19.2 The Underlying Theory . . . . . . . . . . . . . . . . . . . . . . 90

19.3 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 91

19.4 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 91

19.5 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

19.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

20 Using the Onboard DAC 93

20.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 93

20.2 Controlling the DAC . . . . . . . . . . . . . . . . . . . . . . . 94

20.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 95

20.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

20.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

21 Analog to Digital Converters 97

21.1 A General Introduction . . . . . . . . . . . . . . . . . . . . . . 97

21.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 98

21.2.1 ADCCON1 . . . . . . . . . . . . . . . . . . . . . . . . . . 99

21.2.2 ADCCON2 . . . . . . . . . . . . . . . . . . . . . . . . . . 99

21.2.3 ADCCON3 . . . . . . . . . . . . . . . . . . . . . . . . . . 100

21.2.4 ADCDATA . . . . . . . . . . . . . . . . . . . . . . . . . . 100

21.2.5 The A/D Interrupt . . . . . . . . . . . . . . . . . . . . 100

21.2.6 The Inputs . . . . . . . . . . . . . . . . . . . . . . . . 100

21.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 101

21.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

21.5 A Second Experiment . . . . . . . . . . . . . . . . . . . . . . . 102

21.6 The Second Report . . . . . . . . . . . . . . . . . . . . . . . . 102

21.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

8 CONTENTS

22 Designing a Low-pass Filter 105

22.1 A General Introduction . . . . . . . . . . . . . . . . . . . . . . 105

22.2 Stability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

22.3 Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

22.3.1 The Analog Filter . . . . . . . . . . . . . . . . . . . . . 106

22.3.2 The Digital Filter . . . . . . . . . . . . . . . . . . . . . 107

22.4 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 108

22.5 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

22.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

23 Implementing a Simple Oscilloscope 109

23.1 A General Introduction . . . . . . . . . . . . . . . . . . . . . . 109

23.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 109

23.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 110

23.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

23.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

24 Implementing a Simple Capacitance Meter 113

24.1 A General Introduction . . . . . . . . . . . . . . . . . . . . . . 113

24.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 114

24.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 114

24.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

24.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

25 Generating PN Sequences 115

25.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

25.2 Some Facts about PN Sequences . . . . . . . . . . . . . . . . . 115

25.2.1 Length . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

25.2.2 Ones and Zeros . . . . . . . . . . . . . . . . . . . . . . 116

25.2.3 The Autocorrelation . . . . . . . . . . . . . . . . . . . 116

25.3 Implementation Hints . . . . . . . . . . . . . . . . . . . . . . . 116

25.3.1 Shift Registers . . . . . . . . . . . . . . . . . . . . . . . 116

25.3.2 Logical Operations . . . . . . . . . . . . . . . . . . . . 116

25.4 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 117

25.5 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

25.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

26 A Simple Switching Circuit 119

26.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

26.2 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 119

CONTENTS 9

27 Making a Simple Plotter 12327.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12327.2 The Main Idea . . . . . . . . . . . . . . . . . . . . . . . . . . 12327.3 An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12427.4 Implementing the Plotter . . . . . . . . . . . . . . . . . . . . . 125

27.4.1 Storing the Values to Be Plotted . . . . . . . . . . . . 12527.4.2 Plotting the Points . . . . . . . . . . . . . . . . . . . . 125

27.5 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 126

28 Building and Testing a Dynamic Logic Inverter 12728.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12728.2 A Brief Explanation of the Circuit . . . . . . . . . . . . . . . . 12728.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 128

29 Power Management 13129.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13129.2 Power Management in the ADuC841 . . . . . . . . . . . . . . 13229.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 133

30 Reading List 13530.1 Datasheets and Manuals Referred to . . . . . . . . . . . . . . 13530.2 8051 Related Information . . . . . . . . . . . . . . . . . . . . 135

10 CONTENTS

Chapter 1

The ADuC841 Microprocessor

The ADuC841 is essentially an 8052 microprocessor with a host of additionalperipherals added. (A website about the 8052 that you may find useful andinteresting is www.8052.com.)

An 8052 has the following features:

• 256 bytes of internal data memory.

• Special function registers mapped into the top 128 bytes of the internaldata memory.

• 3 timer/counters.

• Several I/O ports.

• 1 Universal Asynchronous Receiver Transmitter (UART) that is ableto communicate using one of the protocols a computer uses.

In this course we will see how all of these peripherals are used.The 8052’s memory is organized into five areas:

• The Code section (Either internal or external—depending on the EApin).

• The internal Data section.

• The bitwise addressable section.

• The external Data section.

• The special function registers.

11

12 CHAPTER 1. THE ADUC841 MICROPROCESSOR

Each of the first four types of memory is accessed using somewhat differentinstructions, and based on the instruction given the processor may access thememory in a physically different fashion. (Access to external memory, forexample, involves changing the voltages on some of the pins that leave theprocessor. Access to internal memory does not involve such changes.) Thefifth type of memory is memory mapped to the a subset of the internal datasection—of the second type of memory.

The ADuC841 has several peripherals that the 8052 does not have. Thetwo most notable additions are an eight channel A/D and two channels ofD/A. It has several other peripherals as well:

• 2048 bytes (2 KB) of on-chip external memory.

• An addition timer that can be used to set the Baud rate of the UART.

• 62 Kbytes of internal FLASH/EE program memory that can be pro-grammed via the ADuC841’s serial port.

• A watchdog timer.

• 4 KBytes of FLASH/EE memory.

In this course, we will not be dealing with a simple ADuC841—we willan evaluation kit for the ADuC841. This kit gives us several features thatthe chip itself does not have. For example, the cable supplied with the kithas a level shifter that takes the output of the on-chip UART and shifts itfrom the chip’s levels of 0 V and 5 V to the RS232 levels—±12 V.

Chapter 2

The Microprocessor

2.1 Overview

Like all members of the 8051 family, the ADuC841’s core can be thought of asbeing composed of several different regions of memory and various processingunits. See Figure 2.1 for a simple schematic of the ADuC841.

2.2 The Registers

The ADuC841, like all the processors in the 8051 family, has four banks ofregisters each of which contains eight 8-bit registers. At any given time, onlyone register bank is active. The registers in the active bank are referred to asR0 through R7. Many commands are designed to work most efficiently withthese registers. At startup, the first bank of registers is active and the stackpointer points to the beginning of the second bank of registers.

The single most important register is probably the accumulator—whosemnemonic is ACC. The accumulator is used in most arithmetic calculationsand in many other places. As we will see, many commands work best withthe accumulator, and other commands only work with the accumulator.

2.3 The Memory

As mentioned previously, the ADuC841 has several types of memory. Unlikethe “standard” Von Neumann architecture in which the program and datamemory are contained in the same physical block of memory, the ADuC841has separate data and program memories. In fact, the data and program

13

14 CHAPTER 2. THE MICROPROCESSOR

Figure 2.1: A Schematic Description of the ADuC841

memories can be further divided into internal data memory, external datamemory, internal program memory, and external program memory.

As with all computers there are a variety of ways in which memory canbe accessed. The simplest way of addressing a location in memory is to tellthe computer that you would like to access a particular location and to tell itwhat location. This is called direct addressing. The command MOV moves orcopies a byte of data from one place to another. If one issues the commandMOV 40H, 50H this causes the contents of memory location 50H to be copiedinto location 40H of the internal data memory.

As mentioned previously, the ADuC841 has four banks of registers eachof which have 8 registers. The register banks are located in the data memoryfrom locations 00H to 1FH. (I.e. the registers are “memory mapped” to thelocations 00H - 1FH, and each byte contains one register.)

A second way of accessing data memory is indirectly. To indirectly addressa byte one stores the location of the byte which one would like to access inone of registers R0 or R1. Then one refers to the location using the at sign,@. For example to move the contents of the location whose address is stored

2.4. MACHINE LANGUAGE AND ASSEMBLY LANGUAGE 15

in R0 to location 40H, one writes MOV 40H, @R0.The internal data memory has two more subdivisions that are of interest

to us. Several of the locations in the internal data memory are bit address-able. We will see that there are a whole suite of commands that allow us tomanipulate bits with ease. Additionally the internal data memory from 80Hto FFH is devoted to the special function registers (SFRs). All accesses tothese registers must be made directly. In order to make it possible to have256 bytes of actual internal (general purpose) memory, indirect accesses tomemory from 80H to FFH refer to a (physically different) set of memoriesthat sit at that location. This memory is meant for general use and is in noway connected to the SFRs.

2.4 Machine Language and Assembly Language

The ADuC841 does not really understand commands of the form MOV 40H,

50H. Commands in this form are written in a language—called assembly lan-guage that is one level above the machine’s own language—called machinelanguage. The reason that assembly language is used is that in machine lan-guage there are many very similar commands that assembly language bundlesinto a single command. We consider the MOV command as a typical—andvery important—example.

Let us start with the command MOV A, Rn. This command causes thecontents of the register Rn to be moved to the accumulator, A. This commandis stored in the program memory as the number 11101rrr where the finalthree bits are the number of the register in binary. Thus, MOV A, R0 isstored as 11101000. A point worth noting is that in the machine languagecommand, the fact that the byte is being moved into the accumulator ispart of the instruction. (This is why A is used to represent the accumulatorand not ACC. We do not actually tell the processor that we want to moveinformation into the accumulator. The command that we give means “moveinformation from general purpose register rrr to the accumulator.”)

If one would like to move data from the accumulator to one of the generalpurpose registers, then one writes MOV Rn, A. This mnemonic is easy tounderstand. The machine language code that corresponds to this instructionis 11111rrr. This does not look too similar to the previous example, thoughits meaning is quite similar.

Now let us try something more interesting. Consider the command MOV

direct, direct where direct means some particular location in the inter-nal data memory. This instruction is coded as:

10000101 direct address of the source direct address of the destination

16 CHAPTER 2. THE MICROPROCESSOR

Note that this instruction requires three bytes of storage in the programmemory. Also, note that this instruction requires 3 cycles to execute. (Thetwo preceding examples required only one byte of storage and one cycle toexecute.)

Once again, the machine code is very different from the assembly languagemnemonic, and even many people who like to work with low-level constructsgenerally prefer assembly language to machine code. To get all the informa-tion you want about the commands—any of the 8051’s commands—see the“8051 Family Programmer’s Guide and Instruction Set” (“The Programmer’sGuide”).

2.5 The Memory—A Programmer’s Perspec-

tive

2.5.1 Internal Data Memory

The ADuC841 (and all of the 8051 family processors) has several classesof commands for using memory. The most important commands for theprogrammer are those that deal with internal data memory. These commandsare also the commands whose names—whose mnemonics—are as simple aspossible. As we have already seen, the command for moving internal datamemory is just MOV. There are many possible “moves” one might want toperform, and the 8051 allows almost all of them. In fact, the MOV commandis the most versatile command in the 8051’s lexicon.

We have already seen how to move data from the accumulator to a generalpurpose register; from a register to the accumulator; from one address toanother; and from an indirectly addressed location to a direct location—to aspecific address. Another important variant is moving a given constant valueto a location in memory. Suppose that one would like to move 50 hex intolocation 40 hex. Then one writes MOV 40H, #050H. The hash mark causes thecompiler to tell the processor to move the value to a particular location. Oneof the simplest ways to write a program that looks fine and is syntacticallycorrect is to type MOV 40H, 50H when one meant to type MOV 40H, #050H.Both commands are legal; the first moves the value stored in location 50 hexto location 40 hex; the second moves the value 50 hex into location 40 hex.There is a big difference between the semantic content of the commands;syntactically they are almost identical. Most MOVs that one might considerare legal. Some, however, are not. For example if one uses MOV R0, R1, onewill find that the compiler will not recognize the command. For a completedescription of the MOV command see “The Programmer’s Guide.”

2.5. THE MEMORY—A PROGRAMMER’S PERSPECTIVE 17

2.5.2 Program Memory

Program memory in the ADuC841 is fully internal. There are two commands—and two commands only—for fetching data from the program memory. Onecan use either the command MOVC A, @A+DPTR or MOVC A, @A + PC. Thefirst command reads the value stored in the program memory at the loca-tion given by the sum of the current value of the 16 bit register DPTR andthe current value of the accumulator and moves this value to the accumu-lator (overwriting its current contents). The second instruction does thesame thing, but uses the PC—the program counter—rather than the DPTR

register. These commands are used to read values in fixed tables—as thevalues stored in the program memory cannot be changed while a programis executing. The fact that the values read are fixed is emphasized by themnemonic MOVC which, according to the “80C51 Family Architecture,” standsfor “MOVe Constant.”

2.5.3 External Data Memory

In addition to the 256+128 bytes of RAM that all 8052s have, the ADuC841has an additional 2K of RAM that is “internally wired” as external RAM.To access this memory, one makes use of the MOVX commands. For moreinformation on these commands, please see the “The Programmer’s Guide.”

2.5.4 Bit Addressable Memory

In addition to regular data memory, certain parts of the data memory are bitaddressable. That means that one can refer to a specific bit in the memoryrather than having to refer to a whole byte. One can write to one bit, readfrom one bit, and perform operations on one bit. This makes it easy toimplement flags without wasting an entire byte for a job that a bit can dobetter.

The bit addressable locations in the regular data memory are all the bitsin the bytes from 20H to 2FH. Additionally any special function registerwhose address (in hex) ends in 0 or 8 is also bit addressable. The SFRs thatare bit addressable are those for which every bit is very important. Often,each bit will control some feature of a peripheral.

The command to set a bit (to one) is SETB bit and the command toclear a bit (to zero) is CLR bit. In addition, there are a large number ofcommands that test a bit and then jump. For example JB bit, rel jumpsif bit is set (to one). For more information on these commands see the “8051Programmer’s Guide.”

18 CHAPTER 2. THE MICROPROCESSOR

2.6 Arithmetic

When performing arithmetic using the ADuC841 (or any other member of8051 family) frequently one must use the accumulator. For example, thereare many ways to add two numbers—and all of them require the use of theaccumulator. Similarly the commands that perform subtraction always havethe accumulator as one of the operands. Many of the logical commands alsowork best with the accumulator. The accumulator is the most importantregister of which the ADuC841 is possessed.

To add two numbers, one uses the ADD command. Suppose that onewould like to add the contents of memory location 40H and 50H. Becausethe ADuC841 does not support addition between two locations in memory,one must first move one of the values to the accumulator and then performthe addition. One way to do this is as follows:

MOV A, 40H

ADD A, 50H

The ADD command always leaves the sum in the accumulator.

Note that when using the add command, if the sum is more than canbe contained in a single byte, then what can be contained there is storedin the accumulator and the carry bit—a special bit—is set as well. Thus,checking the carry bit after an addition tells one whether or not the addition“overflowed.” (The carry bit is the first bit in the program status word—which is one of the SFRs.)

If one needs to perform multiple-byte addition, then one uses the ADD

command for the first byte and the ADDC command for all the rest. The ADDCcommand works just like to ADD command, but it also adds an extra one ifthe carry bit was set.

In addition to an ADD command there is also a SUBB command. See the“8051 Programmer’s Guide for more information on subtraction.

Because one is often interested in counting events, adding one to a valueor subtracting one from a value is a very common operation. For this reasonthe ADuC841 (and all of the 8051 family of processors) has special commandsfor incrementing and decrementing values. To increment a value one uses thecommand INC and to decrement one uses DEC. These commands work on theaccumulator, on the general purpose registers, on locations in memory, or onindirectly accessed locations in memory.

In addition to addition and subtraction, there are also commands thatperform multiplication and division. These commands can be useful whenone would like to shift a byte several bits.

2.7. LOGICAL OPERATIONS 19

2.7 Logical Operations

In addition to the arithmetic operations, there are also a nice set of logicaloperations. These operations allow one to or two bytes with one another,to and two bytes with one another, to exclusive or (xor) two bytes with oneanother, and to rotate bytes.

The rotate commands are particularly interesting. There are four typesof command. RL rotates the accumulator one bit to the left; that is the nth

bit is moved into the (n+ 1)th bit. The last bit of the accumulator is rotatedinto its first bit. The accumulator is treated like a “circular register” whosefirst bit follows its last bit. RR is similar, except that every bit moves one bitto the right and the first bit is rotated into the last bit.

There is also a command called RLC which rotates left through the carrybit. This command treats the accumulator with the carry as one nine bitregister. The carry bit is treated as the lowest order bit. Thus, the valueof the the carry bit is fed into the lowest order bit of the accumulator, andthe value of the highest order bit is fed into the carry bit. If one needs toshift a string of bytes—say in a 32 bit number—this command can be veryuseful. The command RRC works similarly but shifts the bits in the oppositedirection.

2.8 Bitwise Operations

As mentioned previously, there are commands that set and clear bits. It isalso possible to and bits, to or bits, to move bits, and to complement bits.When dealing with bits, the carry bit has a role similar to the role that theaccumulator has for bytes. Many operations must involve the carry bit. Forexample, when anding two bits, one of the bits must be the carry bit. Thereare two forms of the and command. One has ANL C, bit which means thatone must and the carry bit with a specific other bit, and one has ANL C,

/bit which means that one must and the carry bit with the complement ofa specific other bit. Note that in these commands the C is really part ofthe command. The machine language code for the command includes theinformation that one of the bits being anded is the carry bit. Also, the factthat the bit being anded with the carry is to be (or not to be) complementedis part of the machine language instruction. Finally, another way in whichthe carry bit here is similar to the accumulator in byte-wise operations isthat the result of the calculation is stored in the carry bit.

In addition to commands that manipulate bits, there are several com-mands that cause the processor to jump to a new location based on the

20 CHAPTER 2. THE MICROPROCESSOR

status of a particular bit. For example, the command JC causes the proces-sor to jump to a new location if the carry bit is set. The mnemonic is short for“jump if carry set,” Similarly, there is a command referred to as JNC whichcauses the processor to “jump if carry not set.” There are also commandsthat cause the processor to jump based on the status of a particular bit.

2.9 Flow Control

The last major set of commands concern themselves with controlling programflow. The most frequently used flow control command is probably JMP. Whatis interesting about this command is that it has no direct translation intomachine language. The assembler (about which we will learn more shortly)translates the JMP command into either LJMP, AJMP or SJMP. Each of thesecommands causes the program to jump to a new location. The way thelocation is stored—and the distance it can be from the current location—differs from command to command.

As with most programming languages, there is also a command to CALLa subroutine. The programmer generally writes CALL, and the assemblertranslates this command into either ACALL or LCALL. At the end of a sub-routine, one must return to the calling program. This is done using the RET

command.

The next instruction of interest is DJNZ. This mnemonic stands for “decre-ment and jump if not zero.” It is useful when one would like to implementa loop. Suppose that one would like to pass through a loop ten times. Oneway to do this is to use 40H as a counter. One then uses DJNZ to count thenumber of passes through the loop. Consider the following code:

MOV 40H, #10; Move the number 10 into location 40H.

LOOP: The body of the loop

goes here.

DJNZ 40H, LOOP

This loop uses 40H as a counter. Recall that the hash mark (#) that precedesthe number 10 tells the compiler that we want to move the actual numberinto the memory location.

In addition to commands to jump, call, and decrement and jump if notzero, there are several other conditional jump commands. One has CJNE

which compares two values and jumps to a location if they are not equal.One also has JZ which jumps if the accumulator is zero and JNZ which jumpsif the accumulator is not equal to zero.

2.10. EXERCISES 21

2.10 Exercises

1. Use the ADD and ADDC commands to write a routine that will add twosixteen bit numbers. Assume that the first word to add is stored in40H and 41H (with 40H the low-order word) and that the second wordis stored in 42H and 43H (with 42H the low-order word).

2. Suppose that one has a 32 bit number stored in the four bytes 40H,41H, 42H, and 43H. Let 40H contain the least significant byte and 43Hcontain the most significant byte. Use the RLC command to develop aset of commands that will shift the entire long word one bit to the left.You may leave the most significant bit of the long word in the carrybit.

3. Why is the following command “unreasonable?”

MOVC @A+DPTR, #10

(Note that the first operand is generally the destination of a movecommand.)

4. What is the difference between the commands CLR C and CLR CY? Inwhat ways are the commands similar? (You may find the “MicroCon-verter Quick Reference Guide” helpful.)

22 CHAPTER 2. THE MICROPROCESSOR

Chapter 3

The Assembler

3.1 Introduction

Computers have a “mother tongue”—their machine language—that is wellsuited to computers. A computer’s machine language is generally a set ofnumbers whose organization is significant to the computer. A determinedhuman being can learn to read and write machine language, but even thoseof us who like working at a “low level” do not usually want, or need, towork at that low a level. The lowest level most of us deal with is assemblylanguage. Assembly language, as we have seen, is still very low level, but itallows us to work in a more pleasant way.

The program that takes assembly language code and converts it into ma-chine language is called an assembler. In this chapter you will be introducedto an assembler for the ADuC841. In general assemblers make our lives easierin a number of ways:

• they translate assembly language commands into machine languagecommands;

• they allow us to give symbolic names to memory locations;

• they allow us to determine where variables and code will be placed ina reasonably clear fashion;

• and they allow us to add comments to our code.

3.2 The Reference

The reference for the assembler is the “8051 Cross Assembler User’s Manual.”It is available in the file ASM51.pdf. It gives much more information about

23

24 CHAPTER 3. THE ASSEMBLER

the assembler than is contained in this introduction.

3.3 The Assembler as Translator

We have discussed many of the commands that the ADuC841 supports. Wehave spent quite a bit of time learning about the commands, and not muchtime understanding how the microprocessor is “fed” the commands. Weremedy that lack now.

Consider the all-important MOV command. This command tells the micro-processor to move information from one place to another. As we have seen,there are many different machine codes that correspond to this command.How do the commands we type get turned into the correct codes?

In assembly language this is usually easy. Let us consider the commandMOV 40H, #50. Because the meaning of each symbol is unambiguous, we canimmediately state that this command is telling the ADuC841 to move thenumber 50 (in decimal because there is no H after the final number) to thelocation 40 hex. Looking on p. 39 of the “8051 Programmer’s Guide,” wefind that in machine code this is:

0111 0101 0100 0000 0011 0010

The first byte is code that means “move fixed data to a particular location,”The second byte is 40H in binary, and the third byte is 50 (decimal) translatedinto binary. It is clear that a simple program could take care of this type oftranslation.

As mentioned in the architecture chapter, there are other tasks that thecompiler performs. The two “meta-commands” JMP and CALL must be trans-lated into the proper “true” instructions. This takes a slightly smarter pro-gram, but is quite doable.

Where the assembler really helps the programmer is in getting rid of theneed to keep track of myriad physical addresses and constant values. Theassembler makes it possible to assign names to memory locations, to locationswithin a program, to constants, and to specific bits. This makes it possibleto make one’s programs much easier to read—a goal that programmers mustalways keep in mind. Another thing that the assembler does is to allow oneto add comments to one’s programs.

Many of the instructions that cause the microprocessor to jump, actu-ally cause the microprocessor to jump x bytes forward (or backward) in theprogram memory. In such commands, the assembler allows one to write aprogram memory location label; the assembler then calculates how far it is

3.4. TELLING THE ASSEMBLER WHERE IT IS 25

to the label and inserts that value in the correct part of the machine code.Let us consider an example of how this works.

Consider the program fragment:

MOV R0, #10

LOOP: DJNZ R0, LOOP

The first line loads general purpose register 0 with 10. The second line startswith LOOP: This set of characters is not translated into machine code at all!The characters tell the compiler to associate the string LOOP with the programmemory location that corresponds to the beginning of the instruction DJNZ

R0, LOOP.Moreover the DJNZ instruction requires two items. The location or register

to be decremented. That is given by R0. The instruction also requires therelative amount to jump. That is not given directly. We have given thecompiler a label. The compiler must take the label and calculate how far tojump. The compiler does this calculation and then places that value in theappropriate location in the program memory.

Here we see a good example of how the compiler saves us effort—we donot need to worry about calculating jumps—and saves us many mistakes—because getting the jump just right is trivial but not always easy.

3.4 Telling the Assembler Where it is

We have seen that there are many different types of memory. The assembler isable to deal with all of them but must be told in which segment of memory itis working. Additionally, it must know where it is located within the segment.

We discuss four of the segments. The most important segment is the codesegment. To tell the assembler that one wants what follows to be placed in thecode segment one gives the assembler the directive CSEG. This directive is nottranslated into machine language at all—it does not tell the microprocessorwhat to do. It is a directive to the assembler that tells the assembler how tointerpret the information that follows the directive. If one does not tell theassembler otherwise, the code segment is the segment to which the assemblerdefaults. If one appends the directive AT to the segment changing directive,one causes the assembler to move to the chosen segment and to start from thegiven location in the segment. If one would like to start from the beginningof the code segment, then one types CSEG AT 0H. To cause the assembler tochange to a given location within the current segment, one uses the directiveORG. Thus, if one is already in the code segment, to change to location 20F,one could type ORG 020FH.

26 CHAPTER 3. THE ASSEMBLER

The other three segments that are of interest to us are the data segment,the external data memory space, and the bit memory space. To switch to thedata segment, one uses the directive DSEG. Because locations 000H-01FH arethe four register banks and locations 20H-2FH are the bitwise addressablememory, one generally does not want to use memory in the region 00H - 2FHfor general purpose storage. Thus, when switching to the data segment, onegenerally uses the directive DSEG AT 030H.

There are several other ways the compiler helps us. Suppose that wewould like to define a counter in data memory. One way is for us to keeptrack of all the locations in data memory and to use the data memory as weplease. An easier way is to let the compiler do the bookkeeping.

Consider the following code segment:

DSEG AT 30H

COUNTER1: DS 1

COUNTER2: DS 1

The first line tells the compiler that the following directives pertain to thedata segment and that the compiler should start placing variables at location30H. The second line says that COUNTER1 is to be assigned to the next locationin the data segment—in this case 30H. The directive DS is always used whenallocating data memory. The 1 says that one byte should be reserved. (Ifone were to type 3, then the next three bytes would be reserved.) The nextline reserves the next byte—at location 31H—for COUNTER2. Note that wewere saved needing to think much about where the bytes would be stored.Once the memory has been reserved, the labels COUNTER1 and COUNTER2 canbe used any place where one needs to refer to internal data memory locations30H and 31H.

To switch to the external data memory space, one uses the XSEG directive.To reserve space in the external segment, one uses the DS directive—just asone does when using the data segment.

The last segment that is of real interest to us is the bit addressable seg-ment. One tells the compiler to switch to that segment by using the BSEG

directive. Within the segment one uses the DBIT directive to reserve bits. Asimple example of how this directive can be used is:

BSEG

FLAG: DBIT 1

This directive reserves one bit for the flag FLAG and assigns the bit’s addressto FLAG.

In a program one can now use FLAG wherever a bit should go, and onecan use COUNTER1 and COUNTER2 wherever a byte address should go. For

3.5. HEADER FILES 27

example, one can say SETB FLAG in order to set the bit to which FLAG refers,and one can now write DJNZ COUNTER1 rather than DJNZ 030H.

3.5 Header Files

When programming the ADuC841, there are many bytes and bits that onemust refer to. All of the special function registers are located at memorylocation 080H-0FFH. Though one could memorize all the various byte andbit locations of interest, this is neither necessary nor desirable. Even if oneknew all of the relevant memory locations, the next person to read yourprogram might not know what the memory location is used for. In order towrite a readable program, it is best to give meaningful names to the locations.There are a set of directives that allow one to name memory locations andbits. However, Analog Devices provides a set of files— similar to C’s headerfiles—which take care of this work for you. The header file for the ADuC841is MOD841. If one is not using any of the peripherals that are special to theADuC841 and one would like to write code that is compatible with 8052,one can use the file MOD52. Both of these files assign names to the commonlyused bits and bytes. By using these files one is writing code that will be moreeasily understood by others who are familiar with the 8051 family and theADuC841.

To cause the compiler to read and interpret a header file, one gives thecompiler the directive $INCLUDE(MOD52) or $INCLUDE(MOD841). Place thedirective at the begining of the program.

Note that in the system that we use, the names of all special functionregisters that exist in the 8051 are predefined. If all of the special functionregisters used in a program exist in the 8051, then there is no need to use aheader file.

3.6 Comments

Another important part of writing readable code is using comments. In ourassembler, comments begin with a semi-colon (;). From the semi-colon untilthe end of the line, all the rest of the text is a comment. These commentsare often what stand between the programmer and totally unreadable code.

It is important to have a “preamble” before the “useful” content of afile appears. The preamble should include the name(s) of the author(s),the date that the file was written, the date(s) on which the file was revised(if any), the hardware for which the code is meant, the file’s name, and a

28 CHAPTER 3. THE ASSEMBLER

short description of the purpose of the code in the file. Additionally anycommand whose purpose would not be clear to an uninitiated reader shouldhave comments added to it until it reaches the point that a person readingthe file will understand the purpose of the code.

3.7 The Last Directive

Every program must end with the END directive. The only thing that isallowed to follow the END directive is a comment on the same line. If oneplaces code or comments on the lines following the END directive, the compilerwill flag this as an error and will not compile the program.

3.8 Running the Compiler

Throughout the semester, we will be using the Keil integrated developmentenvironment (IDE). The IDE is a program that can do many things to helpyou. One of its components is a compiler. To run the compiler, one “builds”the project.

After the IDE has been properly initialized (see §7.2), when the com-piler is run it produces two files. One is the .hex file which has the machinelanguage code in a form suitable for downloading to the ADuC841. The com-piler also outputs a .lst file. This file has both the source code, the machinecode, a list of errors, a list of locations, and a host of other information thatis often useful in debugging. The .lst file can be very useful.

3.9 Downloading the Program

After being properly initialized, the IDE can download programs to theADuC841. Programs are downloaded to the ADuC841 by using its UART.The UART can be used for all sorts of communication, and before download-ing a new program to the ADuC841, the processor must be “told” that themessage that is about to come is a new program. One “tells” the ADuC841that a new program is about to come by holding down the serial downloadbutton on the evaluation board while resseting the ADuC841. After havinginformed the ADuC841 that one is about to download a program, one goesto the FLASH tab in the IDE, and one clicks on download. Assuming thateverything goes well, the program will start running on the ADuC841 almostimmediately.

3.10. EXERCISES 29

The ADuC841 stores programs in non-volatile memory. As we will see,once a program is in memory, it stays there until the memory is erased. Eachtime you turn on the ADuC841 it runs the last program that was stored inits memory.

3.10 Exercises

1. If the .lst file is destroyed, what must one do in order to run the com-piled program? (The answer is very simple.)

2. Suppose that in the data segment one gives the directive ORG 40 andthen one gives the directive ARRAY: DS 5. Precisely what will the in-struction MOV A, ARRAY+1 do?

3. What is wrong with the following code:

LOOP: JMP LOOP; An infinite loop.

END ; The end of the program.

; A short program to demonstrate an infinite loop.

30 CHAPTER 3. THE ASSEMBLER

Chapter 4

Interrupts

4.1 An Introduction to Interrupts

Microprocessors must interface to a variety of peripherals. In the 8051 andsimilar microprocessors this interfacing is often done through interrupts (andthe SFRs). See Figure 4.1 for a schematic description.

One can think of an interrupt as an interruption of the processor’s normalfunctioning. Let us consider the simplest type of interrupt—one that isasserted when the voltage on a particular pin of the microprocessor changesin a particular fashion.

When the voltage on the pin is changed, the microprocessor automaticallyjumps to a fixed location in the program memory and starts executing fromthat location. At the same time, the microprocessor stores the location thatit was at previously so that when it finishes with whatever commands are lo-cated at the fixed position it can return to whatever activity was interrupted.

In the microprocessors in the 8051 family, each of the (many) interruptscauses the microprocessor to jump to a different location. For example,external interrupt zero, which is asserted when pin 2 of port 3 is changed ina particular way, causes the processor to jump to address 3 in the programmemory.

The set of locations to which the processor jumps is called the interruptvector table. When the processor jumps to a location upon the assertion ofan interrupt, the processor is said to “vector” to the location. Thus, uponthe assertion of the external interrupt 0 interrupt the processor vectors tolocation 3 in the program memory. On page 71 of the ADuC841 Data Sheets(contained in the file ADuC841 2 3.pdf) there is copy of the vector table forthe ADuC841. (It is given in Table 39.)

There are eight bytes between each location in the interrupt vector table.

31

32 CHAPTER 4. INTERRUPTS

Figure 4.1: A Schematic Description of the Interaction between the CPU,the SFRs, and the Peripherals in the ADuC841. Note that all of these inter-acations take place inside the chip.

This means that if the entire response to an interrupt requires eight or fewerlocations, then the interrupt subroutine (ISR) can be placed in the vectortable. Otherwise one jumps from the vector table to the actual location ofthe ISR.

Upon reaching the end of the ISR, one must inform the processor toreturn to its “regularly scheduled programming”—that it must go back tonormal operation. This is done by giving the RETI command. (RETI standsfor RETurn from Interrupt.)

4.2 The Interrupts—in Brief

There are many interrupts. Here we give a brief overview of the interrupts.In the following chapters, many of the interrupts are explained in depth.

• External interrupt zero—is tied to the status of pin 2 of port 3.

• Timer zero interrupt.

4.3. WHY WE USE INTERRUPTS 33

• External interrupt one—is tied to the status of pin 3 of port 3.

• Timer one interrupt.

• Serial port interrupt.

• Timer two interrupt.

• Analog to Digital interrupt.

There are several other interrupts, but we will not make use of them.

4.3 Why We Use Interrupts

The power of interrupts lies in the fact that the various tasks that a micro-processor must control run much more slowly than the microprocessor—eventhe very slow 8051—runs. One way of dealing with very slow processes is tostart something, wait around doing nothing until the process finishes, andthen proceed to the next step.

This style of operation is very wasteful of the processor’s time. Most ofthe processor’s time is spent waiting for something to finish.

When using interrupts, one tells a peripheral to do something, and oneallows the peripheral to interrupt the processor when it has finished doingwhatever it was doing.

One example that pertains to the standard 8051 is the serial transmitinterrupt. A fairly typical 8051 can perform about 1 million operations persecond. The ADuC841 can perform on the order of ten million operations persecond. Transmitting a byte across the serial port at a reasonable speed takesabout half a millisecond—enough time to perform five thousand operations.To transmit one word made up of five letters, would take about 2.5 ms. Thatis time enough for the processor to perform 25,000 operations.

One way of dealing with transmitting five bytes is to transmit a byteand wait until the transmission finishes before sending the next byte. The“correct” way to do this is to use the 8051’s transmit interrupt. What onedoes is to transmit one byte using the on-board peripheral that takes careof serial communications, and then one lets the processor go back to what itwas doing. When the peripheral is finished sending the byte, the peripheralcauses the serial transmit interrupt to be asserted. When the interrupt isasserted, one has the processor move the next byte to be transmitted to theperipheral that takes care of serial communications. After this, one allowsthe processor to return to its “regularly scheduled tasks.” One continuesin this way. When one needs to give more directions to the (slow moving)

34 CHAPTER 4. INTERRUPTS

peripheral that takes care of serial communications one does so. Otherwise,one allows the processor to do its work.

4.4 Enabling Interrupts

Before the microprocessor will react to the changes that can cause an inter-rupt to be asserted, a couple of steps must be taken. First of all, interruptsmust be enabled globally. This is done by setting the highest order bit ofthe interrupt enable register—which is a special function register located ataddress A8H. In MOD52 and MOD841 this bit is given the name EA. That is, toenable interrupts one must give the command SETB EA.

There is a second action that must be taken in order to cause the mi-croprocessor to respond to interrupts. The microprocessor must be told torespond to interrupts generally and it must be told to respond to the partic-ular interrupt of interest. In the case of external interrupt zero, the bit thatmust be set to enable this interrupt is the least significant bit of the interruptenable register. This bit too has been given a name and is called EX0. Thus,to actually cause the microprocessor to react to external interrupt zero onemust tell it to respond to all interrupts (by giving the SETB EA command),and then one must tell it to respond to the external interrupt zero interruptby giving the SETB EX0 command.

Each interrupt has a different bit that must be set to enable the particularinterrupt. To cause the microprocessor to respond to any interrupt one mustenable interrupts globally and one must enable the particular interrupt too.For more information on the various interrupt enable bits, see pp. 70-71 ofthe data sheets for ADuC841.

4.5 Exercises

1. To what location does the ADuC841 vector when external interruptone is asserted. (Please use the data sheets for the ADuC841 to answerthis question.)

2. Which bit of the interrupt enable register must be set to enable theserial interrupt? (Please use the data sheets for the ADuC841 to answerthis question.)

3. Why might one want to globally disable interrupts?

Chapter 5

A Philosophical View of theSpecial Function Registers

5.1 Two Types of SFRs

There are two types of registers that are mapped to the region 80H-FFH.One set of registers are the registers that control how the microprocessorfunctions or that are used by the microprocessor in its functioning. Amongthese registers are the accumulator (whose address is E0H and whose symbolis ACC), the interrupt enable register (whose address is A8H and whose symbolis IE), and the stack pointer (whose address is 81H and whose symbol is SP).

The second set of registers are used to communicate with a variety ofperipherals. These registers pass information to and from the microproces-sor’s “core” to the on-chip peripherals. One can think of these registers asconnecting the internal memory of the “core” of the microprocessor with thecontrol locations of a variety of peripherals.

In the 8052, there is “regular memory” that sits at the same location asthe SFRs. All direct accesses to the location from 080H - 0FFH read or writefrom the SFRs. In order to access the memory that sits at those locations,one must access the memory indirectly.

5.2 Bit Addressable SFRs

Sixteen of the SFRs are bit addressable. These SFRs include the accumu-lator, the SFRs that control ports 0 - 3, and some of the SFRs that controlthe timers. One need not memorize which SFR belongs to which address.The IDE we use comes with “header files,” with the files MOD52 and MOD841,that have all the definitions one needs. Additionally, by default our compiler

35

36CHAPTER 5. A PHILOSOPHICAL VIEWOF THE SPECIAL FUNCTION REGISTERS

recognizes all of the SFRs present in the 8051.For the 8052, the “header” file is c:\ADUC\MOD52. For the ADuC841 the

file is c:\ADUC\MOD841. As the ADuC841 is basically an “extended” 8052,one can use MOD52 as long as one is not intending to make use of any of thespecial features of the ADuC841.

For more general information about the SFRs see p. 22 of the ADuC841’sdata sheets.

5.3 An Example

Let us consider a simple example of such an on-chip peripheral. Let usconsider port 3 of the ADuC841 (or, equivalently, the 8051). The ports onthe ADuC841 (or the 8051) can be controlled pin by pin and some of themcan be either inputs or output. Each pin of a port corresponds to a particularpin on the ADuC841. For example, port 3 pin 0 corresponds to pin 16 onthe ADuC841. (For a diagram of the ADuC841 chip and what each pincorresponds to, see p. 9 of the data sheets for the ADuC841.) Each port iscontrolled by one register. Port 3 is controlled by the SFR at location B0Hand the symbol that corresponds to it is P3. Bit n of the register controlspin n of the port.

One piece of terminology is very important in dealing with bit addressableregisters. To address a particular bit in a register that is bit addressable, onecan write (register name).(bit number). The lowest order bit in a byteis always bit 0 and the high order bit is always 7. Thus, to access the 0 bitof port 3 one can use the terminology P3.0.

Each of the pins that correspond to port 3 can be used either as an inputor an output. Use as an output is simple—setting a particular bit in port3 causes the corresponding pin to go to 5 V. Clearing the bit causes thecorresponding pin to go to 0 V. In Chapter 15 we consider the parallel portsin detail.

5.4 Exercises

1. What is the accumulator’s address in the data memory? Is the accu-mulator bit addressable? (You may want to refer the to the “Micro-Converter Quick Reference Guide” for help.)

Chapter 6

An Introduction to ReusableCode

In this course we will perform many projects. The projects will start outquite small, and their goal will be to teach the student how the 8051 and theADuC841 work. The projects will teach one:

• How to write an assembly language program for the microprocessor.

• How the 3 standard timers of the 8052, timer 0, timer 1 and timer 2work.

• How to control the onboard UART.

• How to use timer 3.

• How to use the parallel I/O ports.

• How to use the DAC.

• How to use the A/D converter.

After doing several projects whose purpose is to familiarize the studentwith the 8052/ADuC841 and its programming environment, we start doingmore complicated projects. Among the projects that we will do there will beprojects that:

• Require the students to develop a “serial clock.”

• Have the student design and implement a frequency measurement tool.

• Show the student how to develop a digital filter.

37

38 CHAPTER 6. AN INTRODUCTION TO REUSABLE CODE

All good programmers are cannibals. It will not be possible to do thelater assignments without cannibalizing from the earlier ones. Make surethat all “general code”—code that controls onboard peripherals—is writtenin such a way that it can be cleanly cut from the program. In particular,make sure that the code that “sets up” the onboard peripherals is clearlycommented and that the mode that the set up leaves the peripheral in isclearly indicated. This will save hours in the later phases of the course. Ifone does not carefully write the earlier programs, the later ones will take upmuch too much time.

Chapter 7

An Introduction to theADuC841

7.1 A General Introduction

In this laboratory you will learn how to write, assemble and run a simpleprogram for the ADuC841. The tool you will use to perform these taskswill be the Keil µVision3 Integrated Development Environment (IDE). (InChapter 11 you will learn much more about how the IDE can help you debugprograms.)

Before you start trying to code anything, let us consider a working program—the program of Figure 7.2.

A few comments will make this program much easier to understand.

• A semicolon in a line denotes the start of a comment. A line that beginswith a semicolon is just a comment.

• By custom the commands and their operands are written in capitalletter.

• R0, ..., R7 are registers zero through seven.

• The instruction clock has a frequency of 11,059,200 Hz. Each instruc-tion clock cycle lasts approximately 0.0904µs.

• Pin 4 of port 3 has been connected to an LED on the evaluation board.We will often use this pin to indicate that something has happened inthe program. As the diode is connected as shown in Figure 7.1, theLED will light up when the output of the pin is 0V. (Please see Problem3 to see why the LED is connected in this fashion.)

39

40 CHAPTER 7. AN INTRODUCTION TO THE ADUC841

Figure 7.1: How the LED Is Connected

7.1.1 The Assembler

Though assembly language is a very low level language, the assembler stilldoes a fair amount of work for the programmer. Often, one must tell aprogram to go to an instruction or to read from a location in memory. Theassembler allows one to assign symbolic names to locations in the code anddata memories.

This type of assignment can be made in several different ways. For ex-ample, the command LED EQU P3.4 sets LED equal to P3.4. It tells theassembler to insert P3.4 wherever the programmer typed LED.

Another place where the assembler has been used is when a label wasneeded for a location in memory. Starting a line with a string followed by acolon, tells the assembler to use that string as a label for that location in thecode memory. For example, DELAY is the label for the address of the codememory that holds the command MOV R7, #8.

Finally the commands JMP and CALL are not directly translatable intocommands to the ADuC841—they are actually interpreted by the assembler.For example JMP LOCATION is actually a command to the assembler to de-termine how to jump to LOCATION. There are three different types of jumpcommands that the ADuC841 (or the 8052) recognizes, and the assemblertries to pick the best one for the purpose. (See p. 2-5 of the assembler manualfor a brief discussion of this feature.)

7.1.2 Some Important Commands

There are several commands that need to be mentioned at this point. Welist four commands and describe what they do and how they are used.

• CLR operand sets the value of the bit operand to zero.

7.2. INTRODUCTION TO µVISION3 41

• SETB operand sets the value of the bit operand to one.

• CPL operand ComPLements the value of the bit operand. That is, ifoperand starts out with a one, it will finish with a zero, and if it startswith a zero it will end with a one.

• MOV destination, source MOVes the value in source to destination.For a very much more detailed description of the command please seethe 80C51 Family Programmer’s Guide and Instruction Set.

7.1.3 Looping

Because of the importance of looping, the 8051 has a special instruction tohelp one loop through a region of code. The instruction is Decrement andJump if Not equal to Zero—DJNZ. This instruction takes either three or fourclock cycles. Its form is DJNZ R#, LABEL (in which form it takes three clockcycles) or DJNZ DIRECT, LABEL (in which form it takes four clock cycles).Note that the compiler allows one to use $ as a label. That causes the “label”to be the beginning of the current instruction.

7.2 Introduction to µVision3

Though there are much simpler assemblers, we will be using µVision3 fromthe first lab. We are not going to explain the program’s more interestingfeatures yet, however. Those will be explained in later chapters. For thetime being, we list the steps you must take to open µVision3 and load aprogram into the IDE’s editor, and then we describe how to setup the IDEso that it will be able to download the compiled version of the program tothe ADuC841.

• Open µVision3–double click on the µVision3 icon.

• Close the “tip of the day.”

• Go to the “Project” menu and choose “new project.”

• Pick a name for the project–perhaps “Lab1.”

• When the “Select Device...” window opens click on “Analog Devices.”

• Select the ADuC841.

• Do not have the program copy the startup code.

42 CHAPTER 7. AN INTRODUCTION TO THE ADUC841

• Go the the left-hand window and click on the “+” to the left of “Target1.”

• Right-click on “Source Group 1” and then click on “Add Files to Group’Source Group 1’.”

• Change Files of type to “Asm Source file (*.s*; *.src; *.a*).”

• Find blse841.asm (assuming that it has previously been stored on yourhard disk) and add it to the group. (If you do not have a copy of theprogram, you can copy the program from Figure 7.2 and save it to yourhard disk as blse.asm. Then add the file to the group.)

• At this point a “+” will appear to the left of “Source Group 1” in thepanel to the left. Clicking on the “+” will show you that blse841.asmis now part of the source group.

• Double click on the blse841.asm and the file will open in the editor.

Now the source code can be edited.

In order to set things up so that the code will be compiled down to a hexfile–a file that can be downloaded to the microprocessor–one must right-clickon “Target 1” in the left-hand panel. Then one clicks on “Options for Target’Target 1’.” Click on the output tab and check the box labeled “Create HEXfile.” Next click on the Utilities tab and in the space under “Use TargetDriver for Flash Programming” go to the drop down arrow and choose “ADIMonitor Driver.” This will allow programs to be downloaded directly fromµVision3. Now click on OK to close this dialog.

7.3 Compiling and Downloading a Program

To compile a file, one can click on the “rebuild all target files” icon, or onecan go to “Project” click on it and then click on “rebuild all target files.”Before downloading the file, one must make sure that the chip is ready toprogram its FLASH program memory. To do this, one must press reset, then,while still pressing on the reset button, one must press on the serial downloadbutton. Then one releases the reset button and, finally, the download button.To download the file to the ADuC841, one must click on the button labeled“load.” After downloading the file, the file will start running immediately.

7.4. THE EXPERIMENT 43

7.4 The Experiment

7.4.1 Part I

Assemble and download blse841.asm. Make sure that the program runs prop-erly after downloading.

7.4.2 Part II

Modify blse841.asm–the original program–to change the period to 5 s on andthen 5 s off. Save the file under a different name, and make sure that thecomments in the program reflect the program’s new goal and structure.

7.4.3 Part III

Modify blse841.asm to use memory addresses rather than registers in theDJNZ command. Make sure that you do not use addresses that will cause thevalues to be stored in SFRs, registers, or addresses whose contents are bitaddressable. Change the comments to reflect the changes in the program andsave the modified program under a new name. Calculate how long the LEDwill be on, and how long it will be off using the new commands. You maywant to look at the “Quick Reference” to find out how long the commandswill take to execute. Note that the oscillator period is:

oscillator period = 1/11,059,200 = 90.422 ns.

Check that the period that you observe when you run the program corre-sponds to the period you calculated. (This can most easily be done by usingan oscilloscope and make use of the “cursors” option.)

7.4.4 The Report

Submit both new programs. Make sure that the programs are properly com-mented. The final grade will depend on how well written and how wellcommented the program is.

44 CHAPTER 7. AN INTRODUCTION TO THE ADUC841

;********************************************************************

; Author : ADI - Apps www.analog.com/MicroConverter

; Revised by: Shlomo Engelberg

; Date : 28 May 1999

; Rev. Date: : 23 May 2002

; Rev. Date: : 27 August 2006

; Rev. Date: : 8 October 2006

; File : blse841.asm

;

; Hardware : Any 8052 based MicroConverter (ADuC8xx)

; Description : Blinks LED continuously.

; The LED is kept on for 1s and off for 100ms.

;********************************************************************

LED EQU P3.4 ; P3.4 is red LED on eval board

;____________________________________________________________________

; MAIN PROGRAM

CSEG

ORG 0000h

CLR LED; clear the LED

BLINK: CPL LED ; flash (complement) the red LED

CALL DELAY ; call short software delay

CPL LED ; comp. the LED

CALL DELAY1 ; call long delay

JMP BLINK ; repeat indefinately

;____________________________________________________________________

; SUBROUTINES

DELAY: ; delay of approx. 100ms

MOV R7,#8 ; 8 * 12.41ms = 99.4ms

MOV R6,#200 ; 200 * 62.1us = 12.42ms

MOV R5,#229 ; 229 * 0.271us = 62.1us

DLY: DJNZ R5,$ ; sit here for 0.271 us

MOV R5, #229

DJNZ R6,DLY ; repeat 200 times (12.4ms delay)

MOV R6, #200

DJNZ R7,DLY ; repeat 8 times (100ms delay)

RET

DELAY1: ; delay approx. 1s

MOV R4,#10 ; 10 * 99.4ms = 1s

DLY1: CALL DELAY

DJNZ R4,DLY1 ; repeat 10 times (1s delay)

RET

;____________________________________________________________________

END

Figure 7.2: A Short Working Program

7.5. EXERCISES 45

7.5 Exercises

1. In the sample program, if one were to change the line MOV R5, #10

to MOV R5, 10, how would this change the meaning of the command?Explain why this is a semantic error but not a syntax error. (Note thatsyntax means “the way in which linguistic elements are put togetherto form constituents,” while semantics means “the study of meanings.”Thus syntax deals with form while semantics deals with substance.)

2. Using the .lst file generated by the compilation of the sample file, findthe machine code that corresponds to DJNZ R5, $.

3. Determine why the LED is connected as shown in Figure 7.1. (Youwill probably want to look at p. 5 of the datasheets. In particular, youmay wish to check how much current the digital outputs can sourceand how much current they can sink.)

46 CHAPTER 7. AN INTRODUCTION TO THE ADUC841

Chapter 8

The Hardware Stack

8.1 When and Why the Stack is Used

A stack is a first in last out (FILO) buffer. By custom putting something onthe stack is called “pushing” the item on the stack, and removing somethingfrom the stack is called “popping” the item from the stack. The 8051 and itsdescendants have built in stacks. The top of the stack is pointed to by thestack pointer, SP. The stack pointer is one of the special function registers. Bydefault the stack starts at location 08H and grows towards higher addresses.The stack is accessed by indirectly accessing the address pointed to by thestack pointer.

When a CALL command is issued or an interrupt occurs, the 8051 and itsdescendants all automatically store the next location—the location to returntoo—on the stack. When the end of the subroutine or interrupt subroutineis reached—when the command RET or RETI is given—the microprocessorPOPs the value of the address to continue from off the stack and jumps to theaddress.

When entering a subroutine, one would often like to save information thatone intends to restore just before returning to the calling program at the endof the subroutine. This is particularly true about interrupt subroutines. Oneconvenient way of doing this is to use the ADuC841’s hardware stack. Onesaves the information by PUSHing it onto the stack. Because the ADuC841expects to find the address to return to at the top of the stack when theRET or RETI commands are issued, it is important to POP all values stored onthe stack before issuing the RET or RETI commands. If one does not POP allthe values before returning, the microprocessor will return to an (relatively)arbitrary memory location.

47

48 CHAPTER 8. THE HARDWARE STACK

8.2 Exercises

1. Please describe the PUSH command and the POP command. Pleaseexplain each command in no more than three sentences.

2. What is wrong with the following subroutine?

PUSH ACC

RET

What kind of problem would you expect the microprocessor to experi-ence?

3. How would one move the stack from address 08H to 80H? Would thismove in any way influence the SFRs?

4. Please explain why the command PUSH A is illegal. How should such acommand be “phrased?”

Chapter 9

Interrupts

9.1 A General Introduction

Interrupt handling for the 8051 is rather simple. Once an interrupt has beenenabled, whenever the interrupt occurs a one bit flag is set and the processorjumps to—vectors to—a fixed location—the location in the interrupt vectortable associated with the particular interrupt. (In most cases, once the pro-cessor vectors to a location, the processor lowers the flag automatically. Inthose cases when it does not lower the flag automatically, the programmermust have the interrupt subroutine lower the flag.) For example, when exter-nal interrupt zero occurs, the processor sets the IE0 bit, vectors to location0003h, and then clears the IE0 bit.

If an interrupt occurs while the processor is already dealing with an in-terrupt, then the processor raises the relevant flag—to “remind itself” thatan interrupt has occured—but continues to handle the interrupt it startedhandling. When it finishes with the interrupt it is handling, it then vectorsto the interrupt whose flag is raised.

9.1.1 Enabling Interrupts

To enable a particular interrupt, two things must be done; interrupts mustbe enabled globally, and the interrupt of interest must be enabled as well.

To enable interrupts, certain bits must be set in the interrupt enable reg-ister. (See p. 6 of the 8051 User’s Guide for more detail about this register.)This register is bit addressable—and the bits are given names in MOD52which is a header file for the 8052 type peripherals and in MOD841 whichis the header file for the ADuC841. (Items that exist in both processors aregiven the same name in each file.)

49

50 CHAPTER 9. INTERRUPTS

One must set the EA bit. This bit enables interrupts globally. If thisbit is not set, no interrupts are active. If one would like to enable externalinterrupt zero, one must also set EX0—the bit that enables the zeroth externalinterrupt.

9.1.2 Some Facts about the External Interrupt Pins

In the case of the external interrupts, there is another bit whose value must bechosen. This is IT0—which determines whether the zeroth external interruptis edge triggered or level triggered. If IT0 is set to 1 then the interrupt isedge triggered, and if IT0 is zero then the interrupt is level triggered.

As the external interrupt pin is also an I/O pin—it is pin two of the thirdport—we must make sure that the I/O pin is set in a way that will allow it tooperate as an input. Port three is an open drain port, and there are internalpull-ups. Thus, a one written to this port does not force a value on the port;it lets the output float and relies on the pull-up resistors to hold the valuehigh. To use this pin as an input, one writes a one to it—using the commandSETB P3.2. (For more information about the I/O pins, see Chapter 15.)

9.2 Bounce

When one closes a switch, the switch’s contacts generally bounce for a littlewhile (on the order of milliseconds). One way of correcting this problem isto build a circuit that responds to one change of voltage and then ignores allchanges that occur in the, say, 50ms after the first change.

9.3 The Experiment

9.3.1 Part I

Write a program that causes the LED to toggle each time external interrupt0 is triggered.

9.3.2 PartII

After pushing the switch, one often sees several changes in the status of theLED. We will take care of this problem by changing our program in such away that after external interrupt zero is asserted, the microprocessor will notrespond to external interrupt zero again for 200 ms.

9.4. EXERCISES 51

When external interrupt 0 is asserted, the microprocessor vectors to0003H. In the new program, have the interrupt subroutine change the statusof the LED and have it clear the interrupt enable bit, EX0. This will stopthe microprocessor from “paying attention to” interrupts of this type untilthe bit is set again. In the interrupt subroutine, set a user defined flag toinform the main program that an interrupt has occurred and then return tothe main program.

In the main program, after performing all the initilizations, have theprocessor repeatedly check the flag you use in the interrupt subroutine. (Youmay want to use a command like JNB FLAG, $.) If the flag is set, then theprocessor knows that an interrupt has occurred – that the button has beenpressed. Have the processor clear the flag and delay for 200 ms. At the end ofthe 200 ms delay, have the processor clear IE0. (Clearing this flag stops thesystem from responding to “bounces” that occured while the program was“wasting time” in the delay loop.) In this way if there was switch bouncein the 200 ms period, the bounce will not cause the LED to “blink.” This isone way of debouncing a switch. After clearing IE0, have the processor setEX0 again. After setting EX0, have the processor start checking the status ofthe user flag again. In this way the processor will not react to bounces, butwill react to actual key-presses as long as they are at least 200 ms apart.

Please make sure to comment both programs clearly.

9.3.3 The Report

Write a one page report explaining what your code does and any interestingtricks you used. Both the program and the report will be graded on correctness,completeness, and clarity.

9.4 Exercises

1. What is the advantage of having both a global interrupt enable bit andseparate bits for each interrupt?

2. How long does it take for a switch to stop “bouncing?” Please cite asource (a book or a website) for your answer.

52 CHAPTER 9. INTERRUPTS

Chapter 10

The Timer Interrupts

10.1 A General Introduction

Often one needs to do something every several seconds, milliseconds, or mi-croseconds. A common example is sampling. One generally needs to samplea signal on a regular basis. Another task that one often wants to do regularlyis to poll a peripheral—a keypad for instance.

To allow one to accomplish such tasks microprocessors and microcon-trollers generally provide timers—on-chip peripherals which can be set tointerrupt the processor on a regular basis.

These devices work by incrementing a register every instruction cycle—but without actually using up any processor time. When the timer’s registeroverflows, it causes an interrupt. These devices are peripherals, external tothe microprocessor’s “core,” with a built-in interface to the microprocessor.

One does not have to let the registers be incremented every instructioncycle—one can have the register be incremented every time the voltage ona specific pin goes from high to low. In this way one can use the timer tocount the number of events that occur. For this reason the timer is generallyreferred to as a “timer/counter.” Once again when the register which is beingincremented overflows, an interrupt is asserted.

The ADuC841—like the 8052 on which it is based—has three generalpurpose timers—Timer 0, Timer 1, and Timer 2. Timer 1 and Timer 2 canbe used to set the baud rate of the UART. In addition, the ADuC841 has afourth, special purpose timer, Timer 3, which can be used to set the baudrate of the UART. In this lab, we only consider Timers 0 and 1.

53

54 CHAPTER 10. THE TIMER INTERRUPTS

10.2 Controlling the Timer

For the details of how the timers work, please see the datasheets for theADuC841. (The information about the timers starts on p. 60.) We presentan introduction to the control of the timers here.

The first two timers, Timer 0 and Timer 1, are controlled using two ofthe SFRs—TMOD and TCON. The final timer is controlled by way of theregister T2CON.

10.2.1 The TMOD SFR

TMOD is not bit addressable—thus one must write to the whole registeranytime one wants to set even one bit.

• Bit 7 is used to gate Timer one—and is not of interest to us. It shouldbe set to zero.

• Bit 6 determines whether timer/counter 1 is a timer or a counter. Itmust be set to make the timer/counter act as a counter and cleared tomake it behave as a timer.

• Bits 5 and 4 are M1 and M0 respectively. These are the mode selectbits. In mode 1—in which M1 is cleared and M0 is set—the two eightbit registers TH1 and TL1 are cascaded to form one 16 bit register. Inmode 2—in which M1 is set and M0 is cleared TL1 is incremented eachclock cycle, and upon overflow it is reloaded with the value stored inTH1. Mode 2 is called auto reload mode.

• Bits 3-0 have the same functions as bits 7-4, but they apply to timer/counter0. Mode 0—which we have not discussed—is different for the two halvesof the register. For more details, see p. 30 of the User’s Guide. Thetwo eight bit registers associated with timer/counter 0 are TH0 andTL0.

Note that when the microcontroller is powered-up, most of the registers as-sume default values. These values are given in the data sheets at the pointat which the peripheral is described. In the case of TMOD, the default valueis 00h.

10.2.2 The TCON SFR

The TCON register is used to control Timers 0 and 1. It is bit addressable.The bit names given in the data sheet are the same names that the assemblerexpects to see as the operands of bit instructions.

10.3. HOW TO SET-UP THE TIMER/COUNTERS 55

The bits’ purposes are as follows:

• Bit 7—known as TF1—is set when timer/counter 1 overflows. It iscleared by the hardware when the PC vectors to the ISR.

• Bit 6—known as TR1—is set in order turn on timer/counter 1. It iscleared to turn off timer/counter 1.

• Bit 5—known as TF0—is set when timer/counter 0 overflows. It iscleared by the hardware when the PC vectors to the ISR.

• Bit 4—known as TR0—is set in order turn on timer/counter 0. It iscleared to turn off timer/counter 0.

• Pins 3 - 0 are not used by the timer, so we do not discuss them here.

10.2.3 The Timer as an Interrupt

We have spoken of the timer interrupt as something that happens automati-cally. However, as with all interrupts, in order for the processor to deal withan interrupt, interrupts generally must be enabled—bit EA must be set—and the particular interrupt of interest must be enabled as well. In our casethe bit that enables Timer 1 is called ET1, and the bit that enables Timer0 is called ET0. (Once again, the names of all the named bits and bytesare given in the file c:\ADUC\mod52 for the 8052 compatible portions andin the file c:\ADUC\mod841 for ADuC841 and 8052 items.) Also, one mustknow where the processor vectors to when the interrupt is asserted. Whenthe Timer 0 interrupt is asserted, the processor vectors to 000Bh. When theTimer 1 interrupt is asserted, the processor vectors to 001Bh.

10.3 How to Set-up the Timer/Counters

Suppose that we would like to cause Timer 0 to assert an interrupt everymillisecond and to toggle the LED each time it asserts an interrupt. We mustdefine the timer/counter as a timer, see to it that the associated register TH0,TL0 overflows once per millisecond, and we must see to it that the associatedinterrupt subroutine causes the LED to toggle.

The evaluation kit has a 11.0592 MHz crystal. Thus, the instruction clockperiod is 1/11059200 = 0.0904µs. The number of instruction clock “ticks”in 1 ms is 11059.2. As one cannot have a fractional clock cycle, we will count11059 ticks before asserting a timer interrupt. The total time to count 11059ticks is 1.0000 ms.

56 CHAPTER 10. THE TIMER INTERRUPTS

We want to start the register pair TH0, TL0 with a number that is 11059from 10000h—from one more than the highest number that a pair of eight bitregisters can hold. The number we want held is D4CDh. That is, we wantto initialize TH0 with 0D4h and TL0 with 0CDh. In fact, each time thatthe register overflows and the interrupt service routine is called the registersmust be reinitialized.

Note that if one needs 256 or fewer clock cycles between timer interrupts,then one can use the auto reload mode to eliminate the need to reload thetimer registers. Also, reloading the registers “by hand” will not give perfectlyaccurately spaced interrupts. To achieve such accuracy, one one must checkthe value of the register immediately before reloading it. Then one mustsubtract the relevant amount—an amount that must take into account thevalue read from the register and how long the subtraction operation takes—from the reload value before reloading the timer register.

10.4 The Experiment

Write a program that uses Timer 1 to cause the LED to blink 500 times persecond. Check that your program works by examining the output of pin P3.4using an oscilloscope. You may use the somewhat inaccurate results you getby using mode 1 of the timer without compensating for the few clock cyclesthat the reload operation requires.

10.5 The Report

Submit the assembly language file you wrote. Make sure that the file isproperly commented. The file will be graded on conciseness, clarity, andcompleteness.

10.6 Exercises

1. Suppose that one uses Timer 0 in mode 2. What is the maximum timebetween timer interrupts given an 11.0592 MHz crystal?

2. Please detail how TMOD, TCON, and TH0 must be set in order tocause Timer 0, when operating in mode 2, to have as much time aspossible between interrupts. Make sure that Timer 1 is not operational.

3. Show how to change bits 4-7 of TMOD without affecting bits 0-3. Youmay want to use the ANL and ORL commands.

Chapter 11

The Integrated DevelopmentEnvironment (IDE)

11.1 Introduction

Modern programming languages often come equipped with a program thatis designed to make using the language easier. These programs provide anenvironment that often includes a word processor, a compiler, a debugger andother features. Such super-programs are generally referred to as integrateddevelopment environments or IDEs.

When one first starts to use an IDE, the IDE usually seems very com-plicated. Once one gets used to working with the IDE one finds that thetools it gives one can be very helpful. There is a rather standard IDE for the8051 family of microprocessors that is produced by Keil Elektronik GmbH.This IDE includes a context sensitive editor—an editor that highlights thevarious commands that the 8051 and the microprocessors in its family use,a compiler, and a debugger.

11.2 Projects

Most IDEs allow and require a programmer to open a new object, called aproject, for each new set of programs. This object includes links to all of thefiles that are used by the given set of programs, and it stores the settingsthat the user wants to have applied when processing the programs.

To start working, open Keil uVision3 by double clicking on its icon. Next,go to the toolbar and click on Project. In the menu that opens pick New

Project. The Select Device window will open. As we are using an AnalogDevices chip, click on Analog Devices. In the list that opens up, click on

57

58CHAPTER 11. THE INTEGRATEDDEVELOPMENT ENVIRONMENT (IDE)

ADuC841. Then click on OK.This tells the IDE what chip you (and it) are working with. Next you

must open a file. Go to File on the tool bar. Then click on New. This willopen a file in the main window of the IDE. Now, in the File menu, go to Save

As and save the file as my_file.asm (where you can use any name insteadof my_file). Using the .asm extension is important to the IDE. It tells theIDE that the program is being written in assembly language. This causesthe editor to highlight assembly commands (rather than C commands).

Next, right click on the Source Group subfolder of the Target 1 folderin the Project Workspace window. Click on the Add Files to Group tab,and add the file my_file.asm.

Finally, right click on the Target 1 folder, and click on “Options for Target’Target 1’.” In the target tab, set the Xtal (MHz) value to 11.0592 to matchthe frequency of the crystal on the evaluation board. Then go to the outputtab and check the “create HEX File” option (which will cause the IDE tocreate a .hex file after compiling the program) and go to the Utilities tab andpick the “ADI Monitor Driver” (which will then allow you to load programsto the evaluation board using the IDE).

11.3 Writing the Assembly Language File

An assembler looks at a text file and converts the mnemonics used into ma-chine readable (but person unreadable) commands. The IDE has an assem-bler. It is possible to tell the IDE to recognize all 8051 commands and registernames—and this is the assembler’s default setting. This setting makes it un-necessary to include definitions of the SFRs as long as one is only using the8051’s SFRs.

If one is using 8052 or ADuC841 SFRs then one must define the namesof the SFRs one is using. The easiest way to do this is to add a directiveto the compiler telling it to include the relevant file. If, for example, oneneeds to include the definitions of the ADuC841’s SFRs, then one adds theline $include (MOD841) to the begining of one’s program. Because this filedefines all the SFRs that exist in the ADuC841, including those SFRs thatexist in the 8051, it is important to tell the IDE not to define those SFRsby default. To stop the IDE from automatically definig the 8051’s SFRs,right-click on Target 1 in the Project Workspace, click on the A51 tab, thenun-check the box labeled “Define 8051 SFR Names,” and then click on OK.If one does not un-check this box, when one compiles the file the compilercomplains that one is attempting to define an already defined symbol.

After saving the assembly language file, one goes to the project window (or

11.4. DEBUGGING THE PROGRAM 59

INC A

JMP WHO ; Jump to location who.

END ; The end of the program.

Figure 11.1: A very small program.

to the toolbar) and clicks on the Build Target tab. The IDE will assemblethe code and will point out any errors or problems with the code. If onedouble clicks on a line in the Output Window (where the error messages aregiven) the IDE will take one to the line in which the error occurs. This canmake debugging somewhat simpler.

11.4 Debugging the Program

Once one has compiled a program without receiving any error messages, it istime to start trying to eliminate errors in the program’s underlying structure.One way to do this is to use the IDE’s debug facility.

To start the debugging process, go to the Debug tab on the toolbar, clickit, and then click the Start/Stop Debug Session tab. This causes the IDEto prepare to simulate the program that has been “built.” Upon startingthe debug session, one will find that the Project Workspace window opens.This window allows one to see the values of the 8051’s eight general purposeregisters, and a host of system registers. Additionally, the debugger will alsoinform one of the number of states—the number of instruction cycles—themicroprocessor has passed through and the number of seconds that havepassed. (This latter number is based on the crystal frequency—which wasentered previously.)

11.5 An Example

Let us use the debugger on the simple program of Figure 11.1. Please enterthis program and build it. Note that the assembler flags an error. Theassembler returns:

myfile.asm(2): ERROR A45: UNDEFINED SYMBOL (PASS-2).

That seems to be saying that there is an undefined symbol somewhere. Click-ing on the line, the IDE flags the second line of the program. One notes thatthe symbol who—which should refer to a location in the code—is undefined.Changing the first line to:

60CHAPTER 11. THE INTEGRATEDDEVELOPMENT ENVIRONMENT (IDE)

who: INC A ; Jump to the location who

and building the file again, we find that there are no more errors to report.Now click on Debug and then on Start/Stop Debug Session. In the

Debug menu (or on the toolbar) click on step. Note how one progressesthrough the program, and note how the registers in the Project Workspace

window change.One can make changes to a file while in debug mode. However, one must

stop the debug mode before one can build the file again.

11.6 Other Helpful Features

In addition to the features that we have discussed so far, the debugger has anumber of other useful features.

11.6.1 Running the Program in the Debugger

In addition to stepping through a file, one can go to the Debug menu (orthe toolbar) and tell the IDE to Run. This causes the IDE to execute theprogram until the IDE hits something that makes it stop. This brings us toour next topic.

11.6.2 Breakpoints

One can insert a breakpoint at any point in the program. One does thisby right-clicking on the line of interest and then clicking on Insert/Remove

Breakpoint. Whenever the IDE reaches a breakpoint, it stops execution ofthe program. This makes it easy to check the microprocessor’s status at thatpoint.

11.6.3 Peripherals

Examine the Peripherals tab. Note that there is a sub-tab for almostevery peripheral one might want. The IDE is pretty good about letting oneexamine what one’s peripherals would be doing on the ADuC841. (In myexperience, however, the A/D and D/A are not emulated very well.)

11.6.4 Watchlists

When run in debug mode, the IDE provides one with the ability to watchone’s variables. To watch a variable, go to the Watches sub-window (on the

11.7. THE EXPERIMENT 61

lower-right hand), click on Watch #1, then click on the area that says “typeF2 to edit,” click on F2, and then type the name of the variable in which oneis interested. The IDE will display the value of the variable (or variables)when it executes the program.

11.6.5 The Logic Analyzer Window

The IDE also provides us with a logic analyzer (which is also an oscilloscope).To open this tool, either click on its icon, or click on “view” and then clickon “logic analyzer window.” When the window opens, click on the setupbutton (at the upper left of the window), push the insert key, and then typethe name of the variable you would like to have displayed.

The IDE has many more features, but the ones mentioned should beenough to get you started.

11.7 The Experiment

Please write a program that causes the LED connected to P3.4 to blink onceeach second. Use Timer 0 in mode 2 to control the period. Use the IDEto write the program, and examine the program using the debugger. Makesure to make use of the I/O ports tab in the Peripherals menu. Use thewatchlists, and use the logic analyzer window to examine the ouput of P3.4 in“real-time.” After debugging the program, run the program on the ADuC841and make sure that the program actually runs correctly.

11.8 The Report

Please submit a completely commented program as the lab report. If theprogram behaved differently from the way the IDE predicted, please submita brief description of the differences and your best guess as to why there weredifferences.

11.9 Exercises

1. If one uses the WSD program to download and run a program, thenwhen one finishes giving the ADuC812 the RUN command, a few of theSFRs are not left initialized to their values after reset. In particular,TR1 is set after the RUN command. (The ADuC812 is almost identicalto the ADuC841. The ADuC841, however, does not “corrupt” TCON

62CHAPTER 11. THE INTEGRATEDDEVELOPMENT ENVIRONMENT (IDE)

in this fashion.) Suppose that a student has a program that doesnot work on the IDE, but decides to download the program to theADuC812. (The student is very stubborn and refuses to try to debugthe program.) The student finds that the program does run on theADuC812. Without assuming that the IDE does not work correctly,explain why the program might work on the ADuC812 while it doesnot work properly when simulated on the IDE. (What programmingerrors might the student have made?)

2. In the Project Workspace window of the Keil IDE, there is a registercalled sp. Please find out what this register is and what its purpose is.Please describe the register in two sentences.

Chapter 12

Using the Onboard UART

12.1 General Introduction

Often one needs to connect one’s microprocessor to another microproces-sor and the two devices must “talk” to each other. One of the standardmethods of connecting microprocessors (and computers generally) is to usea Universal Asynchronous Receiver Transmitter (UART). Here we give abrief introduction to the UART provided with the ADuC841. The completeUART documentation is contained in the ADuC841 datasheets on pp. 65-69.For a general introduction to UARTs, see:http://www.freebsd.org/doc/en_US.ISO8859-1/articles/serial-uart/.

The first parameter that one must understand is the baud1 rate. Thebaud rate, given in symbols per second—in the case of our UART, bits persecond (bps)—is the number of symbols that the UART transmits or receivesper second. Next one must understand how the UART encodes informationbefore transmitting the information. When passed n bits to transmit, theUART always prepends one extra bit—a start bit—to the beginning of thetransmission, and it appends one, one and a half, or two bits—stop bits—tothe end of the transmission. The UART can also add a parity bit betweenthe end of the data and the stop bit(s).

When one sends 8 bits using a UART running at 19200 baud, withoutparity, and with a single stop bit, how long does the transmission take? Eachbit takes 1/19200 seconds. As there are eight data bits, one start bit, onestop bit, and no parity bit, there are a total of 10 bits. Thus, the total timeto transmit the byte is 10/19200 = 1/1920 = 0.52ms.

1Named after the French telegrapher Jean-Maurice-Emile Baudot (1845-1903).

63

64 CHAPTER 12. USING THE ONBOARD UART

12.2 The Onboard UART

The UART on the ADuC841 is an 8051 type on-chip peripheral. It is rela-tively easy to control. The most complicated part of its control is setting thebaud rate. There are several ways of controlling the baud rate—we will notdiscuss all of them.

The SFR that controls the UART is the SCON register. SCON is a bitaddressable register. Its bits serve the following purposes:

• Bit 7 — SM0 and...

• Bit 6 — SM1 are the serial mode select bits. We will use SM0 = 0,SM1 = 1. This is called mode 1, and it puts the UART in 8-bit variablebaud rate mode. We will see how one sets the baud rate later.

• Bit 5 — SM2 is the multiprocessor communication enable bit. We willnot tamper with this bit.

• Bit 4 — REN is the serial port receive enable bit. This bit must be setto one to allow the serial port to receive.

• Bit 3 — TB8 is not used in mode 1.

• Bit 2 — RB8 is not used in an essential way in mode 1.

• Bit 1 — TI is the serial port transmit interrupt flag. This bit is setwhen the UART has finished transmitting a byte. Because there isonly one serial port interrupt, the processor must have some way ofinforming the user whether the interrupt was triggered by the end ofthe transmission of a byte or by the reception of one byte. This bit andbit 0 allow one to determine what the cause of the interrupt was.

• Bit 0 — RI is the serial port receive interrupt flag. It is set when abyte has been received. Note that TI and RI are not cleared by theADuC841. They must be cleared in the interrupt subroutine.

If one is interested in sending and receiving 8 bits of data in variable baudrate mode, one sets SM0 to 0, SM1 to 1, SM2 is left alone, and REN is setto 1.

Next one must set the baud rate. This is done by setting Timer 1, Timer2, or Timer 3 to overflow at an appropriate rate. We will now consider howto use Timer 1 to set the baud rate. (See Chapter 14 for detailed instructionsabout the use of Timer 3.) When using Timer 1, the baud rate is set by:

baud rate =2SMOD

32× (Timer 1 overflow rate).

12.3. WRITING A STRING TO THE UART 65

Note that SMOD is bit 7 of PCON, a non bit-addressable special functionregister (SFR). To change the value of one bit of PCON one must or itscurrent contents with a byte that is one in its seventh bit. When using Timer1 to control the baud rate, the Timer 1 interrupt should be disabled. Oneneither needs nor wants to interrupt the processor each time the timer registeroverflows. Also, if the timer produces no interrupt, it must be reloadedautomatically—it must be run in mode 2. To enable the serial interrupt, onemust set the serial interrupt enable bit, ES. As always, when an interrupt isasserted, the processor vectors to a specific location. In the case of the serialinterrupt, the processor vectors to 0023h.

In order to send a byte when the UART has been set up, one moves datato the serial buffer, SBUF. The UART will start transmitting the data whenSBUF is written. In order to read data from the UART, one reads fromSBUF. Physically, one is reading from a different location from that whichone writes to by writing to SBUF. Since one never needs to read from thetransmit buffer or to write to the receive buffer, the two buffers “share” aregister.

12.3 Writing a String to the UART

In order to write a string to the UART without wasting massive amounts oftime, one uses the transmit interrupt. Suppose that one wants to transmit astring. One transmits the first letter of the string, and then one “tells” theUART (by programming it with an intelligent interrupt service routine) thateach time it finishes transmitting one byte—each time a transmit interrupt isreceived—it should transmit the next byte. After transmitting the last byte,the next transmit interrupt should be ignored.

12.4 The Experiment

The evaluation board for the ADuC841 comes with all of the parts that oneneeds to connect the board up to the com port of a PC. The simplest way to“talk” to the ADuC841 is to run hyperterminal on a PC and use the cablethat is included with the evaluation board to connect the board to the PC.

Write a program that echos all characters transmitted to the UART backto the computer. Use Timer 1 to control the baud rate, and remember to setthe computer’s baud rate to the same baud rate that you choose. Note thatas you are always transmitting one character at a time, you do not need touse the transmit interrupt. Thus, you must ignore all serial interrupts that

66 CHAPTER 12. USING THE ONBOARD UART

came because the transmission of a byte was completed.Next, write a program that sends a single byte to the UART each time

P3.2 is grounded. (Make use of external interrupt 0 to detect and react tothis event.) Note that the UART transmit pin is P3.1 and that this pinis available on the evaluation board. Use a digital oscilloscope in “normalmode” to observe the output of P3.1. In a brief comment added to thecode you submit, explain how the signal that you observe on the oscilloscopeagrees with what we have seen about the UART.

12.5 The Report

Please submit your carefully commented code. Remember that the code willbe graded on completeness, correctness, and conciseness.

12.6 Exercises

1. Use the formula on p. 64 of this manual to calculate values of SMOD andTH1 that correspond to a baud rate of 19,200 baud.

2. What is the lowest baud rate one can achieve in our system when usingTimer 1 in autoreload mode?

3. Most interrupts have bits—flags—that when set indicate both to theinternal operations of the processor and to the user that an interrupthas been asserted. The TI and RI flags perform this function for theUART’s transmit and receive interrupts, respectively. Because theseflags are not cleared by the processor when the processor vectors tothe interrupt, the flags must be cleared by the user in the interruptssubroutine.

(a) What is the equivalent flag for the Timer 1 interrupt?

(b) Does this flag need to be reset by the user? (Please provide areference for you answer.)

Chapter 13

Using the OnboardUART—Printing aPreprogrammed String

13.1 General Introduction

In order to communicate with the outside world, one must often send mes-sages. Generally speaking the set of messages one might wish to send isknown—save perhaps for some numbers that may be a function of what isgoing on.

We are going to store our strings as C-type null-terminated strings. Thatis, we are going to store each string with a zero at the end. We will store thestring in the program memory. We will then read the string and send it tothe UART.

To perform these tasks we will make use of several new commands.First of all, reading from program memory requires the use of a differentcommand—MOVC. Also, strings must be stored in the code segment. For thiswe make use of the DB directive. Also, we must learn how to properly makeuse of the transmit interrupt.

13.2 The New Commands and Techniques

13.2.1 Reading from the Code Segment

To read from the code segment one uses the command MOVC. This commandis covered on p. 41 of the 8051 Programmer’s Guide and Instruction Set. Theform of the instruction that we will use is MOVC A, @A+DPTR. This instruction

67

68CHAPTER 13. USING THE ONBOARDUART—PRINTING A PREPROGRAMMED STRING

loads the accumulator with the value stored in location A + DPTR. DPTR isthe data pointer register. The accumulator (the register to which A refers) isinitially loaded with the offset from the value stored in DPTR.

In a standard 8051/2, DPTR is a 16 bit register. (In the ADuC841, in orderto make it possible to address more memory, DPTR can also function as a 24bit register; by default the 16 bit version of the register is what one “sees.”As we are not interested in the 24 bit option, we will not discuss it further.)The instruction MOV DPTR, #(16 bit word) is used to load a 16 bit wordinto the (lower 16 bits of the) register. The 16 bit version of this instructionis described on p. 41 of the 8051 Programmer’s Guide and Instruction Set.

13.2.2 Some Assembler Directives

Sometimes one needs to store items or reserve space in various memory seg-ments. Most commonly the data is stored in the the code segment and spacefor temporary storage is reserved in the data memory segment or the bit-addressable memory. The details of how this is done can be found on pp.42-45 of the 8051 Cross Assembler User’s Manual.

To reserve space in the data segment, one must first use an assemblerdirective to tell the assembler that one wishes to switch to the data segment.This command is DSEG. One can append to this command a command thattells the assembler where in the data segment to start from. This is importantas the lowest section of the data segment should not be used for simple storage.The first 32 bytes of the data segment are general purpose registers. The next16 bytes are the bit-addressable memory. I advise using the command DSEG

AT 30H. This tells the assembler to start from byte number 30H—which isthe 49th byte. Having told the assembler that you want to reserve space inthe data segment, one must next tell it how much space to reserve. If onewould like to reserve one byte and have the ability to refer to that byte asMAX, one uses the command MAX: DS 1. One can now use MAX anyplace that you could have used a location in memory.

To store data in the code segment, one uses the DB—the data byte—directive. This directive tells the assembler to store the bytes that followthe directive in the code memory. One can give a name to the location fromwhich the assembler starts storing the data as well. Consider the followingcommands:

ORG 0100H

NAME: DB ’This course is’; Here is the first part of the string.

DB ’ great.’ ; Here is the second part. Breaking

;it in two does not affect anything.

13.3. THE EXPERIMENT 69

DB 13 ; Carriage return.

DB 10 ; Line feed.

DB 0 ; 0--the infamous null-termination.

Assuming that one is in the code segment (or adding the command CSEG

before ORG 0100H), the first line tells the assembler to move to position 100Hin the code segment. This puts the data at a point that is relatively far fromthe actual program. The next command says to assign the name NAME to thecurrent location. Next we see one of the nice features of the assembler. Ifone uses single quotes, then the assembler knows to store the ASCII valuesof the characters between the quotes one after the other. The numbers 13and 10 are carriage return and line feed. The zero that appears at the endis the null-termination.

Finally to reserve bits in the bit-addressable segment, one must firstswitch to that segment—using the BSEG command. Then one uses the com-mand DBIT. For example, to reserve space for the flag TRIGGERED, one usesthe command:

TRIGGERED: DBIT 1

This reserves one bit for the flag.

13.2.3 Writing a String to the Serial Port

Because the UART is so much slower than the processor, one does not writea string all at once. What one does is, one writes a byte to the UART andthen continues with one’s main program. Then one has the UART send thenext byte when a transmit interrupt is received. One causes one’s programto ignore the transmit interrupt that occurs after the last byte is sent.

13.2.4 Forcing an Interrupt

Sometimes it is convenient to “trick” a microprocessor into believing thatan interrupt has occurred even when that is not the case. To cause suchan event, one must set the relevant interrupt flag. For example, to cause atransmit interrupt, one must set the TI flag.

13.3 The Experiment

Write a program that writes strings—that you have saved in the code segmentas a null-terminated string—to the serial port whenever the user types one

70CHAPTER 13. USING THE ONBOARDUART—PRINTING A PREPROGRAMMED STRING

of the characters ’a’, ’b’, ’c’, or ’d’. Use different strings for each character.Ignore all characters that are typed while the string is being sent to theUART. Make sure to use the IDE to simulate the program before the programis run. This may save hours of work debugging the program!

13.4 The Report

Please submit your carefully commented code. Remember that the code andcomments will be graded on completeness, correctness, and conciseness.

13.5 Exercises

1. In general instructions for the ADuC841 (and the 8051 family) refer to8 bit objects. The instruction MOV DPTR, #(16 bit word), however,moves a 16 bit word into a 16 bit register. What is the op-code—the machine code—for this instruction? Explain why the existence ofseparate codes for different forms of an instruction makes it easy tohave both 8 bit and 16 bit forms of an instruction.

2. Why is there no instruction to allow one to move information intoprogram memory while the microprocessor is running? (Please considerthe nature of the program memory in your answer.)

3. Please explain why it is important to clear the transmit and receiveflags once the processor has vectored to the UART ISR. (Any reasonableanswer will be accepted.)

4. What is wrong with the following set of commands:

DSEG AT 30H

NAME: DS ’Jerusalem’

Why is the set of commands unreasonable as well as illegal?

5. Using the “MicroConverter Quick Reference Guide,” please determinewhich 3 SFRs hold the 24 bits of the register DPTR.

6. Using the “MicroConverter Quick Reference Guide,” please determinewhether INC DPTR acts on 16 or 24 bits of DPTR. Also, check whetherMOV DPTR, (#24 bit data) is a legal command.

Chapter 14

Timer 3

14.1 Introduction

The 8051 microcontroller has 2 timers, Timer 0 and Timer 1. The 8052has an additional timer, Timer 2. All three of these timers are relativelygeneral purpose. The ADuC841 has a fourth timer—Timer 3. This timeris designed to do one thing and one thing only—to provide a clock to theUART. This allows one to use the other three timers for other functions.Timer 3 is one example of a special purpose peripheral that has been addedto the ADuC841. There are quite a few other special purpose peripherals.

14.2 Using Timer 3

In order to use Timer 3 to clock the UART, one sets up the UART itself as inChapter 13—however one does not use Timer 1 to clock the UART. Instead,one sets up Timer 3 to take care of clocking the UART.

There are two registers connected to the operation of Timer 3. The firstis T3CON and the second is T3FD. T3CON is not bit addressable, and its defaultvalue is 0. Its bits serve the following purposes:

• Bit 7, T3BAUDEN, enables Timer 3 to provide the clock to the UART.It is set to make Timer 3 the source fo the UART’s clock.

• Bits 6-3 are reserved and should not be changed.

• Bits 2-0, DIV2, DIV1, and DIV0 respectively, control the divide factor—about which we shall learn shortly. The three bits should be considereda single three bit binary word.

71

72 CHAPTER 14. TIMER 3

The second register, T3FD, contains a single number between zero and255. The baud rate that Timer 3 provides is:

baud rate =2× fcore

2DIV−1(T3FD + 64).

Here fcore is generally 11.0592 MHz for our board. The recommended methodof calculating the two numbers is to first calculate:

DIV = floor

(log2

(fcore

16×Baud Rate

)).

Next one calculates T3FD according to the formula:

T3FD = round

(2fcore

2DIV−1 ×Baud Rate− 64

).

Finally the actual baud rate will be given by:

Actual Baud Rate =2fcore

2DIV−1(T3FD + 64).

14.3 The Experiment

Write a program that writes strings—that you have saved in the code segmentas a null-terminated string—to the serial port whenever the user types oneof the characters ’a’, ’b’, ’c’ or ’d’. Use different strings for each character.Ignore all characters that are typed while the string is being sent to theUART. Use Timer 3 to clock the UART and set the baudrate to 115,200baud. Make sure to use the IDE to simulate the program before the programis run. This may save hours of work debugging the program!

14.4 Exercises

1. Please produce an Excel spreadsheet or a MATLAB program to calcu-late DIV and T3FD for an arbitrary baud rate.

Chapter 15

Using the Parallel Ports

15.1 General Introduction

The 8051 and the processors in the 8051 family have four parallel I/O ports—ports 0-3. Each parallel port has several input/output pins. In general, pinn of port m is referred to as Pm.n. Each pin of a parallel port can be thoughtof as a device built from a switch and some peripheral circuitry as shown inFigure 15.1. The dashed items are included in ports 2 and 3 but not port 0.(Port 1 of the ADuC841 is an input-only port.)

15.2 How the Parallel Ports Operate

15.2.1 The Connection between the Registers and thePins

The pins on each port are individually addressable by using the bit address-able registers P0, P1, P2, and P3. To address the third bit of port 3, one writesP3.2. (Keep in mind that the first bit is bit 0.) Note that P3.2 sometimesrefers to pin 2 of port 3 and sometimes refers to the third bit of register P3.From the programmers point of view, this terminology is reasonable. Whenone sets a bit of register Pm.n, the controlling circuitry makes changes to thestatus of pin n of port m. To the programmer the register and the pins formtwo pieces of one object.

15.2.2 Parallel Ports 0, 2, and 3 as Outputs

Each pin of each of the parallel ports (except for port 1) can be used as aninput or an output. Let us first consider how they can be used as outputs.

73

74 CHAPTER 15. USING THE PARALLEL PORTS

Figure 15.1: A Schematic Description of a Parallel Port

We assume that the voltage v0 is examined by a high-impedance device. Inthis way, the output voltage is not changed by “loading” effects. When onewrites a zero to Pm.n the switch in Figure 15.1 closes. This causes the outputof the pin, vo, to be shorted to ground. Thus the output will be zero. Whenone writes a one to Pm.n the switch in Figure 15.1 opens.

In ports 2 and 3, the examination point—the point from which vo is read—is connected to VCC through a resistor. As long as a very high impedanceload is all that is connected to the examination point, there will be verylittle—approximately no—current flowing through the resistor. Thus, therewill be no voltage drop across the resistor. This causes the output of thepin to be VCC . VCC is dependent on the supply voltage of the chip; in ourcase it is 5 V. The resistor connected between VCC and the output is calleda pull-up resistor. Its function is to pull-up the voltage at the output whenthe “switch” is open.

In port 0, the resistor and power supply connection are absent. When aone is written to P0.n all that happens is that the output of the pin “floats.”Thus, the output pins of port 0 are either forced to ground—when a zero iswritten to a pin—or are allowed to float—when a one is written to a pin.This is useful if one would like to interface the microprocessor to a device

15.2. HOW THE PARALLEL PORTS OPERATE 75

that does not run off the same voltage as the microprocessor. In such a case,one attaches an external power supply and pull-up resistor to the output pin.Suppose that the external power supply is 3.3 V. Then when a zero is writtenthe output will be forced to zero. When a one is written the output is pulledup to 3.3 V by the external supply and pull-up resistor. Note that each pinof port 0 can be run at a different voltage. Port 1 is an input only port, sothe above discussion does not apply to port 1.

15.2.3 The Registers P0, P2, and P3

We have seen that P0, P2, and P3 control ports 0, 2, and 3. Shortly we willsee that these registers can also be used to examine the values of the pinswhich they control. Moreover, it is possible to write one value to a port andto read a different value from the port. How can that be?

When one writes to registers P0, P2, and P3 one is actually writing toa latch whose individual bits control “switches” like those of Figure 15.1.Writing a one to the latch causes the switch to be opened, and writing a zeroto the latch causes the switch to be closed.

When one checks the value of Pm.n using the JB or JNB commands, onecauses the microprocessor to check the voltage physically present on the pinPm.n. If the voltage corresponds to a logical one, then the bit is consideredset and JB or JNB “sees” a one. If the voltage on the pin corresponds to alogical zero, then the bit is considered cleared and JB or JNB see a zero.

On the other hand, certain instructions that read from the I/O ports readthe value of latch—read the current setting of the switch—rather than thevoltage on the pin. One such instruction is the JBC bit, label command.This command reads the value of bit, jumps if bit is set, and clears bit

before proceeding to the next instruction. When the JBC command is usedto read a bit that is “connected to” a port, the command checks the currentstatus of the latch—and not the voltage on the pin. For more on this generaltopic, see the “Read-Modify-Write Instructions” section of the datasheets.(This section can be found on p. 59 of the datasheets.)

15.2.4 Ports 0, 2, and 3 as Inputs

To use pins of ports 0, 2 and 3 as inputs the first thing that one must dois write a one to the relevant pins. Why? Because if a zero is written to apin, then the pin’s internal examination point (see Figure 15.1) is shorted toground and the only voltage one can ever see at that point is zero. Assumingthat a one has been written, the switch at the relevant pin is open, and onecan force the voltage at the examination point to whatever value one desires.

76 CHAPTER 15. USING THE PARALLEL PORTS

As ports 0, 2, and 3 are digital ports, the voltage one applies to them shouldbe either 0 V or VCC .

In fact, however, the wise designer follows a slightly different path. Thewise designer sets up the system so that when a zero is to be input, thevoltage on the pin is forced to zero. When a one is to be written, the pin isallowed to float. Because of the pull-up resistor, when no voltage is appliedto a pin, the examination point’s voltage is pulled-up to VCC . In this way,it is impossible to damage one’s system by accidentally applying a voltageto a pin whose output is currently shorted to ground. This is an example ofbelt-and-suspenders engineering.

15.2.5 Port 1

Port 1 is an input only port. However, its pins can be either digital inputs—when 0 has been written to the appropriate pin—or analog inputs—when 1has been written to the appropriate pin. It is perfectly legal to have somepins be digital inputs while others are analog inputs.

15.2.6 Alternate Functions

Many ports—or individual pins on ports—can serve one of several purposes.Ports 0 and 2 are used to control the external memory if there is any, andon the ADuC841 port 1 can be used either for digital or analog input. Ad-ditionally some of the pins on port 1 have alternate functions, and all of thepins on port 3 have alternate functions. The parallel ports are described onp. 57 of the data sheets.

15.2.7 Using the Ports

Using the pins on the parallel port is easy. Writing a one to a bit on aport opens the switch associated with that pin. Thus, SETB P3.4 opens theswitch associated with pin four of port three. Any command that reads fromone of the bits associated with a port returns the current status of the pinassociated with the bit. If pin 5 of port 3 has been shorted to ground, thecommand JB P3.5 HIGH will not jump to the location HIGH even if the lastoperation performed on the bit P3.5 was SETB P3.5. The command will justcause the processor to proceed to the next instruction.

15.3. THE EXPERIMENT 77

15.3 The Experiment

Whenever a user hits the key ’t’ or ’T’ (for test) examine the voltage on pin3.2. If the pin is high send a message to the PC that will print out a messagethat the pin is high. Similarly, if the pin is low, send a message to that effect.If any other keys are hit, make the PC beep by using the “bell” or give someother indication that an error has occurred.

15.4 The Report

Submit your carefully commented code. Remember that the commented codewill be graded on completeness, correctness and conciseness.

15.5 Exercises

1. Read the material in “The Programmer’s Guide” that explains the useof the CJNE command. Please explain in 3 sentences or less how thecommand works.

2. If the pin associated with port 3 pin 2 is connected to ground and onesets P3.2 and then checks the value of P3.2 using the JB command,what value will one detect? Will the bit be set or cleared? Explain.

3. Give a good reason why so many pins can be used for one of severalfunctions.

4. Explain the expression belt-and-suspenders. Why will a good engineeroften perform designs in this way?

5. If one clears P3.0 and then connects a 5V source to pin 0 of port 3 onthe ADuC841, what will happen? Note that doing this is clearly a verybad idea.

78 CHAPTER 15. USING THE PARALLEL PORTS

Chapter 16

A Serial Port Controlled Clock

16.1 General Introduction

In this lab, we design a clock that is accurate to several seconds a day andthat “prints” the time to the serial port. To do this, we use the ADuC841’sthird timer. We must understand Timer 2.

Additionally, in order to print the time to the serial port, one must createan appropriate string in the data memory. This is an interesting task as well.

16.2 Timer 2

For the details of how the timers work, please see the datasheets for theADuC841. (The information about the timers starts on p. 60) We presentan introduction to the control of Timer 2 here. Timer 2 is controlled byT2CON.

16.2.1 T2CON

T2CON is the bit addressable register that controls the third timer.

• Bit 7, TF2 is set by the hardware when the timer overflows. TF2 must becleared by the user in the Timer 2 interrupt service routine—otherwisethe interrupt will be triggered again. TF2 is not set if Timer 2 is usedas the transmit or receive clock for the UART. (This is done by settingTCLK and/or RCLK.)

• Bit 6 is not of immediate use to us.

• Bit 5, RCLK, is set if one would like to use Timer 2 as the receive clockof the UART.

79

80 CHAPTER 16. A SERIAL PORT CONTROLLED CLOCK

• Bit 4, TCLK, is set if one would like to use Timer 2 as the transmit clockof the UART. Note that when these two bits are not set, then Timer 1(or Timer 3) is used as the serial clock.

• Bit 3 is not of immediate use to us. It should be cleared for our uses.

• Bit 2, TR2, is the bit that turns on Timer 2.

• Bit 1, CNT2, determines whether the timer functions as a timer or asa counter. When set, the timer functions as a counter. When clearedthe timer functions as a timer.

• Bit 0, CAP2, will generally be set to zero in our applications. Thissets the timer to automatically reload on Timer 2 overflow. Timer2’s registers TH2 and TL2 are reloaded from the registers RCAP2H andRCAP2L.

The power-on default of T2CON is 0.To enable interrupts from Timer 2, the bit ET2 must be set. When a

Timer 2 interrupt occurs, the processor vectors to 002Bh.

16.2.2 Printing a Variable String

To print a string, one generally writes a pair of subroutines. The first subrou-tine initializes all relevant “pointers” and the second, the Serial ISR, sendsout a new character as each old character is sent.

Previously we have needed to transmit one of a fixed set of strings. Westored the fixed strings in the code memory. We must now store the variablestring in the data memory and the program must compose the string. Alterthe code that was used to output the fixed string to allow it to handle run-time strings.

16.2.3 More about Interrupts

When using interrupts it is best to do as little as possible in the actual ISR.It is generally better to have the ISR do only those things that cannot bedone later. The ISR should raise a flag (and this is what the BSEG is for)that tells the “main” program that an interrupt occurred.

Sometimes, when writing short programs in which there are not too manyactive interrupts, these practices are not followed. As a rule, however, theyshould be.

Also, if one cannot reserve registers for specific ISRs, then when an ISRis called that ISR must backup whatever registers it is going to use. When it

16.3. THE EXPERIMENT 81

is about to return control of the processor, it must restore the registers. Inthis way the main program need not worry about the ISR.

16.3 The Experiment

Set up Timer 1 to act as the clock for the UART. Set Timer 1 to give a baudrate of 19,200 baud.

Use Timer 2 as the time base for a clock. Note that when Timer 2 is setto run in autoreload mode, it reloads a 16 bit word from the register pairRCAP2H and RCAP2L. This allows one to use Timer 2 to produce relativelyinfrequent interrupts.

Use Timer 2 and a set of software counters to keep track of the minutesand the seconds since the program started or since someone zeroed all thecounters. Output the elapsed time via the serial port every minute. Use theformat hh:mm:ss. Make sure that your clock works properly until at least 99hours and 59 minutes have elapsed. (To test your clock, you can use reloadvalues that make the Timer 2 interrupt occur much more rapidly than willbe needed in the final program.)

Also, allow the user to type in a one letter command to reset all thecounters and restart the clock.

16.4 The Report

Submit the assembly language file you used, and make sure the file is properlycommented. The code and comments will be graded on conciseness, clarity,and completeness.

16.5 Exercises

1. What is the longest time between Timer 2 interrupts when Timer 2 isrunning in its autoreload mode? Why is this different from Timer 0and Timer 1?

2. Why can’t we store variable strings in the program memory?

3. (a) What information is kept in the program status word (the PSW)?

(b) Why should one save the PSW at the begining of an interruptsubroutine and restore it at the end of the subroutine if one isgoing to perform additions in the interrupt subroutine?

82 CHAPTER 16. A SERIAL PORT CONTROLLED CLOCK

Chapter 17

A Counter

17.1 General Introduction

In this lab we write a program that enables the ADuC841 (or any 8052compatible microprocessor) to measure the number of pulses appearing onpin P3.4 in each second. It also allows the processor to “upload” the numberto a host using the UART. No new peripherals are introduced in this lab,but it is the first time that a timer/counter is used as a counter.

17.2 Using a Timer/Counter as a Counter

To use a timer/counter as a counter, one must set the appropriate bits inthe TMOD register. First of all, the appropriate C/T bit must be set to 1.Second of all, if one wants to count using the two byte register combination,one must set the mode bits to put the timer/counter in mode 1 (M1 = 0, M0

= 1). (The information about the timers starts on p. 60 of the datasheets.)Also, one must connect the source of the pulses to the correct pin. In this

case that is pin P3.4.

17.3 The Experiment

If one is to use Timer 1 as the time base of the UART as we have until now,then one must use Timer 0 or Timer 2 as a counter. One must also use oneof those two timers to tell one when one second has passed.

Because Timer 2 has a reload mode that allows us to reload from a registerpair, we can run it in reload mode while allowing it to use two cascaded 8-bit registers. This allows it to generate relatively infrequent interrupts. As

83

84 CHAPTER 17. A COUNTER

we shall want to produce interrupts once a second—very infrequently—wechoose to use Timer 2 as the timer and Timer 0 as the counter.

Note that even using Timer 2 one cannot get one interrupt every second.Further note that using Timer 2 it is easy to get one interrupt every 5 ms.

Set Timer 2 to give an interrupt every 5 ms. Have Timer 2 raise a flagevery second. Have the main program read the value of the counter 0 countereach second, and zero the counter immediately after reading it.

Write a simple routine to take the 16-bit word you have read and convertit into a string that will print a 4 digit hex number when sent through theUART. Have the microprocessor upload the string each second.

17.4 The Report

As usual your report consists of two parts. You must submit the assemblylanguage file you used—and the file must be properly commented! Also,you must submit a written report explaining in somewhat more detail whatyour program does. The report will be graded on conciseness, clarity, andcompleteness.

17.5 Exercises

1. When one speaks of “raising a flag” one means setting a particular bitto ‘1’ or ‘true.’ What instruction is used to do this? What instructionis used to test if a bit is set?

2. Explain why it is easier to convert a number stored in binary to hexthan it is to convert the number to (the more easily read) decimal.

Chapter 18

Interfacing a Keypad

18.1 General Introduction

A j × k keypad is a device in which j rows of wires run perpendicular to kcolumns of wires. There is a key that sits at the junction of each row andcolumn—there are j ·k keys. Pressing down on the key at the junction of thejth row and the kth column shorts the jth wire to the kth wire. (See Figure18.1.)

By experimenting intelligently with a DVM set to work as a continuitytester, it is possible to determine which of the pins on the keypad connectorconnects to which of the rows or columns. In this lab, we will be using a 4x3keypad, and it is pretty simple to work out the connections.

We will connect the keypad to port 2—one of the parallel ports thathave pull up resistors. The first pin on the keypad is led to pin P2.0 on theADuC841.

The way that one checks which key has been pressed is by lowering thevoltage on one row of keypad and then checking each of the columns to seeif the voltage on the column has gone low as well. If it has, then the buttonthat sits at the junction of that row and that column has been pressed. Oneproceeds to check all of the rows and columns in this fashion.

18.2 The Experiment

In this experiment we check the status of a keypad two hundred times asecond. Each time a key is pressed, we send the appropriate character to theUART.

Please write a program that uses Timer 2 to generate an interrupt every5 ms. In the interrupt subroutine for Timer 2 have the processor lower the

85

86 CHAPTER 18. INTERFACING A KEYPAD

Figure 18.1: A Schematic Description of a 4x3 keypad. Each circle representsa push-button switch.

voltage on a row and then check to see if the voltage on any of the columnshas gone low as well.

Please use Timer 1 to drive the UART’s clock so that the UART runs at19200 baud. Do not enable the serial interrupt—it is not necessary.

When a character is detected send the appropriate ASCII value to theUART and then return from the Timer 2 interrupt. (Note that if one pressesseveral keys at once, one will only be informed of the first one that onechecks. After finding one character the program returns from the interruptsubroutine. Also note that as one is sending 10 bits at 19200 baud, thetotal time that the transmission takes is 1/1920 ≈ 0.5ms. Thus there is noneed to worry that one will need to send one character before the previouscharacter—sent 5ms ago—is finished transmitting.)

There is one complication. As described, the program checks the keypadevery hundredth of a second and sends the value of the depressed key. This isnot normally what one wants to do. One generally wants to send a messageto the computer each time a new key is pressed.

First write a program that sends a character to the serial port every hun-dredth of a second if a key remains depressed. Next, write a small separateprogram that raises a (one bit) flag and causes the LED (at pin P3.4) to lightup whenever any key is pressed and lowers the flag and turns off the LED

18.3. THE REPORT 87

whenever no key is pressed.Finally integrate the two programs in such a way that the ADuC841 only

uploads a character if there has been a period in which no key was beingpressed.

18.3 The Report

Please submit three carefully commented programs and a brief report detail-ing the work you did. Remember that the report will be graded on complete-ness, correctness and conciseness.

18.4 Exercises

1. Why is it important to this experiment that Port 2 has pull-up resis-tors?

2. In implementing the programs for the experiment, one might want tocheck to see if a bit is not set. What command would one use to checkthis condition? Give a one or two line description of the command.

88 CHAPTER 18. INTERFACING A KEYPAD

Chapter 19

Digital to Analog Converters

19.1 A General Introduction

There are many ways of implementing a digital to analog converter. In thislab we consider a very simple way that uses peripherals available on prettynearly any microprocessor—including an ordinary 8051 or 8052. We considera “one-pin” D/A.

The basic idea is to have one pin of one’s microprocessor output a signalwhose average value is proportional to the value of the digital signal one wouldlike to output. Then one follows the pin with a low-pass filter—perhaps asimple RC circuit. The output of the low-pass filter—which performs a kindof windowed average of its input—should be proportional to the “instanta-neous” average of the input to the low-pass.

The simplest way to implement such a system using a microprocessor isto have the microprocessor output a sequence of short pulses whose averagevoltage is the desired voltage. Typically one uses the output of an I/Opin. Thus the output is either (approximately) 5V or (approximately) 0V.One starts a new pulse every TS seconds. Supposing that one one wants anoutput of Vout volts, one makes the width of the pulse (Vout/5) ∗ TS seconds.(Modulating the width of a sequence of pulses in this way is called pulsewidth modulation—PWM.) One passes this signal through a low-pass filterwhose cutoff frequency is greater than the frequency of the analog signal tobe output but is substantially smaller than the frequency of the pulses beingused.

Suppose, for example, that one wanted to output 2V for 0.1s and 3Vfor the next 0.1s. One way to do this would be to have a pulse generatorgenerate 5V pulses every 0.1ms. If for the first 100 ms the pulses were ofwidth 0.04 ms, for the next 100 ms the pulses were of width 0.06 ms, and

89

90 CHAPTER 19. DIGITAL TO ANALOG CONVERTERS

Figure 19.1: The Filtered Output

if one passed the pulses through a low-pass filter whose time constant wasconsiderably larger than 0.1ms, then the output of the filter should be justthe voltages desired. We implemented such a system using Simulink. Theoutput of the filter is given in Figure 19.1. Note that at t = 0.1s there isa transition region. The output of the filter cannot change instantaneouslyfrom one value to another—the filter is a low-pass filter. Also, note that the2V and 3V lines have a certain “thickness.” This is because the low-passfilter does not perfectly average its input. When using this type of D/A, onemust be prepared (and able) to sacrifice accuracy for ease of implementation.

19.2 The Underlying Theory

Let us examine how a simple RC low-pass filter works. If i(t) is the currentflowing through the low-pass filter, then it is easy to see that the voltagedrop across the circuit satisfies:

Ri(t) +

∫ t0 i(τ) dτ

C= vin(t).

If we set:

w(t) ≡∫ t

0i(τ) dτ,

19.3. IMPLEMENTATION 91

then we find that w(t) satisfies the equation:

Rw′(t) + w(t)/C = vin(t), w(0) = 0.

Solving this equation using the method of variation of parameters, we findthat:

w(t) =1

R

∫ t

0e−(t−y)/RCvin(y) dy

and we find that the voltage across the capacitor—the output of the filter—satisfies:

vo(t) =1

RC

∫ t

0e−(t−y)/RCvin(y) dy.

If we treat the exponential as having “ended” after three time constants,then we see that the output is the average of the input over (approximately)three time constants. Thus, if one makes the frequency of the AC parts ofthe signal large relative to the circuits time constant, and if the waveformbeing output to the DAC also changes slowly relative to the circuits timeconstant, this method ought to give an output that is proportional to thedesired voltage.

19.3 Implementation

Suppose that one sets Timer 0 to interrupt 100,000 times per second. Letus consider sets of 32 interrupts together—we consider each group of 32interrupts to be one “period” of our D/A. Let us further assume that weare interested in a 5 bit D/A. We fix the duty cycle of the output of someparticular pin—say P3.4—as follows. If the data we are given to convert, l,satisfies:

8N ≤ l < 8(N + 1), 0 ≤ N < 32

then the duty cycle is l/32 %. (As always, l is an eight bit word. Here weonly relate to the upper five bits.)

Obviously one must pick a low-pass filter for which all but the DC termsare in the high-frequency regime.

19.4 The Experiment

In this experiment, you will not need to build a low-pass filter—we will makeuse of your “built-in” low-pass filter; we will make use of your eye. UsingTimer 0 in mode 2, implement a D/A of the type described in the previoussection. Have the D/A output a sawtooth wave to the LED. Make the period

92 CHAPTER 19. DIGITAL TO ANALOG CONVERTERS

of the sawtooth wave something between 0.1 s and 2 s. This ought to causethe D/A to “blink” at you. Because of the frequency of the signal used bythe D/A, your eye should see smooth changes in the output of the LED. Youshould not notice any flicker.

19.5 The Report

Hand in a copy of the program that you wrote. Make sure that the program isfully commented. If the implementation caused you any difficulties, includecomments that detail what the difficulties were and how you overcame them.

19.6 Exercises

1. Using either the library or the Internet please determine a reasonablevalue for the “time constant” of the “average” human eye. Pleasereference your source properly.

2. The digital outputs—the I/O pins—do not really output 0V and 5V.In fact they output voltages that are generally near zero when they“ought” to be zero, and they output voltages that are generally near5V when they “ought” to be 5V. How will this affect the accuracy of aDAC built using the methods described in this chapter?

3. Please explain the differnce between resolution and accuracy.

Chapter 20

Using the Onboard DAC

20.1 General Introduction

One way of implementing a DAC is to use a single pin and to modulatethe width of the pulse output by the pin. As we saw in “Digital to AnalogConverters,” this is fairly easy to do, though it does take up quite a bit ofprocessor time, and it does not generally give a very accurate DAC.

There are many other ways of building a DAC. One of these is to use a “re-sistor chain.” When building such a DAC one takes 2N identical resistors—where N is the number of bits in the digital word passed to the converter.One connects all of the resistors in series between your Vref and ground,and one connects a switch at ground and between every two resistors. Onenumbers the switches sequentially starting with zero for the switch that isconnected to ground and ending with 2N − 1 for the switch nearest Vref .

The DAC operates in a very simple fashion. When a number is fed tothe DAC, the DAC closes the switch that corresponds to the number. Thus,if 0 is fed to the DAC, only the switch that is connected to ground closes.This forces the output to zero. When 2N − 1 is fed to the DAC, then switch2N − 1 closes, and the output of the circuit is:

2N − 1

2NVref .

See Figure 20.1 for a schematic diagram of such a DAC.

In the ADuC841 there is a 12 bit DAC of this type. Thus there are 4096identical resistors, and 4096 switches. This is not a DAC one would want tobuild by hand. For more general information about the DAC see pp. 38-40of the ADuC841 data sheets.

93

94 CHAPTER 20. USING THE ONBOARD DAC

Figure 20.1: A Schematic Description of a Resistor Chain DAC

20.2 Controlling the DAC

When referring to items that pertain to the DAC one cannot use the “headerfile” MOD52 which only defines those items on the ADuC841 that also existon an 8052. Instead one must use the “header file” MOD841 which defines allthe items related to the ADuC841—whether or not they exist on an 8052.

As with all the onboard peripherals, one controls the DAC using SFRs.The ADuC has two DACs, but they are both controlled from one register—DACCON. The following describes the function of each of the bits of DAC-CON.

• Bit 7 — controls the mode of both of the DACs. If this bit is set to0, then both DACs run as 12 bit DACs. If bit 7 is set to 1, then bothDACs run as 8 bit DACs.

20.3. THE EXPERIMENT 95

• Bit 6 — If this bit is one, then the DAC 1’s output runs from 0 to VDD.If this bit is zero, then the output runs from 0 to VREF . If one doesnot impose a value on VREF , then VREF = 2.5V .

• Bit 5 — is the same as bit 6, but for DAC 0.

• Bit 4 — controls the output of DAC 1. If it is zero, then the output ofDAC 1 is 0 V. If it is one, then the output is whatever it should be.

• Bit 3 — is the same as bit 4, but for DAC 0.

• Bit 2 — controls the synchronization for both DACs. If bit 2 is set to 1,then as soon as the lower order byte of either DAC’s input is received,that DAC’s output is updated. If one would like to update both DACssimultaneously, then one can set bit 2 to 0, update both DACS, andthen set bit 2 to 1.

• Bit 1 — determines whether or not DAC 1 is powered on. If bit 1 isone, then DAC 1 is powered on. If it is zero, then DAC 1 is poweredoff.

• Bit 0 — is the same as bit 1, but for DAC 0.

There are four other registers that one uses with the DACs. The registerDAC0L contains the low-order byte of the data. (It contains the data whenthe DACs are running in 8 bit mode.) The lower nibble of DAC0H containsthe high-order nibble of the 12 bit input to DAC 0. DAC1L and DAC1Hperform the same functions for DAC 1. Additionally, if one would like theDAC to run between 0 V and Vref , then bit 7 of ADCCON1 (MD1) must be setand bit 6 of ADCCON1 (EXT REF) must be cleared!

On the evaluation board, the output of DAC 0 appears on pin 9 of theanalog I/O connector (J1) and the output of DAC 1 appears on pin 10 of theanalog I/O connector. Both outputs are led out through unity-gain buffers.(See pp. 6 and 7 of the “ADuC8XX SAR Evaluation Board Reference Guide”for more information on this topic.)

20.3 The Experiment

Using one of the timers to control the timing, cause DAC 0 to output asawtooth wave.

96 CHAPTER 20. USING THE ONBOARD DAC

20.4 The Report

Hand in a properly commented version of the program you wrote. The com-mented code will be graded on correctness, completeness, and conciseness.

20.5 Exercises

1. Please describe a type of digital to analog converter not described inthis lab manual. Please give a reference (to a book or a web site) forthe type of D/A that you describe.

Chapter 21

Analog to Digital Converters

21.1 A General Introduction

In order to build an analog to digital converter (A/D) one must have twoparts: a sample and hold circuit and a circuit that determines the voltageheld by the sample and hold circuit.

A simple way to implement a sample and hold circuit is to have one’sinput fed to a capacitor by way of a switch. To sample the input one closesthe connection between the input and the capacitor. To hold the sampledvalue on the capacitor, one opens the switch. (See Figure 21.1.) Because ofparasitic resistances, this type of circuit will not hold the sample indefinitely;the sample must be processed reasonably quickly.

If one has a DAC, it is relatively simple to measure the “held” voltage.One can design control circuitry to change the input to the DAC and thencompare the output of the DAC to the held value. When the two signals areequal (or as nearly equal as possible) one has found the digital value that

Figure 21.1: A Schematic Description of a Sample and Hold Circuit

97

98 CHAPTER 21. ANALOG TO DIGITAL CONVERTERS

Figure 21.2: The Schematic of an Analog to Digital Converter

Figure 21.3: A Schematic Description of a Multi-channel A/D

corresponds to the analog input. This digital value is the output of the A/D.Assuming that one has the ability to tell whether the output of the DAC isgreater than the held voltage or less than the held voltage, one can use thebisection method to organize one’s search. This guarantees that one will notneed to make more comparisons than the number of bits output by the A/D.(See Figure 21.2 for a schematic of an A/D.)

Often A/D converters allow one to convert signals on several channels.One way of building such an A/D is to have the input to the sample andhold circuit be the output of a multiplexer. The user chooses which of theinputs to feed to the A/D, and in this way chooses the channel to be sampled.(See Figure 21.3.) One must be careful to give the sample and hold circuitryenough time to “dump” the previous channel’s value before holding the newvalue. This problem is discussed on p. 27 of the datasheets.

21.2 Implementation

The A/D provided with the ADuC841 is described on pp. 23-31 of thedatasheets. Note that the A/D can only accept inputs between 0V andVREF—which is generally 2.5 V. The A/D is controlled by 3 SFR’s—ADCCON1,ADCCON2, and ADCCON3. The values acquired are stored in two SFR’s—ADCDATAH and ADCDATAL. We describe these registers now.

21.2. IMPLEMENTATION 99

21.2.1 ADCCON1

This register is not bit-addressable. This register’s function is described onp. 24 of the datasheets.

• Bit 7 determines whether or not the A/D is turned on. Bit 7 must beset to power up the A/D. When cleared the A/D is powered down.

• Bit 6 is set to use an external reference voltage. It must be cleared touse the internal reference voltage. Note that by default this bit is set.

• Bits 5 and 4 control the clock used for the A/D. The clock should bebetween 400KHz and 8.38 MHz. The faster the clock is, the faster theconversion is done. As our crystal is an 11.0592 MHz crystal, we mustdivide the clock by 2. This corresponds to bits 4 and 5 being one. Seep. 24 for the other settings.

• Bits 3 and 2 control the number of A/D clock cycles used to acquirethe signal. It is recommended that one use three or more cycles. Thiscorresponds to bit 3 being one and bit 2 being zero. The total time thatthe A/D takes to convert a value is 15 A/D clock cycles for the conver-sion, one cycle for synchronization, and the selected number of cyclesfor acquisition—in our case 3 cycles. In our case the total acquisitiontime is:

taq =2

1105920019 = 3.44µs.

• Bit 1 is the Timer 2 conversion bit. If it is set, then every time Timer2 overflows, the A/D starts a conversion.

• Bit 0 is the external trigger enable bit. When set it lets the user triggeran A/D conversion externally.

21.2.2 ADCCON2

This register is bit addressable.

• Bit 7, ADCI is the ADC interrupt bit. It is set by the hardware at theend of an A/D conversion and at the end of a DMA block conversion.It is cleared by hardware when the PC vectors to the A/D ISR.

• Bit 6, DMA, is the DMA enable bit. It is set to allow a DMA transfer.Otherwise it is cleared.

100 CHAPTER 21. ANALOG TO DIGITAL CONVERTERS

• Bit 5, CCONV, is the continuous conversion bit. If this bit is set, theA/D starts a new conversion as each old conversion finishes.

• Bit 4, SCONV, initiates a single conversion when it is set. The bit isreset by the processor when the conversion is finished.

• Bits 3 - 0 are used to select which channel to sample from. Bit 3 isthe high order bit, and bit 0 is the low order bit. The A/D has eight“regular” channels. The first channel is channel zero, and the last ischannel seven. The A/D has a ninth channel, channel 8, that reads aninternal temperature sensor. (This sensor is supposed to output 700 mVwhen the temperature is 25oC and the voltage decreases approximately1.4 mV per degree Celsius.) Using channels 9-12 causes the A/D tosample various voltages produced by the ADuC841. Finally, in theDMA mode the STOP instruction is filling all the channel bits withones.

21.2.3 ADCCON3

This register is not bit addressable. Bit 7, BUSY, of ADCCON3 is set during anA/D conversion or a calibration cycle. Otherwise it is zero. The rest of thebits are either reserved or are used in the calibration process. We will notmake use of these bits.

21.2.4 ADCDATA

The data that the A/D acquires is stored in two registers. The least signif-icant eight bits are stored in ADCDATAL. The most significant four bits arestored in the least significant four bits of the register ADCDATAH. The mostsignificant four bits of that register contain the A/D channel from which thedata was acquired.

21.2.5 The A/D Interrupt

When the A/D finishes converting a sample, it asserts an interrupt. In orderto enable the interrupt, the bit EADC must be set. Upon receiving an A/Dinterrupt, the processor vectors to 0033h.

21.2.6 The Inputs

The inputs to the A/D are shared with the inputs to Port 1. Port 1 is an inputonly port, and its default setting has it configured to accept analog input.

21.3. THE EXPERIMENT 101

Thus, no settings need to be changed to use the A/D. On the evaluationboard, the inputs to channels 0 and 1 are from pins 1 and 2 of J1—theanalog I/O connector. (See p. 7 of the “ADuC8XX SAR Evaluation BoardReference Guide.”) Note that the evaluation board has unity-gain buffersfor channels 0 and 1.

21.3 The Experiment

In this experiment, we compare three ways of operating the A/D. In each ofthe following programs, the value read from the A/D—from channel 0—mustbe output to DAC0. Write programs to do the following:

• Have the microprocessor use the Timer 2 interrupt to run the A/D.Use the single conversion mode, and trigger a conversion on channel 0from the ISR using SCONV.

• Adjust the previous program so that the Timer 2 interrupt is not used,but Timer 2 still sets the conversion rate. (Use bit 1 of ADCCON1.)

• Adjust the previous program to use the continuous conversion mode.Remove all references to Timer 2.

For each program, determine the first frequency for which the output ofthe D/A looks (approximately) constant when the input to the A/D is asine wave. These frequencies give the sampling rate used in each program.Include the frequencies in the comments that you write for each program.

Note that in continuous conversion mode the ADuC841 samples as oftenas it can whether or not the samples were ever read. When a new samplecomes in, it overwrites the old values stored in ADCDATAH/L.

Before downloading the program to the ADuC841, use the debugger totest the program. You will not be able to test the system by inputting asinewave, but you can test whether or not the A/D and D/A are workingproperly. To test the A/D and the D/A, go to the Peripherals tab and checkboth the A/D converter and the D/A converter. When you run the programin the debugger, you will be able to see the inputs to the A/D and the outputsof D/A. By typing a number in the AIN0 box of Analog/Digital Converterdialog box and then moving the cursor to another box, you will be able tochange the value seen by the zeroth input of the A/D. If your program isworking correctly this should be reflected in the value you see at the outputof the output of DAC0.

102 CHAPTER 21. ANALOG TO DIGITAL CONVERTERS

21.4 The Report

Hand in a copy of the programs that you wrote. Make sure that the programsare fully commented.

21.5 A Second Experiment

In this experiment we measure the temperature of the ADuC841 chip byreading its internal temperature sensor. Set the ADC to sample from its ninthchannel—channel number eight. Set the Timer 2 conversion bit and causeTimer 2 to overflow as infrequently as possible. Cause the microprocessor tomove the data read by the ADC to the DAC0 each time an ADC interruptoccurs. Run the DAC in 12 bit mode. (You may want to toggle the onboardLED from the ADC ISR. This will give you an indication of whether or notthe program is running.) When sampling from the temperature sensor, it isbest to set the divide ratio to 32—which means that bits 4 and 5 of ADCCON1should be set to zero. Additionally, bits 2 and 3 of ADCCON1 should both beset to one so that the 4 ADC clock cycles are used when aquiring the signal.

Once the program is running properly and you are looking at the outputof DAC0 on a ’scope please gently heat or cool the ADuC841 and watchthe ’scope trace. If you cool the chip you should the trace rise slightly. Ifyou heat the chip you should see the trace fall a bit. You should be able toobserve the changes made by placing a finger on the microcontroller if youset the ’scope to measure the average value of the signal that is appearingon its screen.

21.6 The Second Report

Please submit a fully commented program as your report for this experiment.

21.7 Exercises

1. One way to test the sampling speed of something that transfers a sam-ple from its A/D to a D/A is as follows. Connect a sine wave generatorto the input of the A/D. Connect a ’scope to the output of the D/A. Setthe frequency of the sine wave to zero initially and gradually increasethe frequency of the sine wave. The first frequency greater than zerofor which one sees a constant output is the sampling frequency of theA/D. Explain why this is so.

21.7. EXERCISES 103

2. One mode that we do not discuss is the DMA mode. Read the infor-mation in the ADuC841 data sheets and give a brief description of theDMA mode. (The description should not be more than five lines long.)

3. Using the library or the world wide web, please find a description of theFlash A/D. In your own words, please describe how this A/D works.Please describe the advangages and the disadvantages of the Flash A/D.

4. Please find out what the start-up values (the values held immediatelyafter reseting the microprocessor) of the registers ADCCON1 and AD-CCON2 are. (You may find the “Quick Reference Guide” helpful here.)

104 CHAPTER 21. ANALOG TO DIGITAL CONVERTERS

Chapter 22

Designing a Low-pass Filter

22.1 A General Introduction

To implement a low-pass filter using a microprocessor, one must use the A/Dfor input, the DAC for output, and one timer to fix the sampling period. Aswe have used all of these peripherals, all that is really left is to choose thesample speed and the filter coefficients.

The input and output voltages of the simplest analog low-pass (RC) filtersatisfy:

τv′out(t) + vout(t) = vin(t).

If one samples every T seconds and one approximates the derivative of theoutput at time nT by:

v′out(nT ) ≈ vout(nT )− vout((n− 1)T )

T

one can then approximate the differential equation by a difference equation.

Let v(n) ≈ vout(nT ). Approximating vout(t) by v(n), One finds that:

v(n) =τ

τ + Tv(n− 1) +

T

T + τvin(nT ).

22.2 Stability

It is easy to show that this filter is bounded input-bounded output (BIBO)stable. Assume that |vin(nT )| ≤M , and let the initial condition on the filterbe that v(0) = 0. We proceed to prove stability by mathematical induction.

105

106 CHAPTER 22. DESIGNING A LOW-PASS FILTER

First note that |v(0)| ≤ M . Next we show that if |v(n − 1)| ≤ M , then|v(n)| ≤M . To show this note that if |v(n− 1)| < M , then:

|v(n)| =∣∣∣∣ τ

τ + Tv(n− 1) +

T

T + τvin(nT )

∣∣∣∣≤ τ

τ + T|v(n− 1)|+ T

T + τ|vin(nT )|

≤(

τ

τ + T+

T

T + τ

)M

= M.

Thus, by mathematical induction, we find that if the input to the filter isbounded in absolute value by M , so is the output.

22.3 Performance

Now let us consider the extent to which the behavior of the digital filtermimics the behavior of the analog filter on which it is modeled. To this end,we consider the step response of both filters. As we will see, the two filtersbehave similarly. Interestingly enough, it is possible to analyze the two filtersusing similar techniques.

22.3.1 The Analog Filter

Suppose that the input is a constant—that vin(t) = A, and that at t = 0 wehave vout(t) = 0. It is clear that vout(t) = A is a solution of the inhomogeneousdifferential equation:

τv′out(t) + vout(t) = A.

The general solution of the homogeneous differential equation is vout(t) =Ce−t/τ . Thus, the general solution of the inhomogeneous equation is:

vout(t) = A+ Ce−t/τ .

Imposing the initial condition—that vout(0) = 0—we find that the output ofthe low-pass filter when the input is a step is:

vout(t) = A(1− e−t/τ ).

This solution starts at 0 and increases monotonically to A.

22.3. PERFORMANCE 107

22.3.2 The Digital Filter

Let us consider the digital filter now. Suppose once again that vin(t) = A.Then the input to the digital filter is the “all A’s sequence.” It is easy to seethat a solution of the inhomogeneous recurrence relation is v(n) = A.

The homogeneous equation is:

v(n) =τ

τ + Tv(n− 1).

It is clear that the general solution to this equation is:

v(n) = C(

τ

τ + T

)n.

We find that the general solution to the inhomogeneous equation is:

v(n) = A+ C(

τ

τ + T

)n.

Finally, enforcing the initial condition we find that the solution to the recur-rence relation with initial condition v(n) = 0 is:

v(n) = A(

1−(

τ

τ + T

)n).

Just as in the case of the analog filter, we find that we have a solution thatstarts from zero and approaches A monotonically.

Actually, one can say a bit more. Suppose that one is sampling quickly—that T << τ . Writing (τ/(T + τ))n as:(

τ

τ + T

)n= en ln(τ/(τ+T ))

and noting that as ln(1− x) ≈ −x, |x| << 1 we can say that:

ln(

τ

τ + T

)= ln

(1− T

τ + T

)T<<τ≈ − T

τ + T≈ T

τ,

we find that the solution is approximately:

v(n) ≈ A(1− e−nT/τ ) = vout(nT ).

That is, as T gets smaller and smaller the output of the digital filter ap-proaches the samples of the output of the analog filter.

108 CHAPTER 22. DESIGNING A LOW-PASS FILTER

22.4 The Experiment

Design and implement a digital filter for which T = 0.5ms and for whichτ = 0.5ms. You may take any reasonable shortcuts, but the filter mustproduce acceptable looking output. In particular, you may run the DAC in8-bit mode if you would like.

Note that you may need to shift the bits around. The 8051 assemblylanguage has several shift commands—RR, RL, RRC, and RLC. See pp. 49-50 ofthe 8051 Programmer’s Guide for more information about these commands.Also note that division by two can be accomplished by right shifting a numberby 1 bit.

22.5 The Report

Submit a copy of the program that you wrote. Make sure that the programis fully commented.

22.6 Exercises

1. Solve the differential equation satisfied by the low-pass filter for τ =T = 0.5 and vin(t) is a unit step function.

2. Please give a two sentence description of the RLC command.

Chapter 23

Implementing a SimpleOscilloscope

23.1 A General Introduction

The goal of this experiment is to have the ADuC841 output two analogsignals—on its two DACs—that will drive an oscilloscope in x-y mode toplot the signal being input to the chip’s A/D.

In order to drive the scope in such a way that one will be able to see thesignal, one must make use of a trigger. One must force the output to startfrom the same place many times—otherwise one will see a very messy signal.More than just starting at the same point, it is important that the outputbe consistently rising or falling at that point.

One must set two parameters in order for the triggering to be effective.One must set the trigger level and the trigger slope.

23.2 Implementation

To implement the ’scope-signal generating program one must do severalthings.

1. One must set up the A/D to sample at an “appropriate” rate—this willinvolve setting up the A/D and setting up a timer. (As we have seen,Timer 2 is probably the best timer to use.)

2. One must check to see if the value read by the A/D converter crossedthe trigger level in the correct direction.

109

110 CHAPTER 23. IMPLEMENTING A SIMPLE OSCILLOSCOPE

3. If it did, then one must set a flag to tell the processor that a triggerevent has occurred.

4. If the flag is set, then one must output two signals. On one channel,one must output the values that one has read in from the A/D. On theother channel one must output a signal that increases linearly—onemust output the time-base.

5. When the time-base has reached its maximum value—when one hasswept the “screen” once, one must de-assert the “triggered” flag andwait for the next trigger event.

23.3 The Experiment

Write a program that takes input from the A/D and outputs signals to theDAC that cause a ’scope in x-y mode to give output that looks like the outputof a ’scope in “normal” mode.

You may find the command SUBB helpful. It subtracts values (with carry)and sets the carry bit if one needs to carry. (The full description of thisinstruction is located on p. 52 of the 8051 Programmer’s Guide.) This canbe used to see if one number is less than another—something that you willneed to check to determine whether or not a trigger event has occurred.

23.4 The Report

Submit a copy of the program that you wrote. Make sure that the programis fully commented.

23.5 Exercises

1. In §23.3 one can use the CJNE command rather than SUBB. Explain howto do this.

2. Suppose that one inputs a sine wave into an oscilloscope that triggersevery time the input to the ’scope passes through zero regardless ofwhether the signal is rising or falling at that point. What will theoutput of the ’scope look like? Please make a simple sketch of theoutput.

23.5. EXERCISES 111

3. Suppose that one inputs a sine wave whose amplitude is 0.5 V into anoscilloscope that triggers every time the input to the ’scope hits 1 Vand is increasing. What will the output of the ’scope look like?

112 CHAPTER 23. IMPLEMENTING A SIMPLE OSCILLOSCOPE

Chapter 24

Implementing a SimpleCapacitance Meter

24.1 A General Introduction

The goal of this experiment is to have the ADuC841 output the capacitance ofa capacitor to the ADuC841’s UART. This goal is accomplished by measuringthe 0 to 50% rise time of the capacitor under test as part of an RC low-passfilter with a fixed resistance value.

Let R be the resistance of the resistor, let C be the capacitance of thecapacitor under test, let V be the voltage impressed upon the low-pass filterat time t = 0, and let τr be the time it takes the capacitor’s voltage to reachhalf of its final value. As the voltage on the capacitor as a function of timeis easily seen to be:

VC(t) = V (1− e−t/(RC)),

and as the final voltage on the capacitor is V , it is clear that τr satisfies:

V/2 = V (1− e−τr/(RC)).

Solving this equation for C, we find that:

C =τr

R ln(2).

Thus, if we can measure τr we can easily find the capacitance.

In order to upload the value of the capacitance, it will be necessary toupload a user generated string via the UART. This can be done using thetechnique described in §16.2.2.

113

114CHAPTER 24. IMPLEMENTING A SIMPLE CAPACITANCEMETER

24.2 Implementation

To implement this simple meter, one connects the output of DAC0 to aresistor, one connects the second side of the resistor to a capacitor and tochannel 0 of the A/D, and one connects the second side of the capacitor toground. Upon being told to start a measurement—by having the user sendthe ASCII for the letter ’m’ to the ADuC841’s UART, for example—theADuC841 sets the voltage at DAC0 to 2.5V. At the same time, the ADuC841starts sampling the input to channel 0 of the A/D. (A simple way to do thisis to have the A/D sample every overflow of Timer 2. Then one can start orstop the A/D by setting or clearing TR2.) In the A/D interrupt subroutine(ISR), one can compare the values received to the value that corresponds to1.25V. If one keeps track of how many times one enters the A/D ISR beforehalf of the voltage is reached, then one knows how long the capacitor tookto reach half of its final value. That is, one finds τr. By carefully choosingthe sampling period and the resistor value, one can make the calculation ofthe capacitance quite simple.

24.3 The Experiment

Write a program that calculates the capacitance of a capacitor and uploadsthe capacitance via the UART. Have the program start a measurement eachtime an ’m’ is sent to the ADuC841 via the UART. Use a 1 KΩ resistor inthe RC low-pass filter.

24.4 The Report

Hand in a copy of the program that you wrote. Make sure that the programis fully commented.

24.5 Exercises

1. What formula does one find for the capacitance of the capacitor undertest when one knows the time it took for the capacitor to reach 90% ofits final voltage and one knows the resistance of the resistor?

2. Suppose that rather than trying to measure the capacitance of a capac-itor one were trying to measure the inductance of an inductor. Whatchanges would one have to make to the method described? (One doesnot need to change very much.)

Chapter 25

Generating PN Sequences

25.1 Introduction

One of the most important signals used in communications is the pseudo-random or psuedo-noise (PN) sequence. Such sequences are nearly spectrallywhite at reasonably low frequencies and can be—and are—used as determin-istic white noise. PN sequences are used in direct sequence spread spectrum(DSSS) systems. PN sequences can also be used to examine the frequencyresponse of filters.

Let yn be a either 0 or 1. Let all operations be operations over the integersmod 2, Z2. (That is, let: 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, 1 + 1 = 0, 0 · 0 = 0,0 · 1 = 0, 1 · 0 = 0, and finally, 1 · 1 = 1.) Let yn satisfy an equation of theform:

yn = a1yn−1 + · · ·+ aNyn−N

where the elements of the sequence and the coefficients are all elements ofZ2. One can show that for appropriate choices of coefficients, the sequencesgenerated are PN sequences. Lists of such coefficients are easily availableboth in print and on the WWW.

25.2 Some Facts about PN Sequences

25.2.1 Length

Because there are only 2N possible values of the previous states yn−1, . . . , ynN,

and because the next set of “previous states” depends only on the current setof “previous states,” the sequence ynmust become periodic. The maximumperiod is not greater than the number of previous states—2N . In fact, itcannot be greater than 2N − 1. This is so because one of the states is the all

115

116 CHAPTER 25. GENERATING PN SEQUENCES

zero state and from that state the sequence looks like . . . , 0, 0, 0, . . .. Thus,the all zero state must be avoided. Thus, the maximal length sequence (MLS)has period 2N−1. It can be shown that maximal length sequences have someof the properties of white noise. Maximal length sequences are PN sequences.

25.2.2 Ones and Zeros

Given a maximal length sequence, what can we say about the number of onesin the sequence and the number of zeros in the sequence? Because the set ofprevious states goes through all 2N −1 possibilities save the all zero previousstate, we know that every state must be zero or one almost the same numberof times. If the all zero state were included, one would have each state beingzero or one the same number of times. Because the all zeros state is notincluded, it will be one one more time than it will be zero.

25.2.3 The Autocorrelation

One can show that the autocorrelation of the PN sequence is nearly a deltafunction. This implies that the spectrum of the sequence is nearly constant.In this experiment, we will see to what extent this is true.

25.3 Implementation Hints

25.3.1 Shift Registers

The standard way to implement a PN sequence generator is to use a shiftregister. It is easy to simulate a shift register on an 8051-type microprocessor(and on most other microprocessors as well). The 8051 has commands forshifting all the bits in the accumulator either right or left. To shift right,one uses the command RR, and to shift left one uses the command RL. Thesecommands rotate the bits in the register. When one uses RR the bit n movesto bit n−1 and bit 0 moves to bit 7. When using RL bit n moves to bit n+ 1and bit 7 moves to zero.

25.3.2 Logical Operations

Though the 8051 family of microprocessors includes several commands forperforming boolean operations on bits, it is sometimes easier to performseveral tests in order to determine the sum of several bits. For example, ifone would like to perform an operation based on the value of a+ b, a, b ∈ Z2,

25.4. THE EXPERIMENT 117

it is fairly simple to use a sequence of JB and JNB commands to determinewhat operation to perform. Sometimes this style of programming leads tosimpler or shorter code than using the 8051 command for logical operations.

25.4 The Experiment

Using the ADuC841, generate the PN sequence that satisfies the equation:

yn = yn−3 + yn−5.

Make use of Timer 1 (in mode 2) to cause 1 bit to be output every 10µs.Write your program in such a way that it is possible to gate the output

using the button connected to pin 3.2. Set up the program so that by defaultno output is produced. If one pushes the button connected to pin 3.2, thenoutput should be produced. Pushing the button again should stop the outputfrom being produced. If output is not being produced, pushing the buttoncauses it to be produced. If output is being produced, pushing the buttoncauses it to stop being produced.

Using an oscilloscope with an FFT option examine the spectrum of theoutput. What is the fundamental frequency of the signal?

25.5 The Report

Please include a fully commented program. Additionally, please print outthe FFT of the output of the final program. Explain how the FFT agrees(or disagrees) with the theory presented in this chapter.

25.6 Exercises

1. Let yn satisfy:

yn = yn−1 + yn−2, y−1 = 1, y−2 = 1.

Please calculate and tabulate y0 through y10. Is yn a maximal lengthsequence? How many ones are there in each period, and how manyzeros are there in each period?

2. Using the WWW find an equation that generates an MLS with period29 − 1 = 511.

118 CHAPTER 25. GENERATING PN SEQUENCES

3. Suppose that BLACK and GREEN are bit variables. Is the command XRL

BLACK, GREEN an acceptable command? How about the command XRL

C, GREEN? What is the meaning of C in the second command? Youmay (and are encouraged to) use the “8051 Programmer’s Guide” toanswer this question.

4. Write a sequence of 8051 instructions that calculates the exclusive orof GREEN and BLACK as defined in the previous question.

Chapter 26

A Simple Switching Circuit

26.1 Introduction

One way to supply a reduced voltage to a load, RL, is to use a simple switch-ing circuit like that of Figure 26.1. The p-channel enhancement MOSFETin the figure acts as a switch, and whenever the output, Vo, drops below thedesired voltage (which must be less than VDD), the microprocessor provides a0V signal to the gate to allow the MOSFET to conduct and charge the capac-itor in the circuit. If Vo is at or above the desired voltage, the microprocessoroutputs VDD to the gate and keeps the MOSFET from conducting.

26.2 The Experiment

Build the circuit of Figure 26.2. (You may leave out RL if you wish. Thenthe two 10K resistors act as both the load and as a measurement circuit.)The circuit has four connections to the evaluation board.

• The MOSFET’s gate input is connected to P3.4.

• The MOSFET’s source and body are tied to one of the 5V outputs ofthe board.

• The load resistor, one of the 10K resistors, and the capacitor are tiedto one of the board’s ground connections.

• The point between the two 10K resistors is tied to the ADC0 input onthe board.

The reason for including the voltage divider is that the ADuC841’s ADCtakes inputs between 0 and 2.5V while the voltage converter’s output can beas high as 5V.

119

120 CHAPTER 26. A SIMPLE SWITCHING CIRCUIT

Figure 26.1: A Schematic diagram of a simple voltage reducing power supply.

Write a program that samples channel zero of the ADC continuously andcompares the voltage with a (value that corresponds to a) desired voltage.If the voltage read is greater than or equal to the desired voltage, keep theMOSFET from conducting by making its gate voltage, the output of P3.4,high. If the voltage read is less than the desired voltage, make the MOSFETconduct by making its gate voltage (aproximately) 0V.

You may choose to use only the upper four bits of the ADC’s output,the bits containend in ADCDATAH, to measure Vo. Doing this gives you 16possible voltage ranges for the output voltage. Your program must comparethe ADC’s output with the desired output – which will also be given as anumber between 000H and 00FH.

Your program must allow the user to change the desired value of the out-put by using the UART. Set the UART’s baud rate to 19,200 characters/sec.Anytime the UART receives a ’+’, have the output voltage increase by oneunit. When the UART receives a ’-’, have the output decrease by one unit.Make sure that the user cannot change the desired voltage to a value thatwill lead to unanticipated output values.

26.2. THE EXPERIMENT 121

Figure 26.2: The circuit diagram of the simple voltage reducing power supply.

122 CHAPTER 26. A SIMPLE SWITCHING CIRCUIT

Chapter 27

Making a Simple Plotter

27.1 Introduction

The ADuc841 is designed to allow one to make measurements. After makingmeasurements, one must present the measurements to the user in a way thathe will find useful. One standard way of representing a set of measurementsis as a graph. In this chapter, we will “teach” the ADuC841 how to plot agraph on a host computer’s screen.

27.2 The Main Idea

When trying to output a graph using the ADuC841’s UART, we cannot hopeto make a very pretty graph. In this lab, we will plot points on our graph byhaving the computer place an asterisk (an *) wherever a point should appear.

One of the challenges of plotting a graph with a microcontroller is thatthe microcontroller outputs “rows” of text via it UART, and we want toplace points in specific columns. The microcontroller works line by line, andwe would normally work column by column.

Suppose that one has a set of 4 bit measurements taken at equally spacedintervals and that one would like to plot the measurements. As there are onlyfour bits in each measurement, we need sixteen rows in our graph. If the listis stored from the measurement that should appear first to the measurementthat should appear last, we can have the microcontroller produce our plot asfollows.

• Have the microcontroller start plotting the graph from the graph’s high-est row – in our example from the row in which items whose value isfifteen should go.

123

124 CHAPTER 27. MAKING A SIMPLE PLOTTER

Input Output0.0 00.25 10.5 20.75 31 2

Table 27.1: Some input-output pairs for our hypothetical system.

• Have the microcontroller read the measurements that have been storedone after the other starting from the measurement that should appearin the first column.

• Each time the microcontroller examines a measurement, it checks tosee whether the measurement is such that an asterisk should appear inthe current column and row. If an asterisk should appear, the micro-controller sends the ASCII for an asterisk to the computer. If not, themicrocontroller send the ASCII for a blank space.

• When the microcontroller gets to the last element in a row, it outputsa carriage return and a line feed and starts the above process for thenext row.

• The microcontroller continues plotting until it finishes all the rows.

27.3 An Example

Let us consider a simple example of how this could work. Suppose that wehave five measurements of the output of a system. The measurements aregiven in Table 27.1.

If we were to have the ADuC841 plot this graph, it would need to usefive columns and four rows. In plotting the graph, it would start by goingfrom element to element and checking to see which elements are equal to thelargest value, to three. It would output an asterisk wherever a three occuredand a space elsewhere. After scanning the data once for threes, it wouldhave output the line * . After scanning the data again for all occurencesof the number two, it would have output * *. After scanning for ones,it would have output * . Finally, after scanning for zeros it would haveoutput * .

27.4. IMPLEMENTING THE PLOTTER 125

At the end of the process, the user would see the following four lines onhis screen.

*

* *

*

*

This is a reasonable graphical representation of the data. In the next section,we discuss some implementation issues.

27.4 Implementing the Plotter

27.4.1 Storing the Values to Be Plotted

Assuming that the values to be plotted might have to change (as they wouldif they are values that we measure in real-time), we cannot store the mea-surements in the code segment. The data must be stored in the data segmentin an array. Recall that one can read from or write to array using indirectaddressing. One can use registers R0 or or R1 to point to the current ele-ment in an array and to read from the array or write to the array using theMOV @R0, --- and the MOV ---, @R0 commands.

27.4.2 Plotting the Points

One way of thinking of the plotter is as a routine that prints a long stringand that chooses the elements of the string on the fly. Thus, most of our hardwork is going to be connecting to setting up the transmit interrupt to printthe string. Assuming that the name of the array (in DSEG) in which thearray is stored is MEASUREMENTS, before starting to print the string, onepoints R0 (or R1) at MEASUREMENTS and one inializes a row counter tobe equal to the highest row and a column counter to be 0 – to be at the veryfirst column. When one is ready to plot, one asserts the transmit interrupt.If the transmit interrupt is handled correctly, one will shortly have a graph.

Because plotting the graph is somewhat complicated, one should not placethe routines in the interrupt subroutine (ISR). It is much better practice toraise a flag in the ISR and do all non-time-critical processing outside theISR. Whenever the transmit interrupt is asserted, the microcontroller tries tooutput the next character in the graph. In the routine that the main programcalls each time a transmit interrupt is detected, the microcontroler checks thevalue of the current element of the array it is plotting. If that element is equal

126 CHAPTER 27. MAKING A SIMPLE PLOTTER

to the value represented by the current row, then the microcontroller outputsthe ASCII for ’*’. If not, it outputs the ASCII for ’ ’. If the end of a row hasbeen reached, then the microcontroller must output a carriage return and aline feed. Of course, the microcontroller must also make sure to update thecurrent column, row, and data element being examined.

27.5 The Experiment

Write a program that plots a triangle wave each time the letter ’P’ is receivedby the ADuC841. The plot must have sixty-four columns and sixteen rows,and the plotting routine must be written with an eye towards being oneelement of a larger program.

Chapter 28

Building and Testing aDynamic Logic Inverter

28.1 Introduction

Sometimes when one builds and tests a circuit it seems like one needs severalextra pairs of hands. It is possible to use a microcontroller and its UARTin place of those extra hands. In this lab, you will write a program for theADuC841 that will allow you test the circuit of Figure 28.1 in a sensiblefashion. Then you will build the circuit, connect it to the microcontroller,and test the circuit.

28.2 A Brief Explanation of the Circuit

The circuit of Figure 28.1 is a “dynamic logic inverter.” When the clocksignal, φ, to the circuit is low, the lower NMOS transistor is cutoff and themiddle transistor has no path to ground – it is just “hanging off” of thePMOS transistor. The capacitor, on the other hand, charges up to VDD

while the clock is high.When the clock is low, the circuit has no connection to VDD but the

middle NMOS transistor is connected to ground through the lower NMOStransistor. Immediately after the transistion from clock-low to clock-high,the capacitor is charged to VDD. If the input to the upper NMOS transistoris approximately zero volts, then that transistor is cutoff and the capacitorcannot discharge. Thus, the output remains VDD. (The voltage will slowlydecay because of leakage currents, but as long as one is clocking the circuitat a reasonable rate, this is not a serious concern in our case.) If the inputto the upper NMOS is VDD, then both NMOS transistors conduct, and the

127

128CHAPTER 28. BUILDING AND TESTING ADYNAMIC LOGIC INVERTER

Figure 28.1: A dynamic logic inverter. The circled number represent the pinsof the SCL4007UBE.

capacitor discharges through them. In this case, after a little while thevoltage on the capacitor fall to 0 V. Taking the voltage on the capacitor asthe output, one finds that shortly after the clock goes high, the output is theinverse of the input. If the input is high, the output is low, and if the inputis low, the output is high.

28.3 The Experiment

Write a program that uses the ADuC841’s serial port and the I/O pins toallow the user to toggle the dynamic logic inverter’s clock and to set theinput to the inverter to be either 0 V or 5 V. Let the output to the clock beP3.4 and the output to the inverter’s input be P3.5. Additionally, wheneverthe clock’s value is toggled or the inputs value is set output a very shortpulse to P3.6. Have the program toggle the clock everytime a capital C isreceived by the UART, have the program output 0 V to the input whenever acapital Z is received, and have the program output 5 V to the input whenever

28.3. THE EXPERIMENT 129

a capital O is received. Test the program thoroughly using the simultor tomake sure that it works, and then download the program to the evaluationkit and make sure that the program does what it is supposed to.

When the program works properly, build the circuit of 28.1. ConnectVDD to the evaluation kit’s DVDD, the circuits ground the the evaluation kit’sDGND, P3.4’s output to the gates of the transistors to which the clock is fed,and connect P3.5’s output to the gate of the transistor to which the signal isinput. (If you are using the 4007, these are pins six and three, respectively.)Connect a ’scope probe to P3.6 and to the capacitor. Use the probe connectedto P3.6 to trigger the ’scope and enjoy testing the dynamic logic inverter.

130CHAPTER 28. BUILDING AND TESTING ADYNAMIC LOGIC INVERTER

Chapter 29

Power Management

29.1 Introduction

The power required by a CMOS circuit is strongly influenced by the rate atwhich the circuit changes state. To understand why, consider the schematicdiagram of a CMOS gate given in Figure 29.1. The gate has two sub-units – apull-up network (PUN) and a pull-down network (PDN). At any given time,one network should behave like a short circuit and the other should behavelike an open circuit. The inputs to the system determine which network isactive – behaves like a short circuit – at any given time, and in that way, theinputs determine the voltage at the output.

The beauty of CMOS circuits is that, in principle, they dissipate almostno power. As there is never (or almost never) a connection from VDD toground, (almost) no current should flow in the circiut. Anyone who has everput his hand near the a Pentium processor knows that in fact such processorsdissipate quite a lot of power. Why is power being dissipated?

One way that power is dissipated in CMOS circuits is in the chargingand discharging of parasitic capacitors. Each time the circuit changes state,parasitic capacitors are charged or discharged, and energy is wasted. If onlywe could stop the circuit from changing state, we could save a lot of power.Unfortunately a circuit that never changes state is a circuit that is not doinganything; we cannot stop the circuit from changing state.

The rate at which circuits are changing state is related to the rate atwhich the circuits dissipate energy. If we can causes the circuits to changestate as little as possible, we should be able to reduce the power dissipatedby the CMOS circuits.

In the case of clocked circuits like microprocessors and micro-controllers,one way to reduce the number of times the internal circuits change states is

131

132 CHAPTER 29. POWER MANAGEMENT

Figure 29.1: A Schematic diagram of a CMOS gate.

to change the clock speed of the processor. In this lab, we will learn how toadjust the internal clock speed of the ADuC841, and we will measure the thepower used by the processor at two different clock speeds. We will see thatwhen we lower the clock speed, we reduce the power used by the processor.

29.2 Power Management in the ADuC841

On the development kit we are using, the crystal that supplies the ADuC841’sclock is a 11.0592 MHz crystal. The ADuC841’s default is to use the crystalfrequency as the internal clock frequency. It is, however, possible to causethe ADuC841 to divide this clock down and to use the lower frequency clockas the internal clock.

The PLLCON SFR, located at 0D7H in the internal memory, can be usedto control the clock speed. The lowest three bits of this register serve to

29.3. THE EXPERIMENT 133

control the amount by which the clock is divided down. Considering thesethree bits, denoted by CD2, CD1, and CD0 as one three bit word, CD = [CD2

CD1 CD0], the ADuC841 divides the internal clock by 2CD. If all three bitsare set to zero, then the ADuC841 does not divide the external clock at alland the micro-controller runs at a clockrate of 11.0592 MHz. If CD0 is set andthe two higher order bits are cleared, then the clock rate will be 5.5296 MHz.By default, all three bits are cleared – and that is why the clockrate that wehave seen has always been 11.0592 MHz. Note that PLLCON is an ADuC841-specific SFR. In order to use it, you must include the appropriate header file.Also, the SFR is not bit addressable. The datasheet for the ADuC841 statesthat top five bits should always have zeros written to them. Thus, whenmoving values into PLLCON, one should always move bytes of the form 0 0 0

0 0 CD2 CD1 CD0.How can one make use of the ability to change the internal clock speed

in order to reduce the power used by the micro-controller? If you are writinga program and you know that the program does not do very much, you canchoose to divide the clock down and, in this way, to reduce the power usedby the processor.

29.3 The Experiment

In this experiment, you must write a program that causes the ADuC841 toecho characters it received via its UART. Because this does not require theADuC841 to do much work, there is no reason to have the ADuC841 work atfull speed. However, in order to make it possible to see the changes we havespoken about, you will write a program that can run the ADuC841 either atits full clock speed or at half the normal clock speed.

Write a program that causes the ADuC841 to echo characters receivedvia its UART. Have the ADuC841 start by working at its full clock speed.Set up the UART to run at 57,600 baud, use Timer 1 to set the baudrate,and set SMOD to zero.

The echoing function must work for all the character except for the ’ !’and the ’)’. When the character ’ !’ (sometimes known as shift-1) is receivedhave the program set CD0 and make sure to change the value with whichTimer 1 is reloaded in such a way that even after the change in internalclock frequency the UART still runs at 57,600 baud. When the character ’)’(sometimes known as shift-0) is received, have the program clear CD0 andmake sure to change the value with which Timer 1 is reloaded in such a waythat even after the change the UART still runs at 57,600 baud.

When using this simple program, the standard user should not be able to

134 CHAPTER 29. POWER MANAGEMENT

tell what the internal clock rate it. Whatever the internal clockrate, the usersees a UART that is running at 57,600 baud.

To make it easier to be sure that the internal clockrate is changing asdesired, use Timer 0 to output a squarewave whose period is 20µs to P3.4

when the internal clock is running at full speed. Do not adjust the reloadvalue when the internal clock is halved. In this way, the “advanced user” willbe able to tell that clock is being halved by looking at the output of P3.4.When the output is a 20µs squarewave, then the clock is not being divideddown. When it is a 40µs squarewave, then the clock is being divided down.

To see the change in the power used by the micro-controller, connect a 9 Vbattery to the development kit, but only connect it to one of the terminals onthe board. Connect the second terminal to the battery through an ammeter.You should observe current in the tens of milliamperes, but you should seea clear drop in the current when you halve the clockrate. Please work verycarefully when performing this part of the experiment and call over one ofthe assistants if you need help.

Chapter 30

Reading List

30.1 Datasheets and Manuals Referred to

• Analog Devices Inc., MicroConverter 12-Bit ADCs and DACs with Em-bedded High Speed 62-kB Flash MCU ADuC841/ADuC842/ADuC843,Rev. 0, Analog Devices Inc., Norwood, MA, 2003. (These are theADuC841’s data sheets.)

• Analog Devices Inc., “ADUC8XX SAR EVALUATION BOARD REF-ERENCE GUIDE,” Version A.3, Analog Devices Inc., Norwood, MA.

• Metalink Corporation, 8051 Cross Assembler User’s Manual, MetalinkCorporation, Chandler, AZ, 1990.

• Philips Semiconductors, 80C51 Family Programmer’s Guide and In-struction Set, Philips Semiconductors,http://www.hoeben.com/80C51_FAM_PROG_GUIDE_1.pdf, last visitedSeptember 6, 2007.

• Philips Semiconductors, “80C51 Family Architecture,” Philips Semi-conductors, http://www.hoeben.com/80C51_FAM_ARCH_1.pdf, last vis-ited September 6, 2007.

30.2 8051 Related Information

• Richard H. Barnett, The 8051 Family of Microcontrollers, PrenticeHall; ISBN 0023062819

• J. Uffenbeck, The 8086/8088 Family, Prentice-Hall, 1987

135

136 CHAPTER 30. READING LIST

• William Kleitz, Microprocessor and Microcontroller Fundamentals :The 8085 and 8051 Hardware and Software, Prentice Hall; ISBN: 0132628252

• Stuart R. Ball, Embedded Microprocessor Systems: Real World Design,Butterworth, 1996 ISBN 0-750-69791-1


Recommended