Vous êtes sur la page 1sur 136

A Microprocessor Laboratory Using the ADuC841

Shlomo Engelberg1 December 13, 2010

1 Copyright

c 2002-2009 by Shlomo Engelberg

Contents
1 The ADuC841 Microprocessor 2 The 2.1 2.2 2.3 2.4 2.5 Microprocessor Overview . . . . . . . . . . . . . . . . . . . . The Registers . . . . . . . . . . . . . . . . . The Memory . . . . . . . . . . . . . . . . . Machine Language and Assembly Language The MemoryA Programmers Perspective 2.5.1 Internal Data Memory . . . . . . . . 2.5.2 Program Memory . . . . . . . . . . . 2.5.3 External Data Memory . . . . . . . . 2.5.4 Bit Addressable Memory . . . . . . . 2.6 Arithmetic . . . . . . . . . . . . . . . . . . . 2.7 Logical Operations . . . . . . . . . . . . . . 2.8 Bitwise Operations . . . . . . . . . . . . . . 2.9 Flow Control . . . . . . . . . . . . . . . . . 2.10 Exercises . . . . . . . . . . . . . . . . . . . . Assembler Introduction . . . . . . . . . The Reference . . . . . . . . The Assembler as Translator Telling the Assembler Where Header Files . . . . . . . . . Comments . . . . . . . . . . The Last Directive . . . . . Running the Compiler . . . Downloading the Program . Exercises . . . . . . . . . . . 11 13 13 13 13 15 16 16 17 17 17 18 19 19 20 21 23 23 23 24 25 27 27 28 28 28 29

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

3 The 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10

. . . . . . . . . it is . . . . . . . . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

4 4 Interrupts 4.1 An Introduction to Interrupts 4.2 The Interruptsin Brief . . . 4.3 Why We Use Interrupts . . . 4.4 Enabling Interrupts . . . . . . 4.5 Exercises . . . . . . . . . . . . 5 A Philosophical View of the 5.1 Two Types of SFRs . . . . 5.2 Bit Addressable SFRs . . 5.3 An Example . . . . . . . . 5.4 Exercises . . . . . . . . . .

CONTENTS 31 31 32 33 34 34 35 35 35 36 36 37 39 39 40 40 41 41 42 43 43 43 43 43 45

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

Special . . . . . . . . . . . . . . . . . . . .

Function . . . . . . . . . . . . . . . . . . . . . . . .

Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . .

. . . .

6 An Introduction to Reusable Code 7 An Introduction to the ADuC841 7.1 A General Introduction . . . . . . . . . 7.1.1 The Assembler . . . . . . . . . 7.1.2 Some Important Commands . . 7.1.3 Looping . . . . . . . . . . . . . 7.2 Introduction to Vision3 . . . . . . . . 7.3 Compiling and Downloading a Program 7.4 The Experiment . . . . . . . . . . . . . 7.4.1 Part I . . . . . . . . . . . . . . 7.4.2 Part II . . . . . . . . . . . . . . 7.4.3 Part III . . . . . . . . . . . . . 7.4.4 The Report . . . . . . . . . . . 7.5 Exercises . . . . . . . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

8 The Hardware Stack 47 8.1 When and Why the Stack is Used . . . . . . . . . . . . . . . . 47 8.2 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 9 Interrupts 9.1 A General Introduction . . . . . . . . . . . . . . 9.1.1 Enabling Interrupts . . . . . . . . . . . . 9.1.2 Some Facts about the External Interrupt 9.2 Bounce . . . . . . . . . . . . . . . . . . . . . . . 9.3 The Experiment . . . . . . . . . . . . . . . . . . 9.3.1 Part I . . . . . . . . . . . . . . . . . . . 9.3.2 PartII . . . . . . . . . . . . . . . . . . . 49 49 49 50 50 50 50 50

. . . . . . Pins . . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

CONTENTS

9.4

9.3.3 The Report . . . . . . . . . . . . . . . . . . . . . . . . 51 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 53 53 54 54 54 55 55 56 56 56 57 57 57 58 59 59 60 60 60 60 60 61 61 61 61 63 63 64 65 65 66 66

10 The Timer Interrupts 10.1 A General Introduction . . . . . . . 10.2 Controlling the Timer . . . . . . . 10.2.1 The TMOD SFR . . . . . . 10.2.2 The TCON SFR . . . . . . 10.2.3 The Timer as an Interrupt . 10.3 How to Set-up the Timer/Counters 10.4 The Experiment . . . . . . . . . . . 10.5 The Report . . . . . . . . . . . . . 10.6 Exercises . . . . . . . . . . . . . . . 11 The 11.1 11.2 11.3 11.4 11.5 11.6

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

Integrated Development Environment (IDE) Introduction . . . . . . . . . . . . . . . . . . . . . . Projects . . . . . . . . . . . . . . . . . . . . . . . . Writing the Assembly Language File . . . . . . . . Debugging the Program . . . . . . . . . . . . . . . An Example . . . . . . . . . . . . . . . . . . . . . . Other Helpful Features . . . . . . . . . . . . . . . . 11.6.1 Running the Program in the Debugger . . . 11.6.2 Breakpoints . . . . . . . . . . . . . . . . . . 11.6.3 Peripherals . . . . . . . . . . . . . . . . . . 11.6.4 Watchlists . . . . . . . . . . . . . . . . . . . 11.6.5 The Logic Analyzer Window . . . . . . . . . 11.7 The Experiment . . . . . . . . . . . . . . . . . . . . 11.8 The Report . . . . . . . . . . . . . . . . . . . . . . 11.9 Exercises . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

. . . . . . . . . . . . . .

12 Using the Onboard UART 12.1 General Introduction . . . . . 12.2 The Onboard UART . . . . . 12.3 Writing a String to the UART 12.4 The Experiment . . . . . . . . 12.5 The Report . . . . . . . . . . 12.6 Exercises . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

13 Using the Onboard UARTPrinting a Preprogrammed String 67 13.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 67 13.2 The New Commands and Techniques . . . . . . . . . . . . . . 67

6 13.2.1 Reading from the Code Segment . . 13.2.2 Some Assembler Directives . . . . . 13.2.3 Writing a String to the Serial Port 13.2.4 Forcing an Interrupt . . . . . . . . 13.3 The Experiment . . . . . . . . . . . . . . . 13.4 The Report . . . . . . . . . . . . . . . . . 13.5 Exercises . . . . . . . . . . . . . . . . . . . 14 Timer 3 14.1 Introduction . . 14.2 Using Timer 3 . 14.3 The Experiment 14.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

CONTENTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 68 69 69 69 70 70 71 71 71 72 72 73 73 73 73 73 75 75 76 76 76 77 77 77 79 79 79 79 80 80 81 81 81

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

15 Using the Parallel Ports 15.1 General Introduction . . . . . . . . . . . . . . . . 15.2 How the Parallel Ports Operate . . . . . . . . . . 15.2.1 The Connection between the Registers and 15.2.2 Parallel Ports 0, 2, and 3 as Outputs . . . 15.2.3 The Registers P0, P2, and P3 . . . . . . . . 15.2.4 Ports 0, 2, and 3 as Inputs . . . . . . . . . 15.2.5 Port 1 . . . . . . . . . . . . . . . . . . . . 15.2.6 Alternate Functions . . . . . . . . . . . . . 15.2.7 Using the Ports . . . . . . . . . . . . . . . 15.3 The Experiment . . . . . . . . . . . . . . . . . . . 15.4 The Report . . . . . . . . . . . . . . . . . . . . . 15.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . 16 A Serial Port Controlled Clock 16.1 General Introduction . . . . . . . 16.2 Timer 2 . . . . . . . . . . . . . . 16.2.1 T2CON . . . . . . . . . . . 16.2.2 Printing a Variable String 16.2.3 More about Interrupts . . 16.3 The Experiment . . . . . . . . . . 16.4 The Report . . . . . . . . . . . . 16.5 Exercises . . . . . . . . . . . . . .

. . . . . . . . . . the Pins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

17 A Counter 83 17.1 General Introduction . . . . . . . . . . . . . . . . . . . . . . . 83 17.2 Using a Timer/Counter as a Counter . . . . . . . . . . . . . . 83

CONTENTS

17.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 83 17.4 The Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 17.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 18 Interfacing a Keypad 18.1 General Introduction 18.2 The Experiment . . . 18.3 The Report . . . . . 18.4 Exercises . . . . . . . 85 85 85 87 87 89 89 90 91 91 92 92 93 93 94 95 96 96 97 97 98 99 99 100 100 100 100 101 102 102 102 102

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

19 Digital to Analog Converters 19.1 A General Introduction . . . 19.2 The Underlying Theory . . . 19.3 Implementation . . . . . . . 19.4 The Experiment . . . . . . . 19.5 The Report . . . . . . . . . 19.6 Exercises . . . . . . . . . . . 20 Using the Onboard DAC 20.1 General Introduction . 20.2 Controlling the DAC . 20.3 The Experiment . . . . 20.4 The Report . . . . . . 20.5 Exercises . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

21 Analog to Digital Converters 21.1 A General Introduction . . . 21.2 Implementation . . . . . . . 21.2.1 ADCCON1 . . . . . . . 21.2.2 ADCCON2 . . . . . . . 21.2.3 ADCCON3 . . . . . . . 21.2.4 ADCDATA . . . . . . . 21.2.5 The A/D Interrupt . 21.2.6 The Inputs . . . . . 21.3 The Experiment . . . . . . . 21.4 The Report . . . . . . . . . 21.5 A Second Experiment . . . . 21.6 The Second Report . . . . . 21.7 Exercises . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

8 22 Designing a Low-pass Filter 22.1 A General Introduction . . 22.2 Stability . . . . . . . . . . 22.3 Performance . . . . . . . . 22.3.1 The Analog Filter . 22.3.2 The Digital Filter . 22.4 The Experiment . . . . . . 22.5 The Report . . . . . . . . 22.6 Exercises . . . . . . . . . .

CONTENTS 105 . 105 . 105 . 106 . 106 . 107 . 108 . 108 . 108 109 . 109 . 109 . 110 . 110 . 110 113 . 113 . 114 . 114 . 114 . 114 115 115 115 115 116 116 116 116 116 117 117 117

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

23 Implementing a Simple Oscilloscope 23.1 A General Introduction . . . . . . . 23.2 Implementation . . . . . . . . . . . 23.3 The Experiment . . . . . . . . . . . 23.4 The Report . . . . . . . . . . . . . 23.5 Exercises . . . . . . . . . . . . . . . 24 Implementing a Simple Capacitance 24.1 A General Introduction . . . . . . . 24.2 Implementation . . . . . . . . . . . 24.3 The Experiment . . . . . . . . . . . 24.4 The Report . . . . . . . . . . . . . 24.5 Exercises . . . . . . . . . . . . . . . 25 Generating PN Sequences 25.1 Introduction . . . . . . . . . . . . 25.2 Some Facts about PN Sequences . 25.2.1 Length . . . . . . . . . . . 25.2.2 Ones and Zeros . . . . . . 25.2.3 The Autocorrelation . . . 25.3 Implementation Hints . . . . . . . 25.3.1 Shift Registers . . . . . . . 25.3.2 Logical Operations . . . . 25.4 The Experiment . . . . . . . . . . 25.5 The Report . . . . . . . . . . . . 25.6 Exercises . . . . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

Meter . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

26 A Simple Switching Circuit 119 26.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 26.2 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 119

CONTENTS 27 Making a Simple Plotter 27.1 Introduction . . . . . . . . . 27.2 The Main Idea . . . . . . . 27.3 An Example . . . . . . . . . 27.4 Implementing the Plotter . . 27.4.1 Storing the Values to 27.4.2 Plotting the Points . 27.5 The Experiment . . . . . . .

9 123 . 123 . 123 . 124 . 125 . 125 . 125 . 126 127 . 127 . 127 . 128

. . . . . . . . . . . . . . . . . . . . . . . . . . . . Be Plotted . . . . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

28 Building and Testing a Dynamic Logic Inverter 28.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 28.2 A Brief Explanation of the Circuit . . . . . . . . . . . . . . . 28.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . .

29 Power Management 131 29.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 29.2 Power Management in the ADuC841 . . . . . . . . . . . . . . 132 29.3 The Experiment . . . . . . . . . . . . . . . . . . . . . . . . . . 133 30 Reading List 135 30.1 Datasheets and Manuals Referred to . . . . . . . . . . . . . . 135 30.2 8051 Related Information . . . . . . . . . . . . . . . . . . . . 135

10

CONTENTS

Chapter 1 The ADuC841 Microprocessor


The ADuC841 is essentially an 8052 microprocessor with a host of additional peripherals added. (A website about the 8052 that you may nd useful and interesting 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 internal data memory. 3 timer/counters. Several I/O ports. 1 Universal Asynchronous Receiver Transmitter (UART) that is able to communicate using one of the protocols a computer uses. In this course we will see how all of these peripherals are used. The 8052s memory is organized into ve areas: The Code section (Either internal or externaldepending on the EA pin). 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 rst four types of memory is accessed using somewhat dierent instructions, and based on the instruction given the processor may access the memory in a physically dierent fashion. (Access to external memory, for example, involves changing the voltages on some of the pins that leave the processor. Access to internal memory does not involve such changes.) The fth type of memory is memory mapped to the a subset of the internal data sectionof the second type of memory. The ADuC841 has several peripherals that the 8052 does not have. The two most notable additions are an eight channel A/D and two channels of D/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 programmed via the ADuC841s serial port. A watchdog timer. 4 KBytes of FLASH/EE memory. In this course, we will not be dealing with a simple ADuC841we will an evaluation kit for the ADuC841. This kit gives us several features that the chip itself does not have. For example, the cable supplied with the kit has a level shifter that takes the output of the on-chip UART and shifts it from the chips levels of 0 V and 5 V to the RS232 levels12 V.

Chapter 2 The Microprocessor


2.1 Overview

Like all members of the 8051 family, the ADuC841s core can be thought of as being composed of several dierent regions of memory and various processing units. 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 of registers each of which contains eight 8-bit registers. At any given time, only one register bank is active. The registers in the active bank are referred to as R0 through R7. Many commands are designed to work most eciently with these registers. At startup, the rst bank of registers is active and the stack pointer points to the beginning of the second bank of registers. The single most important register is probably the accumulatorwhose mnemonic is ACC. The accumulator is used in most arithmetic calculations and in many other places. As we will see, many commands work best with the accumulator, and other commands only work with the accumulator.

2.3

The Memory

As mentioned previously, the ADuC841 has several types of memory. Unlike the standard Von Neumann architecture in which the program and data memory are contained in the same physical block of memory, the ADuC841 has 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 data memory, internal program memory, and external program memory. As with all computers there are a variety of ways in which memory can be accessed. The simplest way of addressing a location in memory is to tell the computer that you would like to access a particular location and to tell it what location. This is called direct addressing. The command MOV moves or copies a byte of data from one place to another. If one issues the command MOV 40H, 50H this causes the contents of memory location 50H to be copied into location 40H of the internal data memory. As mentioned previously, the ADuC841 has four banks of registers each of which have 8 registers. The register banks are located in the data memory from locations 00H to 1FH. (I.e. the registers are memory mapped to the locations 00H - 1FH, and each byte contains one register.) A second way of accessing data memory is indirectly. To indirectly address a byte one stores the location of the byte which one would like to access in one 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 addressable. We will see that there are a whole suite of commands that allow us to manipulate bits with ease. Additionally the internal data memory from 80H to FFH is devoted to the special function registers (SFRs). All accesses to these registers must be made directly. In order to make it possible to have 256 bytes of actual internal (general purpose) memory, indirect accesses to memory from 80H to FFH refer to a (physically dierent) set of memories that sit at that location. This memory is meant for general use and is in no way 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 languagecalled assembly language that is one level above the machines own languagecalled machine language. The reason that assembly language is used is that in machine language there are many very similar commands that assembly language bundles into a single command. We consider the MOV command as a typicaland very importantexample. Let us start with the command MOV A, Rn. This command causes the contents of the register Rn to be moved to the accumulator, A. This command is stored in the program memory as the number 11101rrr where the nal three bits are the number of the register in binary. Thus, MOV A, R0 is stored as 11101000. A point worth noting is that in the machine language command, the fact that the byte is being moved into the accumulator is part of the instruction. (This is why A is used to represent the accumulator and not ACC. We do not actually tell the processor that we want to move information into the accumulator. The command that we give means move information from general purpose register rrr to the accumulator.) If one would like to move data from the accumulator to one of the general purpose registers, then one writes MOV Rn, A. This mnemonic is easy to understand. The machine language code that corresponds to this instruction is 11111rrr. This does not look too similar to the previous example, though its 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 internal 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 program memory. Also, note that this instruction requires 3 cycles to execute. (The two preceding examples required only one byte of storage and one cycle to execute.) Once again, the machine code is very dierent from the assembly language mnemonic, and even many people who like to work with low-level constructs generally prefer assembly language to machine code. To get all the information you want about the commandsany of the 8051s commandssee the 8051 Family Programmers Guide and Instruction Set (The Programmers Guide).

2.5
2.5.1

The MemoryA Programmers Perspective


Internal Data Memory

The ADuC841 (and all of the 8051 family processors) has several classes of commands for using memory. The most important commands for the programmer are those that deal with internal data memory. These commands are also the commands whose nameswhose mnemonicsare as simple as possible. As we have already seen, the command for moving internal data memory is just MOV. There are many possible moves one might want to perform, and the 8051 allows almost all of them. In fact, the MOV command is the most versatile command in the 8051s lexicon. We have already seen how to move data from the accumulator to a general purpose register; from a register to the accumulator; from one address to another; and from an indirectly addressed location to a direct locationto a specic address. Another important variant is moving a given constant value to a location in memory. Suppose that one would like to move 50 hex into location 40 hex. Then one writes MOV 40H, #050H. The hash mark causes the compiler to tell the processor to move the value to a particular location. One of the simplest ways to write a program that looks ne and is syntactically correct is to type MOV 40H, 50H when one meant to type MOV 40H, #050H. Both commands are legal; the rst moves the value stored in location 50 hex to location 40 hex; the second moves the value 50 hex into location 40 hex. There is a big dierence between the semantic content of the commands; syntactically they are almost identical. Most MOVs that one might consider are legal. Some, however, are not. For example if one uses MOV R0, R1, one will nd that the compiler will not recognize the command. For a complete description of the MOV command see The Programmers Guide.

2.5. THE MEMORYA PROGRAMMERS PERSPECTIVE

17

2.5.2

Program Memory

Program memory in the ADuC841 is fully internal. There are two commands and two commands onlyfor fetching data from the program memory. One can use either the command MOVC A, @A+DPTR or MOVC A, @A + PC. The rst command reads the value stored in the program memory at the location given by the sum of the current value of the 16 bit register DPTR and the current value of the accumulator and moves this value to the accumulator (overwriting its current contents). The second instruction does the same thing, but uses the PCthe program counterrather than the DPTR register. These commands are used to read values in xed tablesas the values stored in the program memory cannot be changed while a program is executing. The fact that the values read are xed is emphasized by the mnemonic MOVC which, according to the 80C51 Family Architecture, stands for MOVe Constant.

2.5.3

External Data Memory

In addition to the 256+128 bytes of RAM that all 8052s have, the ADuC841 has an additional 2K of RAM that is internally wired as external RAM. To access this memory, one makes use of the MOVX commands. For more information on these commands, please see the The Programmers Guide.

2.5.4

Bit Addressable Memory

In addition to regular data memory, certain parts of the data memory are bit addressable. That means that one can refer to a specic bit in the memory rather than having to refer to a whole byte. One can write to one bit, read from one bit, and perform operations on one bit. This makes it easy to implement ags without wasting an entire byte for a job that a bit can do better. The bit addressable locations in the regular data memory are all the bits in the bytes from 20H to 2FH. Additionally any special function register whose address (in hex) ends in 0 or 8 is also bit addressable. The SFRs that are 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 to clear a bit (to zero) is CLR bit. In addition, there are a large number of commands that test a bit and then jump. For example JB bit, rel jumps if bit is set (to one). For more information on these commands see the 8051 Programmers Guide.

18

CHAPTER 2. THE MICROPROCESSOR

2.6

Arithmetic

When performing arithmetic using the ADuC841 (or any other member of 8051 family) frequently one must use the accumulator. For example, there are many ways to add two numbersand all of them require the use of the accumulator. Similarly the commands that perform subtraction always have the accumulator as one of the operands. Many of the logical commands also work best with the accumulator. The accumulator is the most important register of which the ADuC841 is possessed. To add two numbers, one uses the ADD command. Suppose that one would like to add the contents of memory location 40H and 50H. Because the ADuC841 does not support addition between two locations in memory, one must rst move one of the values to the accumulator and then perform the 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 can be contained in a single byte, then what can be contained there is stored in the accumulator and the carry bita special bitis set as well. Thus, checking the carry bit after an addition tells one whether or not the addition overowed. (The carry bit is the rst 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 rst byte and the ADDC command for all the rest. The ADDC command works just like to ADD command, but it also adds an extra one if the carry bit was set. In addition to an ADD command there is also a SUBB command. See the 8051 Programmers Guide for more information on subtraction. Because one is often interested in counting events, adding one to a value or subtracting one from a value is a very common operation. For this reason the ADuC841 (and all of the 8051 family of processors) has special commands for incrementing and decrementing values. To increment a value one uses the command INC and to decrement one uses DEC. These commands work on the accumulator, on the general purpose registers, on locations in memory, or on indirectly accessed locations in memory. In addition to addition and subtraction, there are also commands that perform multiplication and division. These commands can be useful when one 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 logical operations. 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 one another, and to rotate bytes. The rotate commands are particularly interesting. There are four types of 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 rotated into its rst bit. The accumulator is treated like a circular register whose rst bit follows its last bit. RR is similar, except that every bit moves one bit to the right and the rst bit is rotated into the last bit. There is also a command called RLC which rotates left through the carry bit. This command treats the accumulator with the carry as one nine bit register. The carry bit is treated as the lowest order bit. Thus, the value of the the carry bit is fed into the lowest order bit of the accumulator, and the value of the highest order bit is fed into the carry bit. If one needs to shift a string of bytessay in a 32 bit numberthis command can be very useful. The command RRC works similarly but shifts the bits in the opposite direction.

2.8

Bitwise Operations

As mentioned previously, there are commands that set and clear bits. It is also 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 the accumulator has for bytes. Many operations must involve the carry bit. For example, when anding two bits, one of the bits must be the carry bit. There are two forms of the and command. One has ANL C, bit which means that one must and the carry bit with a specic other bit, and one has ANL C, /bit which means that one must and the carry bit with the complement of a specic other bit. Note that in these commands the C is really part of the command. The machine language code for the command includes the information that one of the bits being anded is the carry bit. Also, the fact that the bit being anded with the carry is to be (or not to be) complemented is part of the machine language instruction. Finally, another way in which the carry bit here is similar to the accumulator in byte-wise operations is that the result of the calculation is stored in the carry bit. In addition to commands that manipulate bits, there are several commands 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 processor 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 which causes the processor to jump if carry not set. There are also commands that 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 program ow. The most frequently used ow control command is probably JMP. What is interesting about this command is that it has no direct translation into machine language. The assembler (about which we will learn more shortly) translates the JMP command into either LJMP, AJMP or SJMP. Each of these commands causes the program to jump to a new location. The way the location is storedand the distance it can be from the current location diers from command to command. As with most programming languages, there is also a command to CALL a subroutine. The programmer generally writes CALL, and the assembler translates this command into either ACALL or LCALL. At the end of a subroutine, 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 decrement and jump if not zero. It is useful when one would like to implement a loop. Suppose that one would like to pass through a loop ten times. One way to do this is to use 40H as a counter. One then uses DJNZ to count the number of passes through the loop. Consider the following code: MOV 40H, #10; Move the number 10 into location 40H. The body of the loop goes here. DJNZ 40H, LOOP

LOOP:

This loop uses 40H as a counter. Recall that the hash mark (#) that precedes the number 10 tells the compiler that we want to move the actual number into the memory location. In addition to commands to jump, call, and decrement and jump if not zero, 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 jumps if 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 two sixteen bit numbers. Assume that the rst word to add is stored in 40H and 41H (with 40H the low-order word) and that the second word is 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 signicant byte and 43H contain the most signicant byte. Use the RLC command to develop a set of commands that will shift the entire long word one bit to the left. You may leave the most signicant bit of the long word in the carry bit. 3. Why is the following command unreasonable? MOVC @A+DPTR, #10 (Note that the rst operand is generally the destination of a move command.) 4. What is the dierence between the commands CLR C and CLR CY? In what ways are the commands similar? (You may nd the MicroConverter Quick Reference Guide helpful.)

22

CHAPTER 2. THE MICROPROCESSOR

Chapter 3 The Assembler


3.1 Introduction

Computers have a mother tonguetheir machine languagethat is well suited to computers. A computers machine language is generally a set of numbers whose organization is signicant to the computer. A determined human being can learn to read and write machine language, but even those of us who like working at a low level do not usually want, or need, to work at that low a level. The lowest level most of us deal with is assembly language. Assembly language, as we have seen, is still very low level, but it allows us to work in a more pleasant way. The program that takes assembly language code and converts it into machine language is called an assembler. In this chapter you will be introduced to an assembler for the ADuC841. In general assemblers make our lives easier in a number of ways: they translate assembly language commands into machine language commands; they allow us to give symbolic names to memory locations; they allow us to determine where variables and code will be placed in a 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 Users Manual. It is available in the le 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. We have spent quite a bit of time learning about the commands, and not much time understanding how the microprocessor is fed the commands. We remedy that lack now. Consider the all-important MOV command. This command tells the microprocessor to move information from one place to another. As we have seen, there are many dierent 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 command MOV 40H, #50. Because the meaning of each symbol is unambiguous, we can immediately state that this command is telling the ADuC841 to move the number 50 (in decimal because there is no H after the nal number) to the location 40 hex. Looking on p. 39 of the 8051 Programmers Guide, we nd that in machine code this is: 0111 0101 0100 0000 0011 0010

The rst byte is code that means move xed data to a particular location, The second byte is 40H in binary, and the third byte is 50 (decimal) translated into binary. It is clear that a simple program could take care of this type of translation. As mentioned in the architecture chapter, there are other tasks that the compiler performs. The two meta-commands JMP and CALL must be translated into the proper true instructions. This takes a slightly smarter program, but is quite doable. Where the assembler really helps the programmer is in getting rid of the need to keep track of myriad physical addresses and constant values. The assembler makes it possible to assign names to memory locations, to locations within a program, to constants, and to specic bits. This makes it possible to make ones programs much easier to reada goal that programmers must always keep in mind. Another thing that the assembler does is to allow one to add comments to ones programs. Many of the instructions that cause the microprocessor to jump, actually cause the microprocessor to jump x bytes forward (or backward) in the program memory. In such commands, the assembler allows one to write a program 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: LOOP: MOV R0, #10 DJNZ R0, LOOP

The rst line loads general purpose register 0 with 10. The second line starts with 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 program memory 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 the relative amount to jump. That is not given directly. We have given the compiler a label. The compiler must take the label and calculate how far to jump. The compiler does this calculation and then places that value in the appropriate location in the program memory. Here we see a good example of how the compiler saves us eortwe do not need to worry about calculating jumpsand 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 dierent types of memory. The assembler is able to deal with all of them but must be told in which segment of memory it is working. Additionally, it must know where it is located within the segment. We discuss four of the segments. The most important segment is the code segment. To tell the assembler that one wants what follows to be placed in the code segment one gives the assembler the directive CSEG. This directive is not translated into machine language at allit does not tell the microprocessor what to do. It is a directive to the assembler that tells the assembler how to interpret the information that follows the directive. If one does not tell the assembler otherwise, the code segment is the segment to which the assembler defaults. 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 the given location in the segment. If one would like to start from the beginning of the code segment, then one types CSEG AT 0H. To cause the assembler to change to a given location within the current segment, one uses the directive ORG. 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 the data segment, one uses the directive DSEG. Because locations 000H-01FH are the four register banks and locations 20H-2FH are the bitwise addressable memory, one generally does not want to use memory in the region 00H - 2FH for general purpose storage. Thus, when switching to the data segment, one generally uses the directive DSEG AT 030H. There are several other ways the compiler helps us. Suppose that we would like to dene a counter in data memory. One way is for us to keep track of all the locations in data memory and to use the data memory as we please. An easier way is to let the compiler do the bookkeeping. Consider the following code segment: DSEG AT 30H COUNTER1: COUNTER2: DS DS 1 1

The rst line tells the compiler that the following directives pertain to the data segment and that the compiler should start placing variables at location 30H. The second line says that COUNTER1 is to be assigned to the next location in the data segmentin this case 30H. The directive DS is always used when allocating data memory. The 1 says that one byte should be reserved. (If one were to type 3, then the next three bytes would be reserved.) The next line reserves the next byteat location 31Hfor COUNTER2. Note that we were saved needing to think much about where the bytes would be stored. Once the memory has been reserved, the labels COUNTER1 and COUNTER2 can be used any place where one needs to refer to internal data memory locations 30H 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 directivejust as one does when using the data segment. The last segment that is of real interest to us is the bit addressable segment. 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. A simple example of how this directive can be used is: BSEG FLAG: DBIT 1

This directive reserves one bit for the ag FLAG and assigns the bits address to FLAG. In a program one can now use FLAG wherever a bit should go, and one can 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 one must refer to. All of the special function registers are located at memory location 080H-0FFH. Though one could memorize all the various byte and bit locations of interest, this is neither necessary nor desirable. Even if one knew all of the relevant memory locations, the next person to read your program might not know what the memory location is used for. In order to write 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 and bits. However, Analog Devices provides a set of les similar to Cs header leswhich take care of this work for you. The header le for the ADuC841 is MOD841. If one is not using any of the peripherals that are special to the ADuC841 and one would like to write code that is compatible with 8052, one can use the le MOD52. Both of these les assign names to the commonly used bits and bytes. By using these les one is writing code that will be more easily understood by others who are familiar with the 8051 family and the ADuC841. To cause the compiler to read and interpret a header le, one gives the compiler the directive $INCLUDE(MOD52) or $INCLUDE(MOD841). Place the directive at the begining of the program. Note that in the system that we use, the names of all special function registers that exist in the 8051 are predened. If all of the special function registers used in a program exist in the 8051, then there is no need to use a header le.

3.6

Comments

Another important part of writing readable code is using comments. In our assembler, comments begin with a semi-colon (;). From the semi-colon until the end of the line, all the rest of the text is a comment. These comments are often what stand between the programmer and totally unreadable code. It is important to have a preamble before the useful content of a le appears. The preamble should include the name(s) of the author(s), the date that the le was written, the date(s) on which the le was revised (if any), the hardware for which the code is meant, the les name, and a

28

CHAPTER 3. THE ASSEMBLER

short description of the purpose of the code in the le. Additionally any command whose purpose would not be clear to an uninitiated reader should have comments added to it until it reaches the point that a person reading the le will understand the purpose of the code.

3.7

The Last Directive

Every program must end with the END directive. The only thing that is allowed to follow the END directive is a comment on the same line. If one places code or comments on the lines following the END directive, the compiler will ag 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 development environment (IDE). The IDE is a program that can do many things to help you. 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 compiler is run it produces two les. One is the .hex le which has the machine language code in a form suitable for downloading to the ADuC841. The compiler also outputs a .lst le. This le has both the source code, the machine code, a list of errors, a list of locations, and a host of other information that is often useful in debugging. The .lst le can be very useful.

3.9

Downloading the Program

After being properly initialized, the IDE can download programs to the ADuC841. Programs are downloaded to the ADuC841 by using its UART. The UART can be used for all sorts of communication, and before downloading a new program to the ADuC841, the processor must be told that the message that is about to come is a new program. One tells the ADuC841 that a new program is about to come by holding down the serial download button on the evaluation board while resseting the ADuC841. After having informed the ADuC841 that one is about to download a program, one goes to the FLASH tab in the IDE, and one clicks on download. Assuming that everything goes well, the program will start running on the ADuC841 almost immediately.

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. Each time you turn on the ADuC841 it runs the last program that was stored in its memory.

3.10

Exercises

1. If the .lst le is destroyed, what must one do in order to run the compiled program? (The answer is very simple.) 2. Suppose that in the data segment one gives the directive ORG 40 and then one gives the directive ARRAY: DS 5. Precisely what will the instruction 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 and similar microprocessors this interfacing is often done through interrupts (and the SFRs). See Figure 4.1 for a schematic description. One can think of an interrupt as an interruption of the processors normal functioning. Let us consider the simplest type of interruptone that is asserted when the voltage on a particular pin of the microprocessor changes in a particular fashion. When the voltage on the pin is changed, the microprocessor automatically jumps to a xed location in the program memory and starts executing from that location. At the same time, the microprocessor stores the location that it was at previously so that when it nishes with whatever commands are located at the xed position it can return to whatever activity was interrupted. In the microprocessors in the 8051 family, each of the (many) interrupts causes the microprocessor to jump to a dierent location. For example, external interrupt zero, which is asserted when pin 2 of port 3 is changed in a particular way, causes the processor to jump to address 3 in the program memory. The set of locations to which the processor jumps is called the interrupt vector table. When the processor jumps to a location upon the assertion of an interrupt, the processor is said to vector to the location. Thus, upon the assertion of the external interrupt 0 interrupt the processor vectors to location 3 in the program memory. On page 71 of the ADuC841 Data Sheets (contained in the le ADuC841 2 3.pdf) there is copy of the vector table for the 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 interacations take place inside the chip. This means that if the entire response to an interrupt requires eight or fewer locations, then the interrupt subroutine (ISR) can be placed in the vector table. Otherwise one jumps from the vector table to the actual location of the ISR. Upon reaching the end of the ISR, one must inform the processor to return to its regularly scheduled programmingthat it must go back to normal operation. This is done by giving the RETI command. (RETI stands for RETurn from Interrupt.)

4.2

The Interruptsin 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 zerois tied to the status of pin 2 of port 3. Timer zero interrupt.

4.3. WHY WE USE INTERRUPTS External interrupt oneis 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.

33

4.3

Why We Use Interrupts

The power of interrupts lies in the fact that the various tasks that a microprocessor must control run much more slowly than the microprocessoreven the very slow 8051runs. One way of dealing with very slow processes is to start something, wait around doing nothing until the process nishes, and then proceed to the next step. This style of operation is very wasteful of the processors time. Most of the processors time is spent waiting for something to nish. When using interrupts, one tells a peripheral to do something, and one allows the peripheral to interrupt the processor when it has nished doing whatever it was doing. One example that pertains to the standard 8051 is the serial transmit interrupt. A fairly typical 8051 can perform about 1 million operations per second. The ADuC841 can perform on the order of ten million operations per second. Transmitting a byte across the serial port at a reasonable speed takes about half a millisecondenough time to perform ve thousand operations. To transmit one word made up of ve letters, would take about 2.5 ms. That is time enough for the processor to perform 25,000 operations. One way of dealing with transmitting ve bytes is to transmit a byte and wait until the transmission nishes before sending the next byte. The correct way to do this is to use the 8051s transmit interrupt. What one does is to transmit one byte using the on-board peripheral that takes care of serial communications, and then one lets the processor go back to what it was doing. When the peripheral is nished sending the byte, the peripheral causes the serial transmit interrupt to be asserted. When the interrupt is asserted, one has the processor move the next byte to be transmitted to the peripheral that takes care of serial communications. After this, one allows the processor to return to its regularly scheduled tasks. One continues in 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 interrupt to be asserted, a couple of steps must be taken. First of all, interrupts must be enabled globally. This is done by setting the highest order bit of the interrupt enable registerwhich is a special function register located at address A8H. In MOD52 and MOD841 this bit is given the name EA. That is, to enable interrupts one must give the command SETB EA. There is a second action that must be taken in order to cause the microprocessor to respond to interrupts. The microprocessor must be told to respond to interrupts generally and it must be told to respond to the particular interrupt of interest. In the case of external interrupt zero, the bit that must be set to enable this interrupt is the least signicant bit of the interrupt enable 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 one must 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 interrupt by giving the SETB EX0 command. Each interrupt has a dierent bit that must be set to enable the particular interrupt. To cause the microprocessor to respond to any interrupt one must enable interrupts globally and one must enable the particular interrupt too. For more information on the various interrupt enable bits, see pp. 70-71 of the data sheets for ADuC841.

4.5

Exercises

1. To what location does the ADuC841 vector when external interrupt one is asserted. (Please use the data sheets for the ADuC841 to answer this question.) 2. Which bit of the interrupt enable register must be set to enable the serial interrupt? (Please use the data sheets for the ADuC841 to answer this question.) 3. Why might one want to globally disable interrupts?

Chapter 5 A Philosophical View of the Special 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 microprocessor functions or that are used by the microprocessor in its functioning. Among these registers are the accumulator (whose address is E0H and whose symbol is ACC), the interrupt enable register (whose address is A8H and whose symbol is 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 of peripherals. These registers pass information to and from the microprocessors core to the on-chip peripherals. One can think of these registers as connecting the internal memory of the core of the microprocessor with the control locations of a variety of peripherals. In the 8052, there is regular memory that sits at the same location as the SFRs. All direct accesses to the location from 080H - 0FFH read or write from 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 accumulator, the SFRs that control ports 0 - 3, and some of the SFRs that control the timers. One need not memorize which SFR belongs to which address. The IDE we use comes with header les, with the les MOD52 and MOD841, that have all the denitions one needs. Additionally, by default our compiler 35

36CHAPTER 5. A PHILOSOPHICAL VIEW OF THE SPECIAL FUNCTION REGISTERS recognizes all of the SFRs present in the 8051. For the 8052, the header le is c:\ADUC\MOD52. For the ADuC841 the le 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 the special features of the ADuC841. For more general information about the SFRs see p. 22 of the ADuC841s data sheets.

5.3

An Example

Let us consider a simple example of such an on-chip peripheral. Let us consider port 3 of the ADuC841 (or, equivalently, the 8051). The ports on the ADuC841 (or the 8051) can be controlled pin by pin and some of them can be either inputs or output. Each pin of a port corresponds to a particular pin on the ADuC841. For example, port 3 pin 0 corresponds to pin 16 on the ADuC841. (For a diagram of the ADuC841 chip and what each pin corresponds to, see p. 9 of the data sheets for the ADuC841.) Each port is controlled by one register. Port 3 is controlled by the SFR at location B0H and the symbol that corresponds to it is P3. Bit n of the register controls pin n of the port. One piece of terminology is very important in dealing with bit addressable registers. To address a particular bit in a register that is bit addressable, one can write (register name).(bit number). The lowest order bit in a byte is always bit 0 and the high order bit is always 7. Thus, to access the 0 bit of port 3 one can use the terminology P3.0. Each of the pins that correspond to port 3 can be used either as an input or an output. Use as an output is simplesetting a particular bit in port 3 causes the corresponding pin to go to 5 V. Clearing the bit causes the corresponding pin to go to 0 V. In Chapter 15 we consider the parallel ports in detail.

5.4

Exercises

1. What is the accumulators address in the data memory? Is the accumulator bit addressable? (You may want to refer the to the MicroConverter Quick Reference Guide for help.)

Chapter 6 An Introduction to Reusable Code


In this course we will perform many projects. The projects will start out quite small, and their goal will be to teach the student how the 8051 and the ADuC841 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 2 work. 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 student with the 8052/ADuC841 and its programming environment, we start doing more complicated projects. Among the projects that we will do there will be projects 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 lter. 37

38

CHAPTER 6. AN INTRODUCTION TO REUSABLE CODE

All good programmers are cannibals. It will not be possible to do the later assignments without cannibalizing from the earlier ones. Make sure that all general codecode that controls onboard peripheralsis written in 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 clearly commented and that the mode that the set up leaves the peripheral in is clearly indicated. This will save hours in the later phases of the course. If one does not carefully write the earlier programs, the later ones will take up much too much time.

Chapter 7 An Introduction to the ADuC841


7.1 A General Introduction

In this laboratory you will learn how to write, assemble and run a simple program for the ADuC841. The tool you will use to perform these tasks will be the Keil Vision3 Integrated Development Environment (IDE). (In Chapter 11 you will learn much more about how the IDE can help you debug programs.) 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 begins with a semicolon is just a comment. By custom the commands and their operands are written in capital letter. R0, ..., R7 are registers zero through seven. The instruction clock has a frequency of 11,059,200 Hz. Each instruction 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 in the program. As the diode is connected as shown in Figure 7.1, the LED will light up when the output of the pin is 0V. (Please see Problem 3 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 still does a fair amount of work for the programmer. Often, one must tell a program to go to an instruction or to read from a location in memory. The assembler allows one to assign symbolic names to locations in the code and data memories. This type of assignment can be made in several dierent ways. For example, the command LED EQU P3.4 sets LED equal to P3.4. It tells the assembler to insert P3.4 wherever the programmer typed LED. Another place where the assembler has been used is when a label was needed for a location in memory. Starting a line with a string followed by a colon, tells the assembler to use that string as a label for that location in the code memory. For example, DELAY is the label for the address of the code memory that holds the command MOV R7, #8. Finally the commands JMP and CALL are not directly translatable into commands to the ADuC841they are actually interpreted by the assembler. For example JMP LOCATION is actually a command to the assembler to determine how to jump to LOCATION. There are three dierent types of jump commands that the ADuC841 (or the 8052) recognizes, and the assembler tries to pick the best one for the purpose. (See p. 2-5 of the assembler manual for a brief discussion of this feature.)

7.1.2

Some Important Commands

There are several commands that need to be mentioned at this point. We list 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 SETB operand sets the value of the bit operand to one.

41

CPL operand ComPLements the value of the bit operand. That is, if operand starts out with a one, it will nish with a zero, and if it starts with 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 see the 80C51 Family Programmers Guide and Instruction Set.

7.1.3

Looping

Because of the importance of looping, the 8051 has a special instruction to help one loop through a region of code. The instruction is Decrement and Jump if Not equal to ZeroDJNZ. This instruction takes either three or four clock cycles. Its form is DJNZ R#, LABEL (in which form it takes three clock cycles) 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 from the rst lab. We are not going to explain the programs more interesting features yet, however. Those will be explained in later chapters. For the time being, we list the steps you must take to open Vision3 and load a program into the IDEs editor, and then we describe how to setup the IDE so that it will be able to download the compiled version of the program to the ADuC841. Open Vision3double 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 projectperhaps 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 Target 1. Right-click on Source Group 1 and then click on Add Files to Group Source Group 1. Change Files of type to Asm Source le (*.s*; *.src; *.a*). Find blse841.asm (assuming that it has previously been stored on your hard disk) and add it to the group. (If you do not have a copy of the program, you can copy the program from Figure 7.2 and save it to your hard disk as blse.asm. Then add the le to the group.) At this point a + will appear to the left of Source Group 1 in the panel to the left. Clicking on the + will show you that blse841.asm is now part of the source group. Double click on the blse841.asm and the le 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 hex lea le that can be downloaded to the microprocessorone must right-click on 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 HEX le. Next click on the Utilities tab and in the space under Use Target Driver for Flash Programming go to the drop down arrow and choose ADI Monitor 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 le, one can click on the rebuild all target les icon, or one can go to Project click on it and then click on rebuild all target les. Before downloading the le, one must make sure that the chip is ready to program 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 download button. Then one releases the reset button and, nally, the download button. To download the le to the ADuC841, one must click on the button labeled load. After downloading the le, the le will start running immediately.

7.4. THE EXPERIMENT

43

7.4
7.4.1

The Experiment
Part I

Assemble and download blse841.asm. Make sure that the program runs properly after downloading.

7.4.2

Part II

Modify blse841.asmthe original programto change the period to 5 s on and then 5 s o. Save the le under a dierent name, and make sure that the comments in the program reect the programs new goal and structure.

7.4.3

Part III

Modify blse841.asm to use memory addresses rather than registers in the DJNZ command. Make sure that you do not use addresses that will cause the values to be stored in SFRs, registers, or addresses whose contents are bit addressable. Change the comments to reect the changes in the program and save the modied program under a new name. Calculate how long the LED will be on, and how long it will be o using the new commands. You may want to look at the Quick Reference to nd out how long the commands will 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 corresponds to the period you calculated. (This can most easily be done by using an oscilloscope and make use of the cursors option.)

7.4.4

The Report

Submit both new programs. Make sure that the programs are properly commented. The nal grade will depend on how well written and how well commented 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 that syntax means the way in which linguistic elements are put together to form constituents, while semantics means the study of meanings. Thus syntax deals with form while semantics deals with substance.) 2. Using the .lst le generated by the compilation of the sample le, nd the machine code that corresponds to DJNZ R5, $. 3. Determine why the LED is connected as shown in Figure 7.1. (You will probably want to look at p. 5 of the datasheets. In particular, you may wish to check how much current the digital outputs can source and 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 rst in last out (FILO) buer. By custom putting something on the stack is called pushing the item on the stack, and removing something from the stack is called popping the item from the stack. The 8051 and its descendants have built in stacks. The top of the stack is pointed to by the stack pointer, SP. The stack pointer is one of the special function registers. By default the stack starts at location 08H and grows towards higher addresses. The stack is accessed by indirectly accessing the address pointed to by the stack pointer. When a CALL command is issued or an interrupt occurs, the 8051 and its descendants all automatically store the next locationthe location to return tooon the stack. When the end of the subroutine or interrupt subroutine is reachedwhen the command RET or RETI is giventhe microprocessor POPs the value of the address to continue from o the stack and jumps to the address. When entering a subroutine, one would often like to save information that one intends to restore just before returning to the calling program at the end of the subroutine. This is particularly true about interrupt subroutines. One convenient way of doing this is to use the ADuC841s hardware stack. One saves the information by PUSHing it onto the stack. Because the ADuC841 expects to nd the address to return to at the top of the stack when the RET or RETI commands are issued, it is important to POP all values stored on the stack before issuing the RET or RETI commands. If one does not POP all the 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. Please explain each command in no more than three sentences. 2. What is wrong with the following subroutine? PUSH RET ACC

What kind of problem would you expect the microprocessor to experience? 3. How would one move the stack from address 08H to 80H? Would this move in any way inuence the SFRs? 4. Please explain why the command PUSH A is illegal. How should such a command be phrased?

Chapter 9 Interrupts
9.1 A General Introduction

Interrupt handling for the 8051 is rather simple. Once an interrupt has been enabled, whenever the interrupt occurs a one bit ag is set and the processor jumps tovectors toa xed locationthe location in the interrupt vector table associated with the particular interrupt. (In most cases, once the processor vectors to a location, the processor lowers the ag automatically. In those cases when it does not lower the ag automatically, the programmer must have the interrupt subroutine lower the ag.) For example, when external interrupt zero occurs, the processor sets the IE0 bit, vectors to location 0003h, and then clears the IE0 bit. If an interrupt occurs while the processor is already dealing with an interrupt, then the processor raises the relevant agto remind itself that an interrupt has occuredbut continues to handle the interrupt it started handling. When it nishes with the interrupt it is handling, it then vectors to the interrupt whose ag is raised.

9.1.1

Enabling Interrupts

To enable a particular interrupt, two things must be done; interrupts must be enabled globally, and the interrupt of interest must be enabled as well. To enable interrupts, certain bits must be set in the interrupt enable register. (See p. 6 of the 8051 Users Guide for more detail about this register.) This register is bit addressableand the bits are given names in MOD52 which is a header le for the 8052 type peripherals and in MOD841 which is the header le for the ADuC841. (Items that exist in both processors are given the same name in each le.) 49

50

CHAPTER 9. INTERRUPTS

One must set the EA bit. This bit enables interrupts globally. If this bit is not set, no interrupts are active. If one would like to enable external interrupt zero, one must also set EX0the bit that enables the zeroth external interrupt.

9.1.2

Some Facts about the External Interrupt Pins

In the case of the external interrupts, there is another bit whose value must be chosen. This is IT0which determines whether the zeroth external interrupt is edge triggered or level triggered. If IT0 is set to 1 then the interrupt is edge triggered, and if IT0 is zero then the interrupt is level triggered. As the external interrupt pin is also an I/O pinit is pin two of the third portwe must make sure that the I/O pin is set in a way that will allow it to operate as an input. Port three is an open drain port, and there are internal pull-ups. Thus, a one written to this port does not force a value on the port; it lets the output oat and relies on the pull-up resistors to hold the value high. To use this pin as an input, one writes a one to itusing the command SETB P3.2. (For more information about the I/O pins, see Chapter 15.)

9.2

Bounce

When one closes a switch, the switchs contacts generally bounce for a little while (on the order of milliseconds). One way of correcting this problem is to build a circuit that responds to one change of voltage and then ignores all changes that occur in the, say, 50ms after the rst change.

9.3
9.3.1

The Experiment
Part I

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

9.3.2

PartII

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

9.4. EXERCISES

51

When external interrupt 0 is asserted, the microprocessor vectors to 0003H. In the new program, have the interrupt subroutine change the status of the LED and have it clear the interrupt enable bit, EX0. This will stop the microprocessor from paying attention to interrupts of this type until the bit is set again. In the interrupt subroutine, set a user dened ag to inform the main program that an interrupt has occurred and then return to the main program. In the main program, after performing all the initilizations, have the processor repeatedly check the ag you use in the interrupt subroutine. (You may want to use a command like JNB FLAG, $.) If the ag is set, then the processor knows that an interrupt has occurred that the button has been pressed. Have the processor clear the ag and delay for 200 ms. At the end of the 200 ms delay, have the processor clear IE0. (Clearing this ag stops the system from responding to bounces that occured while the program was wasting time in the delay loop.) In this way if there was switch bounce in the 200 ms period, the bounce will not cause the LED to blink. This is one way of debouncing a switch. After clearing IE0, have the processor set EX0 again. After setting EX0, have the processor start checking the status of the user ag again. In this way the processor will not react to bounces, but will 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 interesting tricks 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 and separate bits for each interrupt? 2. How long does it take for a switch to stop bouncing? Please cite a source (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 microseconds. A common example is sampling. One generally needs to sample a signal on a regular basis. Another task that one often wants to do regularly is to poll a peripherala keypad for instance. To allow one to accomplish such tasks microprocessors and microcontrollers generally provide timerson-chip peripherals which can be set to interrupt 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 timers register overows, it causes an interrupt. These devices are peripherals, external to the microprocessors core, with a built-in interface to the microprocessor. One does not have to let the registers be incremented every instruction cycleone can have the register be incremented every time the voltage on a specic pin goes from high to low. In this way one can use the timer to count the number of events that occur. For this reason the timer is generally referred to as a timer/counter. Once again when the register which is being incremented overows, an interrupt is asserted. The ADuC841like the 8052 on which it is basedhas three general purpose timersTimer 0, Timer 1, and Timer 2. Timer 1 and Timer 2 can be used to set the baud rate of the UART. In addition, the ADuC841 has a fourth, special purpose timer, Timer 3, which can be used to set the baud rate 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 the ADuC841. (The information about the timers starts on p. 60.) We present an introduction to the control of the timers here. The rst two timers, Timer 0 and Timer 1, are controlled using two of the SFRsTMOD and TCON. The nal timer is controlled by way of the register T2CON.

10.2.1

The TMOD SFR

TMOD is not bit addressablethus one must write to the whole register anytime one wants to set even one bit. Bit 7 is used to gate Timer oneand is not of interest to us. It should be set to zero. Bit 6 determines whether timer/counter 1 is a timer or a counter. It must be set to make the timer/counter act as a counter and cleared to make it behave as a timer. Bits 5 and 4 are M1 and M0 respectively. These are the mode select bits. In mode 1in which M1 is cleared and M0 is setthe two eight bit registers TH1 and TL1 are cascaded to form one 16 bit register. In mode 2in which M1 is set and M0 is cleared TL1 is incremented each clock cycle, and upon overow it is reloaded with the value stored in TH1. Mode 2 is called auto reload mode. Bits 3-0 have the same functions as bits 7-4, but they apply to timer/counter 0. Mode 0which we have not discussedis dierent for the two halves of the register. For more details, see p. 30 of the Users Guide. The two eight bit registers associated with timer/counter 0 are TH0 and TL0. Note that when the microcontroller is powered-up, most of the registers assume default values. These values are given in the data sheets at the point at which the peripheral is described. In the case of TMOD, the default value is 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 assembler expects to see as the operands of bit instructions.

10.3. HOW TO SET-UP THE TIMER/COUNTERS The bits purposes are as follows:

55

Bit 7known as TF1is set when timer/counter 1 overows. It is cleared by the hardware when the PC vectors to the ISR. Bit 6known as TR1is set in order turn on timer/counter 1. It is cleared to turn o timer/counter 1. Bit 5known as TF0is set when timer/counter 0 overows. It is cleared by the hardware when the PC vectors to the ISR. Bit 4known as TR0is set in order turn on timer/counter 0. It is cleared to turn o 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 automatically. However, as with all interrupts, in order for the processor to deal with an interrupt, interrupts generally must be enabledbit EA must be set and the particular interrupt of interest must be enabled as well. In our case the bit that enables Timer 1 is called ET1, and the bit that enables Timer 0 is called ET0. (Once again, the names of all the named bits and bytes are given in the le c:\ADUC\mod52 for the 8052 compatible portions and in the le c:\ADUC\mod841 for ADuC841 and 8052 items.) Also, one must know where the processor vectors to when the interrupt is asserted. When the Timer 0 interrupt is asserted, the processor vectors to 000Bh. When the Timer 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 every millisecond and to toggle the LED each time it asserts an interrupt. We must dene the timer/counter as a timer, see to it that the associated register TH0, TL0 overows once per millisecond, and we must see to it that the associated interrupt subroutine causes the LED to toggle. The evaluation kit has a 11.0592 MHz crystal. Thus, the instruction clock period is 1/11059200 = 0.0904s. The number of instruction clock ticks in 1 ms is 11059.2. As one cannot have a fractional clock cycle, we will count 11059 ticks before asserting a timer interrupt. The total time to count 11059 ticks is 1.0000 ms.

56

CHAPTER 10. THE TIMER INTERRUPTS

We want to start the register pair TH0, TL0 with a number that is 11059 from 10000hfrom one more than the highest number that a pair of eight bit registers can hold. The number we want held is D4CDh. That is, we want to initialize TH0 with 0D4h and TL0 with 0CDh. In fact, each time that the register overows and the interrupt service routine is called the registers must 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 the timer registers. Also, reloading the registers by hand will not give perfectly accurately spaced interrupts. To achieve such accuracy, one one must check the value of the register immediately before reloading it. Then one must subtract the relevant amountan amount that must take into account the value 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 per second. Check that your program works by examining the output of pin P3.4 using an oscilloscope. You may use the somewhat inaccurate results you get by using mode 1 of the timer without compensating for the few clock cycles that the reload operation requires.

10.5

The Report

Submit the assembly language le you wrote. Make sure that the le is properly commented. The le will be graded on conciseness, clarity, and completeness.

10.6

Exercises

1. Suppose that one uses Timer 0 in mode 2. What is the maximum time between timer interrupts given an 11.0592 MHz crystal? 2. Please detail how TMOD, TCON, and TH0 must be set in order to cause Timer 0, when operating in mode 2, to have as much time as possible between interrupts. Make sure that Timer 1 is not operational. 3. Show how to change bits 4-7 of TMOD without aecting bits 0-3. You may want to use the ANL and ORL commands.

Chapter 11 The Integrated Development Environment (IDE)


11.1 Introduction

Modern programming languages often come equipped with a program that is designed to make using the language easier. These programs provide an environment that often includes a word processor, a compiler, a debugger and other features. Such super-programs are generally referred to as integrated development environments or IDEs. When one rst starts to use an IDE, the IDE usually seems very complicated. Once one gets used to working with the IDE one nds that the tools it gives one can be very helpful. There is a rather standard IDE for the 8051 family of microprocessors that is produced by Keil Elektronik GmbH. This IDE includes a context sensitive editoran editor that highlights the various 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 a project, for each new set of programs. This object includes links to all of the les that are used by the given set of programs, and it stores the settings that 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 Analog Devices chip, click on Analog Devices. In the list that opens up, click on 57

58CHAPTER 11. THE INTEGRATED DEVELOPMENT ENVIRONMENT (IDE) ADuC841. Then click on OK. This tells the IDE what chip you (and it) are working with. Next you must open a le. Go to File on the tool bar. Then click on New. This will open a le in the main window of the IDE. Now, in the File menu, go to Save As and save the le as my_file.asm (where you can use any name instead of my_file). Using the .asm extension is important to the IDE. It tells the IDE that the program is being written in assembly language. This causes the editor to highlight assembly commands (rather than C commands). Next, right click on the Source Group subfolder of the Target 1 folder in the Project Workspace window. Click on the Add Files to Group tab, and add the le 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 match the frequency of the crystal on the evaluation board. Then go to the output tab and check the create HEX File option (which will cause the IDE to create a .hex le after compiling the program) and go to the Utilities tab and pick the ADI Monitor Driver (which will then allow you to load programs to the evaluation board using the IDE).

11.3

Writing the Assembly Language File

An assembler looks at a text le and converts the mnemonics used into machine readable (but person unreadable) commands. The IDE has an assembler. It is possible to tell the IDE to recognize all 8051 commands and register namesand this is the assemblers default setting. This setting makes it unnecessary to include denitions of the SFRs as long as one is only using the 8051s SFRs. If one is using 8052 or ADuC841 SFRs then one must dene the names of the SFRs one is using. The easiest way to do this is to add a directive to the compiler telling it to include the relevant le. If, for example, one needs to include the denitions of the ADuC841s SFRs, then one adds the line $include (MOD841) to the begining of ones program. Because this le denes all the SFRs that exist in the ADuC841, including those SFRs that exist in the 8051, it is important to tell the IDE not to dene those SFRs by default. To stop the IDE from automatically denig the 8051s SFRs, right-click on Target 1 in the Project Workspace, click on the A51 tab, then un-check the box labeled Dene 8051 SFR Names, and then click on OK. If one does not un-check this box, when one compiles the le the compiler complains that one is attempting to dene an already dened symbol. After saving the assembly language le, one goes to the project window (or

11.4. DEBUGGING THE PROGRAM INC JMP END A WHO

59

; Jump to location who. ; 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 assemble the code and will point out any errors or problems with the code. If one double clicks on a line in the Output Window (where the error messages are given) the IDE will take one to the line in which the error occurs. This can make debugging somewhat simpler.

11.4

Debugging the Program

Once one has compiled a program without receiving any error messages, it is time to start trying to eliminate errors in the programs underlying structure. One way to do this is to use the IDEs debug facility. To start the debugging process, go to the Debug tab on the toolbar, click it, and then click the Start/Stop Debug Session tab. This causes the IDE to prepare to simulate the program that has been built. Upon starting the debug session, one will nd that the Project Workspace window opens. This window allows one to see the values of the 8051s eight general purpose registers, and a host of system registers. Additionally, the debugger will also inform one of the number of statesthe number of instruction cyclesthe microprocessor has passed through and the number of seconds that have passed. (This latter number is based on the crystal frequencywhich was entered previously.)

11.5

An Example

Let us use the debugger on the simple program of Figure 11.1. Please enter this program and build it. Note that the assembler ags an error. The assembler returns: myfile.asm(2): ERROR A45: UNDEFINED SYMBOL (PASS-2). That seems to be saying that there is an undened symbol somewhere. Clicking on the line, the IDE ags the second line of the program. One notes that the symbol whowhich should refer to a location in the codeis undened. Changing the rst line to:

60CHAPTER 11. THE INTEGRATED DEVELOPMENT ENVIRONMENT (IDE) who: INC A ; Jump to the location who

and building the le again, we nd 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 progresses through the program, and note how the registers in the Project Workspace window change. One can make changes to a le while in debug mode. However, one must stop the debug mode before one can build the le again.

11.6

Other Helpful Features

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

11.6.1

Running the Program in the Debugger

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

11.6.2

Breakpoints

One can insert a breakpoint at any point in the program. One does this by right-clicking on the line of interest and then clicking on Insert/Remove Breakpoint. Whenever the IDE reaches a breakpoint, it stops execution of the program. This makes it easy to check the microprocessors status at that point.

11.6.3

Peripherals

Examine the Peripherals tab. Note that there is a sub-tab for almost every peripheral one might want. The IDE is pretty good about letting one examine what ones peripherals would be doing on the ADuC841. (In my experience, 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 watch ones 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 type F2 to edit, click on F2, and then type the name of the variable in which one is 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 click on logic analyzer window. When the window opens, click on the setup button (at the upper left of the window), push the insert key, and then type the name of the variable you would like to have displayed. The IDE has many more features, but the ones mentioned should be enough to get you started.

11.7

The Experiment

Please write a program that causes the LED connected to P3.4 to blink once each second. Use Timer 0 in mode 2 to control the period. Use the IDE to write the program, and examine the program using the debugger. Make sure to make use of the I/O ports tab in the Peripherals menu. Use the watchlists, 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 ADuC841 and make sure that the program actually runs correctly.

11.8

The Report

Please submit a completely commented program as the lab report. If the program behaved dierently from the way the IDE predicted, please submit a brief description of the dierences and your best guess as to why there were dierences.

11.9

Exercises

1. If one uses the WSD program to download and run a program, then when one nishes giving the ADuC812 the RUN command, a few of the SFRs are not left initialized to their values after reset. In particular, TR1 is set after the RUN command. (The ADuC812 is almost identical to the ADuC841. The ADuC841, however, does not corrupt TCON

62CHAPTER 11. THE INTEGRATED DEVELOPMENT ENVIRONMENT (IDE) in this fashion.) Suppose that a student has a program that does not work on the IDE, but decides to download the program to the ADuC812. (The student is very stubborn and refuses to try to debug the program.) The student nds that the program does run on the ADuC812. Without assuming that the IDE does not work correctly, explain why the program might work on the ADuC812 while it does not work properly when simulated on the IDE. (What programming errors might the student have made?) 2. In the Project Workspace window of the Keil IDE, there is a register called sp. Please nd 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 ones microprocessor to another microprocessor and the two devices must talk to each other. One of the standard methods of connecting microprocessors (and computers generally) is to use a Universal Asynchronous Receiver Transmitter (UART). Here we give a brief introduction to the UART provided with the ADuC841. The complete UART 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 rst parameter that one must understand is the baud1 rate. The baud rate, given in symbols per secondin the case of our UART, bits per second (bps)is the number of symbols that the UART transmits or receives per second. Next one must understand how the UART encodes information before transmitting the information. When passed n bits to transmit, the UART always prepends one extra bita start bitto the beginning of the transmission, and it appends one, one and a half, or two bitsstop bitsto the end of the transmission. The UART can also add a parity bit between the end of the data and the stop bit(s). When one sends 8 bits using a UART running at 19200 baud, without parity, and with a single stop bit, how long does the transmission take? Each bit takes 1/19200 seconds. As there are eight data bits, one start bit, one stop bit, and no parity bit, there are a total of 10 bits. Thus, the total time to transmit the byte is 10/19200 = 1/1920 = 0.52ms.
1

Named 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 relatively easy to control. The most complicated part of its control is setting the baud rate. There are several ways of controlling the baud ratewe will not discuss all of them. The SFR that controls the UART is the SCON register. SCON is a bit addressable 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 variable baud rate mode. We will see how one sets the baud rate later. Bit 5 SM2 is the multiprocessor communication enable bit. We will not tamper with this bit. Bit 4 REN is the serial port receive enable bit. This bit must be set to 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 ag. This bit is set when the UART has nished transmitting a byte. Because there is only one serial port interrupt, the processor must have some way of informing the user whether the interrupt was triggered by the end of the transmission of a byte or by the reception of one byte. This bit and bit 0 allow one to determine what the cause of the interrupt was. Bit 0 RI is the serial port receive interrupt ag. It is set when a byte has been received. Note that TI and RI are not cleared by the ADuC841. They must be cleared in the interrupt subroutine. If one is interested in sending and receiving 8 bits of data in variable baud rate mode, one sets SM0 to 0, SM1 to 1, SM2 is left alone, and REN is set to 1. Next one must set the baud rate. This is done by setting Timer 1, Timer 2, or Timer 3 to overow at an appropriate rate. We will now consider how to use Timer 1 to set the baud rate. (See Chapter 14 for detailed instructions about the use of Timer 3.) When using Timer 1, the baud rate is set by: baud rate = 2SM OD (Timer 1 overow rate). 32

12.3. WRITING A STRING TO THE UART

65

Note that SMOD is bit 7 of PCON, a non bit-addressable special function register (SFR). To change the value of one bit of PCON one must or its current contents with a byte that is one in its seventh bit. When using Timer 1 to control the baud rate, the Timer 1 interrupt should be disabled. One neither needs nor wants to interrupt the processor each time the timer register overows. Also, if the timer produces no interrupt, it must be reloaded automaticallyit must be run in mode 2. To enable the serial interrupt, one must set the serial interrupt enable bit, ES. As always, when an interrupt is asserted, the processor vectors to a specic location. In the case of the serial interrupt, the processor vectors to 0023h. In order to send a byte when the UART has been set up, one moves data to the serial buer, SBUF. The UART will start transmitting the data when SBUF is written. In order to read data from the UART, one reads from SBUF. Physically, one is reading from a dierent location from that which one writes to by writing to SBUF. Since one never needs to read from the transmit buer or to write to the receive buer, the two buers share a register.

12.3

Writing a String to the UART

In order to write a string to the UART without wasting massive amounts of time, one uses the transmit interrupt. Suppose that one wants to transmit a string. One transmits the rst letter of the string, and then one tells the UART (by programming it with an intelligent interrupt service routine) that each time it nishes transmitting one byteeach time a transmit interrupt is receivedit 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 one needs 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 cable that is included with the evaluation board to connect the board to the PC. Write a program that echos all characters transmitted to the UART back to the computer. Use Timer 1 to control the baud rate, and remember to set the computers baud rate to the same baud rate that you choose. Note that as you are always transmitting one character at a time, you do not need to use 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 to this event.) Note that the UART transmit pin is P3.1 and that this pin is available on the evaluation board. Use a digital oscilloscope in normal mode to observe the output of P3.1. In a brief comment added to the code you submit, explain how the signal that you observe on the oscilloscope agrees with what we have seen about the UART.

12.5

The Report

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

12.6

Exercises

1. Use the formula on p. 64 of this manual to calculate values of SMOD and TH1 that correspond to a baud rate of 19,200 baud. 2. What is the lowest baud rate one can achieve in our system when using Timer 1 in autoreload mode? 3. Most interrupts have bitsagsthat when set indicate both to the internal operations of the processor and to the user that an interrupt has been asserted. The TI and RI ags perform this function for the UARTs transmit and receive interrupts, respectively. Because these ags are not cleared by the processor when the processor vectors to the interrupt, the ags must be cleared by the user in the interrupts subroutine. (a) What is the equivalent ag for the Timer 1 interrupt? (b) Does this ag need to be reset by the user? (Please provide a reference for you answer.)

Chapter 13 Using the Onboard UARTPrinting a Preprogrammed String


13.1 General Introduction

In order to communicate with the outside world, one must often send messages. Generally speaking the set of messages one might wish to send is knownsave perhaps for some numbers that may be a function of what is going on. We are going to store our strings as C-type null-terminated strings. That is, we are going to store each string with a zero at the end. We will store the string in the program memory. We will then read the string and send it to the 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 dierent commandMOVC. Also, strings must be stored in the code segment. For this we make use of the DB directive. Also, we must learn how to properly make use of the transmit interrupt.

13.2
13.2.1

The New Commands and Techniques


Reading from the Code Segment

To read from the code segment one uses the command MOVC. This command is covered on p. 41 of the 8051 Programmers Guide and Instruction Set. The form of the instruction that we will use is MOVC A, @A+DPTR. This instruction 67

68CHAPTER 13. USING THE ONBOARD UARTPRINTING A PREPROGRAMMED ST loads the accumulator with the value stored in location A + DPTR. DPTR is the data pointer register. The accumulator (the register to which A refers) is initially loaded with the oset from the value stored in DPTR. In a standard 8051/2, DPTR is a 16 bit register. (In the ADuC841, in order to make it possible to address more memory, DPTR can also function as a 24 bit 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 word into the (lower 16 bits of the) register. The 16 bit version of this instruction is described on p. 41 of the 8051 Programmers Guide and Instruction Set.

13.2.2

Some Assembler Directives

Sometimes one needs to store items or reserve space in various memory segments. Most commonly the data is stored in the the code segment and space for temporary storage is reserved in the data memory segment or the bitaddressable memory. The details of how this is done can be found on pp. 42-45 of the 8051 Cross Assembler Users Manual. To reserve space in the data segment, one must rst use an assembler directive 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 that tells the assembler where in the data segment to start from. This is important as the lowest section of the data segment should not be used for simple storage. The rst 32 bytes of the data segment are general purpose registers. The next 16 bytes are the bit-addressable memory. I advise using the command DSEG AT 30H. This tells the assembler to start from byte number 30Hwhich is the 49th byte. Having told the assembler that you want to reserve space in the data segment, one must next tell it how much space to reserve. If one would like to reserve one byte and have the ability to refer to that byte as MAX, one uses the command MAX: DS 1. One can now use MAX any place that you could have used a location in memory. To store data in the code segment, one uses the DBthe data byte directive. This directive tells the assembler to store the bytes that follow the directive in the code memory. One can give a name to the location from which the assembler starts storing the data as well. Consider the following commands: ORG 0100H NAME: DB DB

This course is; Here is the first part of the string. great. ; Here is the second part. Breaking ;it in two does not affect anything.

13.3. THE EXPERIMENT DB DB DB 13 10 0

69 ; Carriage return. ; Line feed. ; 0--the infamous null-termination.

Assuming that one is in the code segment (or adding the command CSEG before ORG 0100H), the rst line tells the assembler to move to position 100H in the code segment. This puts the data at a point that is relatively far from the actual program. The next command says to assign the name NAME to the current location. Next we see one of the nice features of the assembler. If one uses single quotes, then the assembler knows to store the ASCII values of the characters between the quotes one after the other. The numbers 13 and 10 are carriage return and line feed. The zero that appears at the end is the null-termination. Finally to reserve bits in the bit-addressable segment, one must rst switch to that segmentusing the BSEG command. Then one uses the command DBIT. For example, to reserve space for the ag TRIGGERED, one uses the command: TRIGGERED: DBIT 1

This reserves one bit for the ag.

13.2.3

Writing a String to the Serial Port

Because the UART is so much slower than the processor, one does not write a string all at once. What one does is, one writes a byte to the UART and then continues with ones main program. Then one has the UART send the next byte when a transmit interrupt is received. One causes ones program to 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 that an interrupt has occurred even when that is not the case. To cause such an event, one must set the relevant interrupt ag. For example, to cause a transmit interrupt, one must set the TI ag.

13.3

The Experiment

Write a program that writes stringsthat you have saved in the code segment as a null-terminated stringto the serial port whenever the user types one

70CHAPTER 13. USING THE ONBOARD UARTPRINTING A PREPROGRAMMED ST of the characters a, b, c, or d. Use dierent strings for each character. Ignore all characters that are typed while the string is being sent to the UART. Make sure to use the IDE to simulate the program before the program is run. This may save hours of work debugging the program!

13.4

The Report

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

13.5

Exercises

1. In general instructions for the ADuC841 (and the 8051 family) refer to 8 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 codefor this instruction? Explain why the existence of separate codes for dierent forms of an instruction makes it easy to have both 8 bit and 16 bit forms of an instruction. 2. Why is there no instruction to allow one to move information into program memory while the microprocessor is running? (Please consider the nature of the program memory in your answer.) 3. Please explain why it is important to clear the transmit and receive ags once the processor has vectored to the UART ISR. (Any reasonable answer 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 determine which 3 SFRs hold the 24 bits of the register DPTR. 6. Using the MicroConverter Quick Reference Guide, please determine whether INC DPTR acts on 16 or 24 bits of DPTR. Also, check whether MOV 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 8052 has an additional timer, Timer 2. All three of these timers are relatively general purpose. The ADuC841 has a fourth timerTimer 3. This timer is designed to do one thing and one thing onlyto provide a clock to the UART. 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 added to 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 in Chapter 13however 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 rst is T3CON and the second is T3FD. T3CON is not bit addressable, and its default value 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 UARTs 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 considered a single three bit binary word. 71

72

CHAPTER 14. TIMER 3

The second register, T3FD, contains a single number between zero and 255. The baud rate that Timer 3 provides is: baud rate = 2 fcore DIV 1 (T 3F D 2 + 64) .

Here fcore is generally 11.0592 MHz for our board. The recommended method of calculating the two numbers is to rst calculate: DIV = oor log2 fcore 16 Baud Rate .

Next one calculates T3FD according to the formula: T3FD = round 2fcore 64 . Baud Rate

2DIV1

Finally the actual baud rate will be given by: Actual Baud Rate = 2fcore DIV1 (T3FD 2 + 64) .

14.3

The Experiment

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

14.4

Exercises

1. Please produce an Excel spreadsheet or a MATLAB program to calculate 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, pin n of port m is referred to as Pm.n. Each pin of a parallel port can be thought of as a device built from a switch and some peripheral circuitry as shown in Figure 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
15.2.1

How the Parallel Ports Operate


The Connection between the Registers and the Pins

The pins on each port are individually addressable by using the bit addressable registers P0, P1, P2, and P3. To address the third bit of port 3, one writes P3.2. (Keep in mind that the rst bit is bit 0.) Note that P3.2 sometimes refers 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. When one sets a bit of register Pm.n, the controlling circuitry makes changes to the status of pin n of port m. To the programmer the register and the pins form two 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 an input or an output. Let us rst 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. In this way, the output voltage is not changed by loading eects. When one writes a zero to Pm.n the switch in Figure 15.1 closes. This causes the output of the pin, vo , to be shorted to ground. Thus the output will be zero. When one writes a one to Pm.n the switch in Figure 15.1 opens. In ports 2 and 3, the examination pointthe point from which vo is read is connected to VCC through a resistor. As long as a very high impedance load is all that is connected to the examination point, there will be very littleapproximately nocurrent owing through the resistor. Thus, there will be no voltage drop across the resistor. This causes the output of the pin to be VCC . VCC is dependent on the supply voltage of the chip; in our case it is 5 V. The resistor connected between VCC and the output is called a pull-up resistor. Its function is to pull-up the voltage at the output when the switch is open. In port 0, the resistor and power supply connection are absent. When a one is written to P0.n all that happens is that the output of the pin oats. Thus, the output pins of port 0 are either forced to groundwhen a zero is written to a pinor are allowed to oatwhen 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 o 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 written the output will be forced to zero. When a one is written the output is pulled up to 3.3 V by the external supply and pull-up resistor. Note that each pin of port 0 can be run at a dierent voltage. Port 1 is an input only port, so the 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 will see that these registers can also be used to examine the values of the pins which they control. Moreover, it is possible to write one value to a port and to read a dierent value from the port. How can that be? When one writes to registers P0, P2, and P3 one is actually writing to a 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 zero to the latch causes the switch to be closed. When one checks the value of Pm.n using the JB or JNB commands, one causes the microprocessor to check the voltage physically present on the pin Pm.n. If the voltage corresponds to a logical one, then the bit is considered set and JB or JNB sees a one. If the voltage on the pin corresponds to a logical 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 read the value of latchread the current setting of the switchrather than the voltage 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 used to read a bit that is connected to a port, the command checks the current status of the latchand not the voltage on the pin. For more on this general topic, 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 rst thing that one must do is write a one to the relevant pins. Why? Because if a zero is written to a pin, then the pins internal examination point (see Figure 15.1) is shorted to ground and the only voltage one can ever see at that point is zero. Assuming that a one has been written, the switch at the relevant pin is open, and one can 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 should be either 0 V or VCC . In fact, however, the wise designer follows a slightly dierent path. The wise designer sets up the system so that when a zero is to be input, the voltage on the pin is forced to zero. When a one is to be written, the pin is allowed to oat. Because of the pull-up resistor, when no voltage is applied to a pin, the examination points voltage is pulled-up to VCC . In this way, it is impossible to damage ones system by accidentally applying a voltage to a pin whose output is currently shorted to ground. This is an example of belt-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 pinor analog inputswhen 1 has been written to the appropriate pin. It is perfectly legal to have some pins be digital inputs while others are analog inputs.

15.2.6

Alternate Functions

Many portsor individual pins on portscan serve one of several purposes. Ports 0 and 2 are used to control the external memory if there is any, and on the ADuC841 port 1 can be used either for digital or analog input. Additionally some of the pins on port 1 have alternate functions, and all of the pins on port 3 have alternate functions. The parallel ports are described on p. 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 a port opens the switch associated with that pin. Thus, SETB P3.4 opens the switch associated with pin four of port three. Any command that reads from one of the bits associated with a port returns the current status of the pin associated with the bit. If pin 5 of port 3 has been shorted to ground, the command JB P3.5 HIGH will not jump to the location HIGH even if the last operation performed on the bit P3.5 was SETB P3.5. The command will just cause 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 pin 3.2. If the pin is high send a message to the PC that will print out a message that the pin is high. Similarly, if the pin is low, send a message to that eect. If any other keys are hit, make the PC beep by using the bell or give some other indication that an error has occurred.

15.4

The Report

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

15.5

Exercises

1. Read the material in The Programmers Guide that explains the use of the CJNE command. Please explain in 3 sentences or less how the command works. 2. If the pin associated with port 3 pin 2 is connected to ground and one sets 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 several functions. 4. Explain the expression belt-and-suspenders. Why will a good engineer often perform designs in this way? 5. If one clears P3.0 and then connects a 5V source to pin 0 of port 3 on the ADuC841, what will happen? Note that doing this is clearly a very bad 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 and that prints the time to the serial port. To do this, we use the ADuC841s third timer. We must understand Timer 2. Additionally, in order to print the time to the serial port, one must create an 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 the ADuC841. (The information about the timers starts on p. 60) We present an introduction to the control of Timer 2 here. Timer 2 is controlled by T2CON.

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 overows. TF2 must be cleared by the user in the Timer 2 interrupt service routineotherwise the interrupt will be triggered again. TF2 is not set if Timer 2 is used as the transmit or receive clock for the UART. (This is done by setting TCLK 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 clock of 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 clock of 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 as a counter. When set, the timer functions as a counter. When cleared the timer functions as a timer. Bit 0, CAP2, will generally be set to zero in our applications. This sets the timer to automatically reload on Timer 2 overow. Timer 2s registers TH2 and TL2 are reloaded from the registers RCAP2H and RCAP2L.

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 rst subroutine initializes all relevant pointers and the second, the Serial ISR, sends out a new character as each old character is sent. Previously we have needed to transmit one of a xed set of strings. We stored the xed strings in the code memory. We must now store the variable string in the data memory and the program must compose the string. Alter the code that was used to output the xed string to allow it to handle runtime 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 be done later. The ISR should raise a ag (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 many active interrupts, these practices are not followed. As a rule, however, they should be. Also, if one cannot reserve registers for specic ISRs, then when an ISR is 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. In this 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 baud rate of 19,200 baud. Use Timer 2 as the time base for a clock. Note that when Timer 2 is set to run in autoreload mode, it reloads a 16 bit word from the register pair RCAP2H and RCAP2L. This allows one to use Timer 2 to produce relatively infrequent interrupts. Use Timer 2 and a set of software counters to keep track of the minutes and the seconds since the program started or since someone zeroed all the counters. Output the elapsed time via the serial port every minute. Use the format hh:mm:ss. Make sure that your clock works properly until at least 99 hours and 59 minutes have elapsed. (To test your clock, you can use reload values that make the Timer 2 interrupt occur much more rapidly than will be needed in the nal program.) Also, allow the user to type in a one letter command to reset all the counters and restart the clock.

16.4

The Report

Submit the assembly language le you used, and make sure the le is properly commented. 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 is running in its autoreload mode? Why is this dierent from Timer 0 and Timer 1? 2. Why cant 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 interrupt subroutine and restore it at the end of the subroutine if one is going 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 8052 compatible microprocessor) to measure the number of pulses appearing on pin P3.4 in each second. It also allows the processor to upload the number to a host using the UART. No new peripherals are introduced in this lab, but it is the rst 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 in the 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 one of 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 register pair, we can run it in reload mode while allowing it to use two cascaded 8bit registers. This allows it to generate relatively infrequent interrupts. As 83

84

CHAPTER 17. A COUNTER

we shall want to produce interrupts once a secondvery infrequentlywe choose 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 ag every second. Have the main program read the value of the counter 0 counter each second, and zero the counter immediately after reading it. Write a simple routine to take the 16-bit word you have read and convert it into a string that will print a 4 digit hex number when sent through the UART. Have the microprocessor upload the string each second.

17.4

The Report

As usual your report consists of two parts. You must submit the assembly language le you usedand the le must be properly commented! Also, you must submit a written report explaining in somewhat more detail what your program does. The report will be graded on conciseness, clarity, and completeness.

17.5

Exercises

1. When one speaks of raising a ag one means setting a particular bit to 1 or true. What instruction is used to do this? What instruction is used to test if a bit is set? 2. Explain why it is easier to convert a number stored in binary to hex than 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 k columns of wires. There is a key that sits at the junction of each row and columnthere are j k keys. Pressing down on the key at the junction of the j th row and the k th column shorts the j th wire to the k th wire. (See Figure 18.1.) By experimenting intelligently with a DVM set to work as a continuity tester, it is possible to determine which of the pins on the keypad connector connects to which of the rows or columns. In this lab, we will be using a 4x3 keypad, and it is pretty simple to work out the connections. We will connect the keypad to port 2one of the parallel ports that have pull up resistors. The rst pin on the keypad is led to pin P2.0 on the ADuC841. The way that one checks which key has been pressed is by lowering the voltage on one row of keypad and then checking each of the columns to see if the voltage on the column has gone low as well. If it has, then the button that sits at the junction of that row and that column has been pressed. One proceeds 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 a second. Each time a key is pressed, we send the appropriate character to the UART. Please write a program that uses Timer 2 to generate an interrupt every 5 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 represents a push-button switch. voltage on a row and then check to see if the voltage on any of the columns has gone low as well. Please use Timer 1 to drive the UARTs clock so that the UART runs at 19200 baud. Do not enable the serial interruptit is not necessary. When a character is detected send the appropriate ASCII value to the UART and then return from the Timer 2 interrupt. (Note that if one presses several keys at once, one will only be informed of the rst one that one checks. After nding one character the program returns from the interrupt subroutine. Also note that as one is sending 10 bits at 19200 baud, the total time that the transmission takes is 1/1920 0.5ms. Thus there is no need to worry that one will need to send one character before the previous charactersent 5ms agois nished transmitting.) There is one complication. As described, the program checks the keypad every hundredth of a second and sends the value of the depressed key. This is not normally what one wants to do. One generally wants to send a message to the computer each time a new key is pressed. First write a program that sends a character to the serial port every hundredth of a second if a key remains depressed. Next, write a small separate program that raises a (one bit) ag and causes the LED (at pin P3.4) to light up whenever any key is pressed and lowers the ag and turns o 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 being pressed.

18.3

The Report

Please submit three carefully commented programs and a brief report detailing the work you did. Remember that the report will be graded on completeness, correctness and conciseness.

18.4

Exercises

1. Why is it important to this experiment that Port 2 has pull-up resistors? 2. In implementing the programs for the experiment, one might want to check to see if a bit is not set. What command would one use to check this 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 this lab we consider a very simple way that uses peripherals available on pretty nearly any microprocessorincluding an ordinary 8051 or 8052. We consider a one-pin D/A. The basic idea is to have one pin of ones microprocessor output a signal whose average value is proportional to the value of the digital signal one would like to output. Then one follows the pin with a low-pass lterperhaps a simple RC circuit. The output of the low-pass lterwhich performs a kind of windowed average of its inputshould be proportional to the instantaneous average of the input to the low-pass. The simplest way to implement such a system using a microprocessor is to have the microprocessor output a sequence of short pulses whose average voltage is the desired voltage. Typically one uses the output of an I/O pin. Thus the output is either (approximately) 5V or (approximately) 0V. One starts a new pulse every TS seconds. Supposing that one one wants an output 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 pulse width modulationPWM.) One passes this signal through a low-pass lter whose cuto frequency is greater than the frequency of the analog signal to be output but is substantially smaller than the frequency of the pulses being used. Suppose, for example, that one wanted to output 2V for 0.1s and 3V for the next 0.1s. One way to do this would be to have a pulse generator generate 5V pulses every 0.1ms. If for the rst 100 ms the pulses were of width 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 lter whose time constant was considerably larger than 0.1ms, then the output of the lter should be just the voltages desired. We implemented such a system using Simulink. The output of the lter is given in Figure 19.1. Note that at t = 0.1s there is a transition region. The output of the lter cannot change instantaneously from one value to anotherthe lter is a low-pass lter. Also, note that the 2V and 3V lines have a certain thickness. This is because the low-pass lter does not perfectly average its input. When using this type of D/A, one must be prepared (and able) to sacrice accuracy for ease of implementation.

19.2

The Underlying Theory

Let us examine how a simple RC low-pass lter works. If i(t) is the current owing through the low-pass lter, then it is easy to see that the voltage drop across the circuit satises: Ri(t) + If we set: w(t)
0 t 0

i( ) d = vin (t). C
t

i( ) d,

19.3. IMPLEMENTATION then we nd that w(t) satises the equation: Rw (t) + w(t)/C = vin (t), w(0) = 0.

91

Solving this equation using the method of variation of parameters, we nd that: 1 t (ty)/RC e vin (y) dy w(t) = R 0 and we nd that the voltage across the capacitorthe output of the lter satises: t 1 e(ty)/RC vin (y) dy. vo (t) = RC 0 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 of the signal large relative to the circuits time constant, and if the waveform being output to the DAC also changes slowly relative to the circuits time constant, this method ought to give an output that is proportional to the desired voltage.

19.3

Implementation

Suppose that one sets Timer 0 to interrupt 100,000 times per second. Let us consider sets of 32 interrupts togetherwe consider each group of 32 interrupts to be one period of our D/A. Let us further assume that we are interested in a 5 bit D/A. We x the duty cycle of the output of some particular pinsay P3.4as follows. If the data we are given to convert, l, satises: 8N l < 8(N + 1), 0 N < 32 then the duty cycle is l/32 %. (As always, l is an eight bit word. Here we only relate to the upper ve bits.) Obviously one must pick a low-pass lter for which all but the DC terms are in the high-frequency regime.

19.4

The Experiment

In this experiment, you will not need to build a low-pass lterwe will make use of your built-in low-pass lter; we will make use of your eye. Using Timer 0 in mode 2, implement a D/A of the type described in the previous section. 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 cause the D/A to blink at you. Because of the frequency of the signal used by the D/A, your eye should see smooth changes in the output of the LED. You should not notice any icker.

19.5

The Report

Hand in a copy of the program that you wrote. Make sure that the program is fully commented. If the implementation caused you any diculties, include comments that detail what the diculties were and how you overcame them.

19.6

Exercises

1. Using either the library or the Internet please determine a reasonable value for the time constant of the average human eye. Please reference your source properly. 2. The digital outputsthe I/O pinsdo 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 near 5V when they ought to be 5V. How will this aect the accuracy of a DAC built using the methods described in this chapter? 3. Please explain the diernce 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 modulate the width of the pulse output by the pin. As we saw in Digital to Analog Converters, this is fairly easy to do, though it does take up quite a bit of processor 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 resistor 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. One numbers the switches sequentially starting with zero for the switch that is connected 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 to the 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 switch 2N 1 closes, and the output of the circuit is: 2N 1 Vref . 2N 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 4096 identical resistors, and 4096 switches. This is not a DAC one would want to build by hand. For more general information about the DAC see pp. 38-40 of 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 header le MOD52 which only denes those items on the ADuC841 that also exist on an 8052. Instead one must use the header le MOD841 which denes all the items related to the ADuC841whether 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 DACCON. Bit 7 controls the mode of both of the DACs. If this bit is set to 0, then both DACs run as 12 bit DACs. If bit 7 is set to 1, then both DACs run as 8 bit DACs.

20.3. THE EXPERIMENT

95

Bit 6 If this bit is one, then the DAC 1s output runs from 0 to VDD . If this bit is zero, then the output runs from 0 to VREF . If one does not 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 of DAC 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 DACs input is received, that DACs output is updated. If one would like to update both DACs simultaneously, then one can set bit 2 to 0, update both DACS, and then set bit 2 to 1. Bit 1 determines whether or not DAC 1 is powered on. If bit 1 is one, then DAC 1 is powered on. If it is zero, then DAC 1 is powered o. Bit 0 is the same as bit 1, but for DAC 0. There are four other registers that one uses with the DACs. The register DAC0L contains the low-order byte of the data. (It contains the data when the DACs are running in 8 bit mode.) The lower nibble of DAC0H contains the high-order nibble of the 12 bit input to DAC 0. DAC1L and DAC1H perform the same functions for DAC 1. Additionally, if one would like the DAC to run between 0 V and Vref , then bit 7 of ADCCON1 (MD1) must be set and bit 6 of ADCCON1 (EXT REF) must be cleared! On the evaluation board, the output of DAC 0 appears on pin 9 of the analog I/O connector (J1) and the output of DAC 1 appears on pin 10 of the analog I/O connector. Both outputs are led out through unity-gain buers. (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 a sawtooth wave.

96

CHAPTER 20. USING THE ONBOARD DAC

20.4

The Report

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

20.5

Exercises

1. Please describe a type of digital to analog converter not described in this lab manual. Please give a reference (to a book or a web site) for the 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 two parts: a sample and hold circuit and a circuit that determines the voltage held by the sample and hold circuit. A simple way to implement a sample and hold circuit is to have ones input fed to a capacitor by way of a switch. To sample the input one closes the connection between the input and the capacitor. To hold the sampled value on the capacitor, one opens the switch. (See Figure 21.1.) Because of parasitic resistances, this type of circuit will not hold the sample indenitely; 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 then compare the output of the DAC to the held value. When the two signals are equal (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 is greater than the held voltage or less than the held voltage, one can use the bisection method to organize ones search. This guarantees that one will not need 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 and hold circuit be the output of a multiplexer. The user chooses which of the inputs 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 circuitry enough time to dump the previous channels value before holding the new value. 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 the datasheets. Note that the A/D can only accept inputs between 0V and VREF which is generally 2.5 V. The A/D is controlled by 3 SFRsADCCON1, ADCCON2, and ADCCON3. The values acquired are stored in two SFRs ADCDATAH and ADCDATAL. We describe these registers now.

21.2. IMPLEMENTATION

99

21.2.1

ADCCON1

This register is not bit-addressable. This registers function is described on p. 24 of the datasheets. Bit 7 determines whether or not the A/D is turned on. Bit 7 must be set 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 to use 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 be between 400KHz and 8.38 MHz. The faster the clock is, the faster the conversion is done. As our crystal is an 11.0592 MHz crystal, we must divide the clock by 2. This corresponds to bits 4 and 5 being one. See p. 24 for the other settings. Bits 3 and 2 control the number of A/D clock cycles used to acquire the signal. It is recommended that one use three or more cycles. This corresponds to bit 3 being one and bit 2 being zero. The total time that the A/D takes to convert a value is 15 A/D clock cycles for the conversion, one cycle for synchronization, and the selected number of cycles for acquisitionin our case 3 cycles. In our case the total acquisition time is: 2 19 = 3.44s. taq = 11059200 Bit 1 is the Timer 2 conversion bit. If it is set, then every time Timer 2 overows, the A/D starts a conversion. Bit 0 is the external trigger enable bit. When set it lets the user trigger an 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 the end 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, the A/D starts a new conversion as each old conversion nishes. Bit 4, SCONV, initiates a single conversion when it is set. The bit is reset by the processor when the conversion is nished. Bits 3 - 0 are used to select which channel to sample from. Bit 3 is the high order bit, and bit 0 is the low order bit. The A/D has eight regular channels. The rst channel is channel zero, and the last is channel seven. The A/D has a ninth channel, channel 8, that reads an internal temperature sensor. (This sensor is supposed to output 700 mV when the temperature is 25o C and the voltage decreases approximately 1.4 mV per degree Celsius.) Using channels 9-12 causes the A/D to sample various voltages produced by the ADuC841. Finally, in the DMA mode the STOP instruction is lling all the channel bits with ones.

21.2.3

ADCCON3

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

21.2.4

ADCDATA

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

21.2.5

The A/D Interrupt

When the A/D nishes converting a sample, it asserts an interrupt. In order to enable the interrupt, the bit EADC must be set. Upon receiving an A/D interrupt, 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 input only port, and its default setting has it congured to accept analog input.

21.3. THE EXPERIMENT

101

Thus, no settings need to be changed to use the A/D. On the evaluation board, the inputs to channels 0 and 1 are from pins 1 and 2 of J1the analog I/O connector. (See p. 7 of the ADuC8XX SAR Evaluation Board Reference Guide.) Note that the evaluation board has unity-gain buers for channels 0 and 1.

21.3

The Experiment

In this experiment, we compare three ways of operating the A/D. In each of the following programs, the value read from the A/Dfrom channel 0must be 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 0 from 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 rst frequency for which the output of the D/A looks (approximately) constant when the input to the A/D is a sine 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 often as it can whether or not the samples were ever read. When a new sample comes in, it overwrites the old values stored in ADCDATAH/L. Before downloading the program to the ADuC841, use the debugger to test the program. You will not be able to test the system by inputting a sinewave, but you can test whether or not the A/D and D/A are working properly. To test the A/D and the D/A, go to the Peripherals tab and check both the A/D converter and the D/A converter. When you run the program in the debugger, you will be able to see the inputs to the A/D and the outputs of D/A. By typing a number in the AIN0 box of Analog/Digital Converter dialog box and then moving the cursor to another box, you will be able to change the value seen by the zeroth input of the A/D. If your program is working correctly this should be reected in the value you see at the output of 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 programs are fully commented.

21.5

A Second Experiment

In this experiment we measure the temperature of the ADuC841 chip by reading its internal temperature sensor. Set the ADC to sample from its ninth channelchannel number eight. Set the Timer 2 conversion bit and cause Timer 2 to overow as infrequently as possible. Cause the microprocessor to move the data read by the ADC to the DAC0 each time an ADC interrupt occurs. Run the DAC in 12 bit mode. (You may want to toggle the onboard LED from the ADC ISR. This will give you an indication of whether or not the program is running.) When sampling from the temperature sensor, it is best to set the divide ratio to 32which means that bits 4 and 5 of ADCCON1 should be set to zero. Additionally, bits 2 and 3 of ADCCON1 should both be set 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 output of DAC0 on a scope please gently heat or cool the ADuC841 and watch the scope trace. If you cool the chip you should the trace rise slightly. If you heat the chip you should see the trace fall a bit. You should be able to observe the changes made by placing a nger on the microcontroller if you set the scope to measure the average value of the signal that is appearing on 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 sample from its A/D to a D/A is as follows. Connect a sine wave generator to the input of the A/D. Connect a scope to the output of the D/A. Set the frequency of the sine wave to zero initially and gradually increase the frequency of the sine wave. The rst frequency greater than zero for which one sees a constant output is the sampling frequency of the A/D. Explain why this is so.

21.7. EXERCISES

103

2. One mode that we do not discuss is the DMA mode. Read the information in the ADuC841 data sheets and give a brief description of the DMA mode. (The description should not be more than ve lines long.) 3. Using the library or the world wide web, please nd a description of the Flash 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 nd out what the start-up values (the values held immediately after reseting the microprocessor) of the registers ADCCON1 and ADCCON2 are. (You may nd 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 lter using a microprocessor, one must use the A/D for input, the DAC for output, and one timer to x the sampling period. As we have used all of these peripherals, all that is really left is to choose the sample speed and the lter coecients. The input and output voltages of the simplest analog low-pass (RC) lter satisfy: vout (t) + vout (t) = vin (t). If one samples every T seconds and one approximates the derivative of the output at time nT by: vout (nT ) vout (nT ) vout ((n 1)T ) T

one can then approximate the dierential equation by a dierence equation. Let v (n) vout (nT ). Approximating vout (t) by v (n), One nds that: v (n) = T v (n 1) + vin (nT ). +T T +

22.2

Stability

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

106

CHAPTER 22. DESIGNING A LOW-PASS FILTER

First note that |(0)| M . Next we show that if |(n 1)| M , then v v |(n)| M . To show this note that if |(n 1)| < M , then: v v |(n)| = v T v (n 1) + vin (nT ) +T T + T |(n 1)| + v |vin (nT )| +T T + T + M +T T + = M.

Thus, by mathematical induction, we nd that if the input to the lter is bounded 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 lter mimics the behavior of the analog lter on which it is modeled. To this end, we consider the step response of both lters. As we will see, the two lters behave similarly. Interestingly enough, it is possible to analyze the two lters using similar techniques.

22.3.1

The Analog Filter

Suppose that the input is a constantthat vin (t) = A, and that at t = 0 we have vout (t) = 0. It is clear that vout (t) = A is a solution of the inhomogeneous dierential equation: vout (t) + vout (t) = A. The general solution of the homogeneous dierential equation is vout (t) = Cet/ . Thus, the general solution of the inhomogeneous equation is: vout (t) = A + Cet/ . Imposing the initial conditionthat vout (0) = 0we nd that the output of the low-pass lter when the input is a step is: vout (t) = A(1 et/ ). 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 lter now. Suppose once again that vin (t) = A. Then the input to the digital lter is the all As sequence. It is easy to see that a solution of the inhomogeneous recurrence relation is v (n) = A. The homogeneous equation is: v (n) = v (n 1). +T

It is clear that the general solution to this equation is: v (n) = C +T


n

We nd that the general solution to the inhomogeneous equation is: v (n) = A + C +T


n

Finally, enforcing the initial condition we nd that the solution to the recurrence relation with initial condition v (n) = 0 is: v (n) = A 1 +T
n

Just as in the case of the analog lter, we nd that we have a solution that starts 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 nd that the solution is approximately: v (n) A(1 enT / ) = vout (nT ). That is, as T gets smaller and smaller the output of the digital lter approaches the samples of the output of the analog lter.

108

CHAPTER 22. DESIGNING A LOW-PASS FILTER

22.4

The Experiment

Design and implement a digital lter for which T = 0.5ms and for which = 0.5ms. You may take any reasonable shortcuts, but the lter must produce acceptable looking output. In particular, you may run the DAC in 8-bit mode if you would like. Note that you may need to shift the bits around. The 8051 assembly language has several shift commandsRR, RL, RRC, and RLC. See pp. 49-50 of the 8051 Programmers Guide for more information about these commands. Also note that division by two can be accomplished by right shifting a number by 1 bit.

22.5

The Report

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

22.6

Exercises

1. Solve the dierential equation satised by the low-pass lter 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 Simple Oscilloscope


23.1 A General Introduction

The goal of this experiment is to have the ADuC841 output two analog signalson its two DACsthat will drive an oscilloscope in x-y mode to plot the signal being input to the chips A/D. In order to drive the scope in such a way that one will be able to see the signal, one must make use of a trigger. One must force the output to start from the same place many timesotherwise one will see a very messy signal. More than just starting at the same point, it is important that the output be consistently rising or falling at that point. One must set two parameters in order for the triggering to be eective. One must set the trigger level and the trigger slope.

23.2

Implementation

To implement the scope-signal generating program one must do several things. 1. One must set up the A/D to sample at an appropriate ratethis will involve 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 crossed the trigger level in the correct direction. 109

110

CHAPTER 23. IMPLEMENTING A SIMPLE OSCILLOSCOPE

3. If it did, then one must set a ag to tell the processor that a trigger event has occurred. 4. If the ag 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 the other channel one must output a signal that increases linearlyone must output the time-base. 5. When the time-base has reached its maximum valuewhen one has swept the screen once, one must de-assert the triggered ag and wait for the next trigger event.

23.3

The Experiment

Write a program that takes input from the A/D and outputs signals to the DAC that cause a scope in x-y mode to give output that looks like the output of a scope in normal mode. You may nd the command SUBB helpful. It subtracts values (with carry) and sets the carry bit if one needs to carry. (The full description of this instruction is located on p. 52 of the 8051 Programmers Guide.) This can be used to see if one number is less than anothersomething that you will need 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 program is fully commented.

23.5

Exercises

1. In 23.3 one can use the CJNE command rather than SUBB. Explain how to do this. 2. Suppose that one inputs a sine wave into an oscilloscope that triggers every time the input to the scope passes through zero regardless of whether the signal is rising or falling at that point. What will the output of the scope look like? Please make a simple sketch of the output.

23.5. EXERCISES

111

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

112

CHAPTER 23. IMPLEMENTING A SIMPLE OSCILLOSCOPE

Chapter 24 Implementing a Simple Capacitance Meter


24.1 A General Introduction

The goal of this experiment is to have the ADuC841 output the capacitance of a capacitor to the ADuC841s UART. This goal is accomplished by measuring the 0 to 50% rise time of the capacitor under test as part of an RC low-pass lter with a xed resistance value. Let R be the resistance of the resistor, let C be the capacitance of the capacitor under test, let V be the voltage impressed upon the low-pass lter at time t = 0, and let r be the time it takes the capacitors voltage to reach half of its nal value. As the voltage on the capacitor as a function of time is easily seen to be: VC (t) = V (1 et/(RC) ), and as the nal voltage on the capacitor is V , it is clear that r satises: V /2 = V (1 er /(RC) ). Solving this equation for C, we nd that: C= r . R ln(2)

Thus, if we can measure r we can easily nd the capacitance. In order to upload the value of the capacitance, it will be necessary to upload a user generated string via the UART. This can be done using the technique described in 16.2.2. 113

114CHAPTER 24. IMPLEMENTING A SIMPLE CAPACITANCE METER

24.2

Implementation

To implement this simple meter, one connects the output of DAC0 to a resistor, one connects the second side of the resistor to a capacitor and to channel 0 of the A/D, and one connects the second side of the capacitor to ground. Upon being told to start a measurementby having the user send the ASCII for the letter m to the ADuC841s UART, for examplethe ADuC841 sets the voltage at DAC0 to 2.5V. At the same time, the ADuC841 starts sampling the input to channel 0 of the A/D. (A simple way to do this is to have the A/D sample every overow of Timer 2. Then one can start or stop 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 to 1.25V. If one keeps track of how many times one enters the A/D ISR before half of the voltage is reached, then one knows how long the capacitor took to reach half of its nal value. That is, one nds r . By carefully choosing the sampling period and the resistor value, one can make the calculation of the capacitance quite simple.

24.3

The Experiment

Write a program that calculates the capacitance of a capacitor and uploads the capacitance via the UART. Have the program start a measurement each time an m is sent to the ADuC841 via the UART. Use a 1 K resistor in the RC low-pass lter.

24.4

The Report

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

24.5

Exercises

1. What formula does one nd for the capacitance of the capacitor under test when one knows the time it took for the capacitor to reach 90% of its nal voltage and one knows the resistance of the resistor? 2. Suppose that rather than trying to measure the capacitance of a capacitor one were trying to measure the inductance of an inductor. What changes would one have to make to the method described? (One does not need to change very much.)

Chapter 25 Generating PN Sequences


25.1 Introduction

One of the most important signals used in communications is the pseudorandom or psuedo-noise (PN) sequence. Such sequences are nearly spectrally white at reasonably low frequencies and can beand areused as deterministic white noise. PN sequences are used in direct sequence spread spectrum (DSSS) systems. PN sequences can also be used to examine the frequency response of lters. Let yn be a either 0 or 1. Let all operations be operations over the integers mod 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 nally, 1 1 = 1.) Let yn satisfy an equation of the form: yn = a1 yn1 + + aN ynN where the elements of the sequence and the coecients are all elements of Z2 . One can show that for appropriate choices of coecients, the sequences generated are PN sequences. Lists of such coecients are easily available both in print and on the WWW.

25.2
25.2.1

Some Facts about PN Sequences


Length

Because there are only 2N possible values of the previous states yn1 , . . . , ynN , and because the next set of previous states depends only on the current set of previous states, the sequence {yn } must become periodic. The maximum period is not greater than the number of previous states2N . In fact, it cannot 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 some of 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 ones in the sequence and the number of zeros in the sequence? Because the set of previous states goes through all 2N 1 possibilities save the all zero previous state, we know that every state must be zero or one almost the same number of times. If the all zero state were included, one would have each state being zero or one the same number of times. Because the all zeros state is not included, 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 delta function. 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
25.3.1

Implementation Hints
Shift Registers

The standard way to implement a PN sequence generator is to use a shift register. It is easy to simulate a shift register on an 8051-type microprocessor (and on most other microprocessors as well). The 8051 has commands for shifting 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. These commands rotate the bits in the register. When one uses RR the bit n moves to bit n 1 and bit 0 moves to bit 7. When using RL bit n moves to bit n + 1 and bit 7 moves to zero.

25.3.2

Logical Operations

Though the 8051 family of microprocessors includes several commands for performing boolean operations on bits, it is sometimes easier to perform several tests in order to determine the sum of several bits. For example, if one 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 determine what operation to perform. Sometimes this style of programming leads to simpler or shorter code than using the 8051 command for logical operations.

25.4

The Experiment

Using the ADuC841, generate the PN sequence that satises the equation: yn = yn3 + yn5 . Make use of Timer 1 (in mode 2) to cause 1 bit to be output every 10s. 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 default no output is produced. If one pushes the button connected to pin 3.2, then output should be produced. Pushing the button again should stop the output from being produced. If output is not being produced, pushing the button causes it to be produced. If output is being produced, pushing the button causes it to stop being produced. Using an oscilloscope with an FFT option examine the spectrum of the output. What is the fundamental frequency of the signal?

25.5

The Report

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

25.6

Exercises

1. Let yn satisfy: yn = yn1 + yn2 , y1 = 1, y2 = 1.

Please calculate and tabulate y0 through y10 . Is yn a maximal length sequence? How many ones are there in each period, and how many zeros are there in each period? 2. Using the WWW nd an equation that generates an MLS with period 29 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? You may (and are encouraged to) use the 8051 Programmers Guide to answer this question. 4. Write a sequence of 8051 instructions that calculates the exclusive or of GREEN and BLACK as dened 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 switching circuit like that of Figure 26.1. The p-channel enhancement MOSFET in the gure acts as a switch, and whenever the output, Vo , drops below the desired voltage (which must be less than VDD ), the microprocessor provides a 0V signal to the gate to allow the MOSFET to conduct and charge the capacitor in the circuit. If Vo is at or above the desired voltage, the microprocessor outputs 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. Then the two 10K resistors act as both the load and as a measurement circuit.) The circuit has four connections to the evaluation board. The MOSFETs gate input is connected to P3.4. The MOSFETs source and body are tied to one of the 5V outputs of the board. The load resistor, one of the 10K resistors, and the capacitor are tied to one of the boards ground connections. The point between the two 10K resistors is tied to the ADC0 input on the board. The reason for including the voltage divider is that the ADuC841s ADC takes inputs between 0 and 2.5V while the voltage converters output can be as 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 and compares 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 the MOSFET 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 MOSFET conduct by making its gate voltage (aproximately) 0V. You may choose to use only the upper four bits of the ADCs output, the bits containend in ADCDATAH, to measure Vo . Doing this gives you 16 possible voltage ranges for the output voltage. Your program must compare the ADCs output with the desired output which will also be given as a number between 000H and 00FH. Your program must allow the user to change the desired value of the output by using the UART. Set the UARTs baud rate to 19,200 characters/sec. Anytime the UART receives a +, have the output voltage increase by one unit. 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 that will 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 making measurements, one must present the measurements to the user in a way that he will nd useful. One standard way of representing a set of measurements is as a graph. In this chapter, we will teach the ADuC841 how to plot a graph on a host computers screen.

27.2

The Main Idea

When trying to output a graph using the ADuC841s UART, we cannot hope to make a very pretty graph. In this lab, we will plot points on our graph by having the computer place an asterisk (an *) wherever a point should appear. One of the challenges of plotting a graph with a microcontroller is that the microcontroller outputs rows of text via it UART, and we want to place points in specic columns. The microcontroller works line by line, and we would normally work column by column. Suppose that one has a set of 4 bit measurements taken at equally spaced intervals and that one would like to plot the measurements. As there are only four bits in each measurement, we need sixteen rows in our graph. If the list is stored from the measurement that should appear rst to the measurement that should appear last, we can have the microcontroller produce our plot as follows. Have the microcontroller start plotting the graph from the graphs highest row in our example from the row in which items whose value is fteen should go. 123

124

CHAPTER 27. MAKING A SIMPLE PLOTTER Input Output 0.0 0 0.25 1 0.5 2 0.75 3 1 2 Table 27.1: Some input-output pairs for our hypothetical system.

Have the microcontroller read the measurements that have been stored one after the other starting from the measurement that should appear in the rst column. Each time the microcontroller examines a measurement, it checks to see whether the measurement is such that an asterisk should appear in the current column and row. If an asterisk should appear, the microcontroller sends the ASCII for an asterisk to the computer. If not, the microcontroller send the ASCII for a blank space. When the microcontroller gets to the last element in a row, it outputs a carriage return and a line feed and starts the above process for the next row. The microcontroller continues plotting until it nishes all the rows.

27.3

An Example

Let us consider a simple example of how this could work. Suppose that we have ve measurements of the output of a system. The measurements are given in Table 27.1. If we were to have the ADuC841 plot this graph, it would need to use ve columns and four rows. In plotting the graph, it would start by going from element to element and checking to see which elements are equal to the largest value, to three. It would output an asterisk wherever a three occured and a space elsewhere. After scanning the data once for threes, it would have output the line * . After scanning the data again for all occurences of the number two, it would have output * *. After scanning for ones, it would have output * . Finally, after scanning for zeros it would have output * .

27.4. IMPLEMENTING THE PLOTTER

125

At the end of the process, the user would see the following four lines on his screen. * * * * * This is a reasonable graphical representation of the data. In the next section, we discuss some implementation issues.

27.4
27.4.1

Implementing the Plotter


Storing the Values to Be Plotted

Assuming that the values to be plotted might have to change (as they would if they are values that we measure in real-time), we cannot store the measurements in the code segment. The data must be stored in the data segment in an array. Recall that one can read from or write to array using indirect addressing. One can use registers R0 or or R1 to point to the current element in an array and to read from the array or write to the array using the MOV @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 string and that chooses the elements of the string on the y. Thus, most of our hard work is going to be connecting to setting up the transmit interrupt to print the string. Assuming that the name of the array (in DSEG) in which the array is stored is MEASUREMENTS, before starting to print the string, one points R0 (or R1) at MEASUREMENTS and one inializes a row counter to be equal to the highest row and a column counter to be 0 to be at the very rst 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 place the routines in the interrupt subroutine (ISR). It is much better practice to raise a ag in the ISR and do all non-time-critical processing outside the ISR. Whenever the transmit interrupt is asserted, the microcontroller tries to output the next character in the graph. In the routine that the main program calls each time a transmit interrupt is detected, the microcontroler checks the value 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 outputs the ASCII for *. If not, it outputs the ASCII for . If the end of a row has been reached, then the microcontroller must output a carriage return and a line feed. Of course, the microcontroller must also make sure to update the current 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 received by the ADuC841. The plot must have sixty-four columns and sixteen rows, and the plotting routine must be written with an eye towards being one element of a larger program.

Chapter 28 Building and Testing a Dynamic Logic Inverter


28.1 Introduction

Sometimes when one builds and tests a circuit it seems like one needs several extra pairs of hands. It is possible to use a microcontroller and its UART in place of those extra hands. In this lab, you will write a program for the ADuC841 that will allow you test the circuit of Figure 28.1 in a sensible fashion. 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 clock signal, , to the circuit is low, the lower NMOS transistor is cuto and the middle transistor has no path to ground it is just hanging o of the PMOS 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 NMOS transistor. Immediately after the transistion from clock-low to clock-high, the capacitor is charged to VDD . If the input to the upper NMOS transistor is approximately zero volts, then that transistor is cuto and the capacitor cannot discharge. Thus, the output remains VDD . (The voltage will slowly decay because of leakage currents, but as long as one is clocking the circuit at a reasonable rate, this is not a serious concern in our case.) If the input to the upper NMOS is VDD , then both NMOS transistors conduct, and the 127

128CHAPTER 28. BUILDING AND TESTING A DYNAMIC LOGIC INVERTER

Figure 28.1: A dynamic logic inverter. The circled number represent the pins of the SCL4007UBE. capacitor discharges through them. In this case, after a little while the voltage on the capacitor fall to 0 V. Taking the voltage on the capacitor as the output, one nds that shortly after the clock goes high, the output is the inverse of the input. If the input is high, the output is low, and if the input is low, the output is high.

28.3

The Experiment

Write a program that uses the ADuC841s serial port and the I/O pins to allow the user to toggle the dynamic logic inverters clock and to set the input to the inverter to be either 0 V or 5 V. Let the output to the clock be P3.4 and the output to the inverters input be P3.5. Additionally, whenever the clocks value is toggled or the inputs value is set output a very short pulse to P3.6. Have the program toggle the clock everytime a capital C is received by the UART, have the program output 0 V to the input whenever a capital 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 to make sure that it works, and then download the program to the evaluation kit and make sure that the program does what it is supposed to. When the program works properly, build the circuit of 28.1. Connect VDD to the evaluation kits DVDD, the circuits ground the the evaluation kits DGND, P3.4s output to the gates of the transistors to which the clock is fed, and connect P3.5s output to the gate of the transistor to which the signal is input. (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 connected to P3.6 to trigger the scope and enjoy testing the dynamic logic inverter.

130CHAPTER 28. BUILDING AND TESTING A DYNAMIC LOGIC INVERTER

Chapter 29 Power Management


29.1 Introduction

The power required by a CMOS circuit is strongly inuenced by the rate at which the circuit changes state. To understand why, consider the schematic diagram of a CMOS gate given in Figure 29.1. The gate has two sub-units a pull-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 behave like an open circuit. The inputs to the system determine which network is active behaves like a short circuit at any given time, and in that way, the inputs determine the voltage at the output. The beauty of CMOS circuits is that, in principle, they dissipate almost no power. As there is never (or almost never) a connection from VDD to ground, (almost) no current should ow in the circiut. Anyone who has ever put his hand near the a Pentium processor knows that in fact such processors dissipate quite a lot of power. Why is power being dissipated? One way that power is dissipated in CMOS circuits is in the charging and discharging of parasitic capacitors. Each time the circuit changes state, parasitic capacitors are charged or discharged, and energy is wasted. If only we 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 doing anything; we cannot stop the circuit from changing state. The rate at which circuits are changing state is related to the rate at which the circuits dissipate energy. If we can causes the circuits to change state as little as possible, we should be able to reduce the power dissipated by 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 to adjust the internal clock speed of the ADuC841, and we will measure the the power used by the processor at two dierent clock speeds. We will see that when 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 ADuC841s clock is a 11.0592 MHz crystal. The ADuC841s default is to use the crystal frequency as the internal clock frequency. It is, however, possible to cause the ADuC841 to divide this clock down and to use the lower frequency clock as the internal clock. The PLLCON SFR, located at 0D7H in the internal memory, can be used to 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 these three 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 bits are set to zero, then the ADuC841 does not divide the external clock at all and the micro-controller runs at a clockrate of 11.0592 MHz. If CD0 is set and the 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 we have seen has always been 11.0592 MHz. Note that PLLCON is an ADuC841specic SFR. In order to use it, you must include the appropriate header le. Also, the SFR is not bit addressable. The datasheet for the ADuC841 states that top ve bits should always have zeros written to them. Thus, when moving 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 writing a program and you know that the program does not do very much, you can choose to divide the clock down and, in this way, to reduce the power used by the processor.

29.3

The Experiment

In this experiment, you must write a program that causes the ADuC841 to echo characters it received via its UART. Because this does not require the ADuC841 to do much work, there is no reason to have the ADuC841 work at full speed. However, in order to make it possible to see the changes we have spoken about, you will write a program that can run the ADuC841 either at its full clock speed or at half the normal clock speed. Write a program that causes the ADuC841 to echo characters received via 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 received have the program set CD0 and make sure to change the value with which Timer 1 is reloaded in such a way that even after the change in internal clock frequency the UART still runs at 57,600 baud. When the character ) (sometimes known as shift-0) is received, have the program clear CD0 and make sure to change the value with which Timer 1 is reloaded in such a way that 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 user sees a UART that is running at 57,600 baud. To make it easier to be sure that the internal clockrate is changing as desired, 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 reload value when the internal clock is halved. In this way, the advanced user will be 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 divided down. 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 V battery to the development kit, but only connect it to one of the terminals on the board. Connect the second terminal to the battery through an ammeter. You should observe current in the tens of milliamperes, but you should see a clear drop in the current when you halve the clockrate. Please work very carefully when performing this part of the experiment and call over one of the 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 Embedded High Speed 62-kB Flash MCU ADuC841/ADuC842/ADuC843, Rev. 0, Analog Devices Inc., Norwood, MA, 2003. (These are the ADuC841s data sheets.) Analog Devices Inc., ADUC8XX SAR EVALUATION BOARD REFERENCE GUIDE, Version A.3, Analog Devices Inc., Norwood, MA. Metalink Corporation, 8051 Cross Assembler Users Manual, Metalink Corporation, Chandler, AZ, 1990. Philips Semiconductors, 80C51 Family Programmers Guide and Instruction Set, Philips Semiconductors, http://www.hoeben.com/80C51_FAM_PROG_GUIDE_1.pdf, last visited September 6, 2007. Philips Semiconductors, 80C51 Family Architecture, Philips Semiconductors, http://www.hoeben.com/80C51_FAM_ARCH_1.pdf, last visited September 6, 2007.

30.2

8051 Related Information

Richard H. Barnett, The 8051 Family of Microcontrollers, Prentice Hall; ISBN 0023062819 J. Uenbeck, 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

Vous aimerez peut-être aussi