The following documentation is also provided with the relevant labs.
Please click on LABS link to obtain the printable versions ( PDF files ) of those labs.
Programming the Microprocessor
(Section 6 and Section A of M68HC11 Reference Manual)
- Arithmetic operations:
ABA, ABX, ABY, ADCA, ADCB, ADDA, ADDB, ADDD, INC, INCA, INCB, INS, INX, INY
SBA, SBCA, SBCB, SUBA, SUBB, SUBD, DEC, DECA, DECB, DES, DEX, DEY
- Multiplication: MUL
- Division: FDIV, IDIV
- Logical operations: (note: logical operations are carried out on a bit by bit basis)
- Standard logical operations: ANDA, ANDB, EORA, EORB, ORAA, ORAB, COM
- Operations that shift the location of the bits in the register:
ASL, ASLA, ASLB, ASLD, ASR, ASRA, ASRB, LSL, LSLA, LSLB, LSLD, LSR, LSRA, LSRB, LSRD, ROL, ROLA, ROLB, ROR, RORA, RORB
- Operations that compare two numbers:
BITA, BITB, CBA, CMPA, CMPB, CPD, CPX, CPY
- Branching commands: (see also the section on branching) BCC, BCS, BEQ, BGE, BGT, BHI, BHS, BLE, BLO, BLS, BLT, BMI, BNE, BPL, BRA, BRCLR, BRN, BRSET, BSR, BVC, BVS, JMP, JSR, RTS, RTI, WAI
- Memory/Register Functions
- Move data into / out of memory: LDAA, LDAB, LDD, LDS, LDX, LDY, STAA, STAB, STD, STS, STX, STY
- Change the values in memory/registers: BCLR, BSET, CLC, CLI, CLR, CLRA, CLRB, CLV, COM, COMA, COMB, NEG, NEGA, NEGB, SEC, SEI, SEV
- Transfer data from one register to another: TAB, TAP, TBA, TPA, TSX, TSY, TXS, TYS, XGDX, XGDY
5) Stack Pointer Functions: PSHA, PSHB, PSHX, PSHY, PULA, PULB, PULX, PULY
6) Misc.: NOP, SWI
(Section 6.2 of M68HC11 Reference Manual)
There are five addressing modes used in the MC6811 microprocessor: Immediate, Direct, Indexed, Inherent, and Relative. Details follow.
The inherent mode commands are one-byte commands consisting only of an op-code. These commands take place entirely within the microcontroller and require no outside data.
Example 1: Add the value currently in Accumulator A to the value currently in Accumulator B and store the result in Accumulator A.
$0000 1B ABA INH Add Accumulators A and B. Results stays in accA.
Example 2: Add 0116 to the value in Accumulator B and store the result in Accumulator B.
$0000 5C INCB INH Increment Accumulator B
Instructions given in the immediate mode contain two parts: the op-code and the value to be used in the command. The command is usually two bytes long; however, the instruction may be three bytes long if a long (two byte) number is required, such as a load double accumulator command. A pre-byte to the op-code is required for instructions involving the Y index register. This could cause the command to be as much as four bytes long. This mode cannot be used to store values.
Place the value 5616 in Accumulator A.
$0010 86 LDAA IMM Load Accumulator A
Example 2: Add 1016 to the value currently in Accumulator B and store the results in Accumulator B.
$0010 CB ADDB IMM Add to Accumulator B
Example 3: Place the value 010216 in Accumulator D.
$0010 CC LDD IMM Load Accumulator D
Remember that Accumulator D is composed of Accumulator A and Accumulator B. After this command, Accumulator A will have the value 0116, and Accumulator B will have the value 0216. Any values in Accumulator A and Accumulator B before this command have been overwritten.
Instructions given in the direct mode are usually two bytes long. The first byte is the op-code, and the second byte is the memory location where the data for the command is stored. This addressing mode assumes that the most significant byte of the memory address is 0016. For example, if the second byte of the command is 8316, the memory location used in the command would be 008316. Commands can be three bytes long if a prebyte is required.
Place in Accumulator A the value 1816 from address $0012.
$0000 96 LDAA DIR Load Accumulator A
Add to the value currently in Accumulator B the value 0416from address $0020. The result remains in accB.
$0000 DB ADDB DIR Add to Accumulator B
Load the value 201216 into Accumulator D.
$0000 DC LDD DIR Load Accumulator D
Note the Boolean notation M:M+1 (concatenated) in the description of LDD. This means that the memory location directly referred to as (M) gets loaded into the high byte (Accumulator A), while the memory location (M+1) gets loaded into the low byte (Accumulator B).
Example 1: Place the value 1816 in Accumulator A.
$0000 B6 LDAA EXT Load Accumulator A
Example 2: Add the value 0416 to the value currently in Accumulator B.
$0000 FB ADDB EXT Add to Accumulator B
Example 3: Load the value 201216 into Accumulator D.
$0000 FC LDD EXT Load Accumulator D
Example 4: Store the high byte of Accumulator D in memory location $0008, and store the lower byte of Accumulator D in memory location $0009.
$0000 FD STD EXT Store Accumulator D
The commands using the index X mode are usually two byte commands; those using the index Y mode are usually three byte commands. The first byte(s) is the op-code, and the second or third byte is the offset. The value of the last byte, the offset, is added to the current value in the index register. This sum is the address of the memory location that stores the data for the command. The offset is not a two's complement number. The index mode can only refer to a memory location greater than the value in the index register.
For all the following examples, assume the value 001016 is in the index register.
Load the value 5816 into Accumulator A.
$0000 A6 LDAA INDX Load Accumulator A
Example 2: Store the value currently in the index register, 001016 in the memory locations $0021 and $0022.
$0000 EF STX IND Store X index register
Note that this command operates in a manner similar to the STD command explained before. $0021 will have the value 0016, and $0022 will have the value 1016.
Relative ModeExample 1:
The relative mode is used for branching commands. The value following the op-code is a two's complement number indicating the size and direction of the branch. This number is the relative offset and can be calculated as follows:
Relative Offset = (Address of Destination) - [(Address of Op-code) + n]
where n is the length of the command in bytes. Most branch statements are two bytes long, although some are as long as five bytes long. The maximum jump forward is 127 memory locations from [(Address of Op-code) + n]. The maximum jump backwards is -128 memory locations.
Branch to location $0005 in memory.
$0000 20 BRA REL Branch Always
Branch to location $000C in memory if the Z bit is equal to 0 when the program gets to memory location $001A.
$001A 26 BNE REL Branch if Not Zero (Z=0)
Sample Program Using Simple Commands and Addressing Modes
Perform addition of hex numbers #38 and #38 using accA and accB and store result in memory. Utilize IMM, DIR, EXT, INDX, and INH addressing modes in this process, as follows:
Load Accumulator A with #38. || (IMM) ||Store Accumulator A into $0000. || (DIR)
||Load Accumulator B with $0000. || (EXT)
||Load INDX with #1000. || (IMM)
||Add Accumulator A and Accumulator B. || (INH)
||Store Accumulator A into $1001. || (INDX)
||Stop program execution. || (INH)
MEMORY || OPCODE/DATA || ABBR. || MODE |
|$0010 ||86 || LDAA ||IMM |
|$0011 || 38 |
|$0012 || 97 || STAA || DIR |
|$0013 || 00 |
|$0014 || F6 || LDAB ||EXT |
|$0015 || 00 |
|$0016 || 00 |
|$0017 || CE || LDX || IMM |
|$0018 || 10 |
|$0019 || 00 |
|$001A || 1B || ABA || INH |
|$001B || A7 || STAA || INDX |
|$001C || 01 |
| $001D || 3F || SWI || INH |
Is the processor plugged into the PC serial port?
Is the processor plugged into the power supply?
Is the power supply turned on?
Is the PC in the C:\MC6811 directory running MC6811?
Is the serial port plugged into the correct connector?
- Does the breadboard have power? - Check all voltages
- Are the chips oriented correctly - notch in the correct direction?
- Do the chips straddle the gap in the center of the board?
- Make sure all chips have power (not just input & output lines).
- Verify the direction of diodes and electrolytic capacitors.
- Verify the power at intermediate locations - use 5 or 0 volts from the supply instead of chip input to check various conditions.
- Verify that the PC ports are giving the expected output signals.
- Verify chip and transistor pins with the pin diagrams.
- Are there any "open" lines, no voltage connection instead of zero volts?
- Verify resistor codes and capacitor values.
- Is the correct program currently in memory?
- Is the correct starting location being used (G ????).
- Was the correct name used when MC6811 was run?
- Verify the program with ASM.
- Use trace (T) to step through and verify branches, jumps and data.
- Compare memory locations with expected information after the program stops.
- Insert SWI at a key location to allow verification of branch, memory and accumulator values.
- Do branches and jumps have the correct offsets?
- Have RET and RTI commands been reversed somewhere?
- For serial communications, has TE or RE been set?
- For serial communications, has TDRE or RDRF been reset?
- For parallel port C, has 1007 been set for input or output?
- Has the interrupt mask been cleared (CLI)?
- Has the stack pointer changed substantially?
Use the BUFFALO commands to do step-by-step (Trace, T) and Break-Point (BR) execution of the program. Press F1 for details of the BUFFALO commands.
Parallel Ports(Section 7 of the M68HC11 Reference Manual)
Parallel communication is communication that occurs simultaneously on many lines -- thus the word, parallel. It is used most often when the communicating devices are local to one another. For the MC6811, there are two parallel ports to which the user has direct access: Port B and Port C. Since MC6811 is an 8-bit microcontroller, each of these parallel ports has 8 bits. That is, each of the parallel ports has eight separate wires coming out of the microcontroller, one wire for each bit of data.
The two parallel ports are configured differently. Parallel Port B is restricted to output- only applications. Parallel Port C can be used for either input or output. Moreover, in Parallel Port C, not all bits have to be the same type of communication. For example, the first four bits of Parallel Port C (PC0 - PC3) can be set to read input, while the last four bits of Parallel Port C (PC4 - PC7) can be set to send output information.
To use these parallel ports, a program must load and store specific numbers to special memory locations. These memory locations are referred to as control registers. There are three different control registers, which are related to Parallel Port operation, one related to Parallel Port B, and two related to Parallel Port C.
As Parallel Port B is output only, there is only one thing, which needs to be specified: the output data. This will be a signal of either 5V or 0V for each line in the Parallel Port. A 0 corresponds to 0V; a 1 corresponds to 5V. To send desired data out Parallel Port B, store the two-digit hexadecimal number corresponding to the eight bits of data that you wish to output into memory location $1004. This one action specifies the output voltage on the eight separate output lines.
For Parallel Port C, two aspects of parallel communication must be specified. These are the data direction for each pin (whether a pin is input or output) and the actual data for each pin. The data direction for each pin is specified by storing a two-digit hexadecimal number corresponding to the data direction of each individual pin into memory location $1007. A 0 corresponds to input; a 1 corresponds to output. The specific data for Parallel Port C is in memory location $1003. If the pin is output, then the value in that bit location indicates the voltage currently sent out that pin. The behavior of Parallel Port C in output is the same as Parallel Port B. Changing the value of the bit changes the value of the output voltage. If the pin is input, the value in that bit location indicates the voltage currently being measured on that pin. Writing to an input pin has no effect.
DO NOT SEND AN INPUT SIGNAL INTO A PIN SPECIFIED FOR OUTPUT!!! THAT WILL FRY THE CHIP!!!
Serial Communications(Section 9 of the M68HC11 Reference Manual)
Serial communications are used when one bit is sent at a time. All the data is transferred on one line; the bits are transferred sequentially, making serial communication much slower than parallel communication. The data is specified by holding each bit at a certain voltage for a certain period of time. The data is usually sent in character format using the 7-bit ASCII (American Standard Code for Information Interchange) code. It specifies a 7 bit binary code for commonly used characters. To put the 7-bit ASCII into an 8-bit byte, one fills the 8th bit with 0.
The data byte being sent is bracketed by two bits, the start bit (0V) and the stop bit (5V). An idle line has a voltage of 5V. Each data byte is prefixed by a 0V start bit. The data bits are then sent from the least significant bit to the most significant bit. At the end, a 5V stop bit is added. All bits are held for the same amount of time. The time is specified by the BAUD rate (bits/sec).
MC6811 has the capacity to receive and transmit data through the serial communication interface. The selection of receive and/or transmit modes is done by setting to 1 the RE and TE bits in the Serial Communication Control Register #2 (SCCR2) (memory location $102D, bits 2 and 3). Simultaneous selection of both receive and transmit modes is permitted, since MC6811 has separate lines for reception and transmission (RxD and TxD through port D pins PD0 and PD1, respectively).
In the receive mode, the Receive-Data-Register-Full (RDRF) indicates when serial communications data has been received (RDRF=1). RDRF is bit 5 of the Serial Communication Status Register (SCSR) at memory location $102E. When serial communications data is received, it gets placed in the Serial-Communication-Data-Register (SCDR) (memory location $102F). As a user, you would normally check RDRF until found equal to 1, then load the data from SCDR into an accumulator. This sequence of reading RDRF=1 and loading data from SCDR will trigger the clearing of RDRF (i.e., will make RDRF=0). For this reason, it is called "clearing sequence". In this way, MC6811 becomes ready for the reception of the next serial communication data.
Transmission of data from MC6811 also uses the Serial-Communication-Data-Register (SCDR). Before placing new data in SCDR for transmission, one must first make sure that SCDR is empty, i.e., it has finished transmitting previous data. This verification is done by checking the value of Transmit Data Register Empty (TDRE) bit (memory location $102E, bit 7). If TDRE = 0, then MC6811 is still transmitting data through the serial communication interface. If TDRE = 1, then transmission has finished, and the data register is empty and ready to receive new data for transmission. When data is stored into SCDR for transmission, MC6811 automatically adds the start and stop bits to the data, sends the data out through the serial communication interface, and, after transmission is complete, makes TDRE=1. The clearing sequence for TDRE consists in reading TDRE=1 followed by storing of data into SCDR. Subsequently, MC6811 starts serial communication transmission of the data placed in SCDR.
Interrogating the value of specific bits in SCSR (RDRF, TDRE, etc.) can be done in a number of ways. One way could be to AND the contents of SCSR with the appropriate mask and use a BEQ instruction to loop back if the result is zero (i.e., if the interrogated bit is not yet set). For RDRF (bit 5), the mask is #20. For TDRE (bit 7), the mask is #80. However, there are also other ways of branching in correlation with the status of specific bits (e.g., instructions BRCLR, BRSET, etc.). Feel free to experiment!
Serial communication is critical to the operation of modern computers. This is how keyboards communicate with the computer, and how you will control your programs during labs and project.
NOTE: Please, see Section 9 of the M68HC11 Reference Manual for more detailed information on serial communication.
Timer Functions(Section 10 of the M68HC11 Reference Manual)
Timer functions allow the microcontroller to determine "time" by counting the number of machine cycles between events. The timer is based on the Timer Counter register (TCNT, $100E - $100F). The timer counter register increments once every machine cycle. Once the timer counter register reaches #FFFF, the next machine cycle causes the register to "overflow" (go from #FFFF to #0000). To let the user know that this has happened, the microcontroller sets a flag, TOF, the Timer Overflow Flag (bit 7 of $1025). 1 implies that there has been a timer overflow; 0 implies that there has not been a timer overflow. To use TOF as a counting tool, you must clear TOF. Here, clearing TOF is obtain by writing a 1 to it (unusual, but true for all timer flags: see Section 10.2.4 on page 10-14 in the Reference Manual). When clearing a flag, it is important that you do not interfere with the other bits in the register!
The timer is also linked to external lines, allowing the microcontroller to record the value of the timer counter when an input voltage changes. These functions are called input capture functions. They detect a signal transition. At the time that the signal transition is detected, the input capture function automatically records the value in the timer counter in a separate memory location and sets a flag, ICxF, to let the user know that there has been an input capture. Value 1 implies that there has been an input capture; 0 implies that there has not. Each flag is cleared by writing a 1 to the flag in the control registers. The type of signal transition that causes an input capture is determined by the edge bits, EDGxB and EDGxA. Because these two bits act together, there are four different modes for each input capture: disabled; low-to-high detection; high-to-low detection; and both low-to-high and high-to-low detection. MC6811 has three individual input captures. All act in the same way, with separate memory locations, EDG bits, and ICF's.
Another timer function is the output compare function. When the value in the timer counter register reaches the value in the output compare register, the microcontroller sends a signal out on the selected pin. In essence, the microcontroller schedules when to send the signal out. There are four commonly used output compares on the MC6811. They are OC2, OC3, OC4, and OC5. As the timer is a two byte register, each of the output compare registers is a two-byte register. To set a value for output compare, simply store the two-byte number to the output compare registers. Once the timer counter reaches the value in a timer output compare register, an OCxF (output compare flag) is set to let the user know that an output compare has occurred. 1 indicates that output compare has occurred; 0 indicates that output compare has not occurred. To clear an output compare flag, write a 1 to OCxF. The signal sent out of the microcontroller on output compare is controlled by two bits acting together, the OMx and OLx bits. The four available options are: (i) disabled; (ii) send out 0V; (iii) send out 5V; and (iv) toggle the output voltage. Each of the timer output compare functions has output compare registers, OM and OL bits, and output compare flags in the control registers.
The timer counts and measures events in terms of machine cycles. In Lab 3, you measure the clock speed of the microcontroller. In essence, you calculate a conversion factor between machine cycles and real time. Using the timer functions of the microcontroller and the conversion factor that you derive, you can use the microcontroller for data acquisition involving time measurement.
(Section 12 of the M68HC11 Reference Manual)
An analog-to-digital converter (A/D) takes an analog voltage, such as those produced by many electronic measuring devices, and converts it to a digital value. MC6811 has an 8-bit analog-to-digital converter. The range of measurement is from 0V to 5V. This allows the microcontroller to interface with such devices as potentiometers, cermets, thermocouples, LVDT's, etc. MC6811 has many different ways that analog-to-digital conversions can be made, as there are 8 separate lines (or channels) that the A/D can utilize. All of the options are controlled by one control register, ADCTL, in $1030. The results of the A/D conversions are stored in four separate memory locations, $1031, $1032, $1033, and $1034 -- ADR1, ADR2, ADR3, and ADR4, respectively.
There are two different modes that MC6811 can use to take data. These are determined by the value of SCAN, bit 5 in $1030. If SCAN = 1, then the microcontroller continuously scans for data along the A/D lines. Every time a new measurement is made, the data is stored in the appropriate memory location. If SCAN = 0, then four conversions are made, one on each specified line. The results of these four conversions are stored in the specified memory locations. As soon as all four conversions are completed, the A/D stops making conversions.
The lines specified to take data are determined by bits CD - CA, bits 3 - 0 in $1030. The meanings of these bits are specified by MULT, bit 4 in $1030. If MULT = 0, then four consecutive conversions are performed on the same data line. The results of the conversions are stored in ADR1 - ADR4. CD - CA specify the single line for all four conversions. Table 12 - 1 shows the values of CD - CA for each input line. If MULT = 1, then one conversion is made on each of four separate lines. The results are stored in ADR1 - ADR4. Only CD and CC have any effect in determining which four lines take the data. The four lines and the location of the A/D data are shown in Table 12 - 1.
To start the A/D conversions, write the value to $1030 that configures SCAN, MULT, CD, CC, CB, and CA for the desired data acquisition. This action automatically clears the Conversion Complete Flag, CCF in ADCTL (bit 7 of $1030). CCF is set when four A/D conversions are completed. If SCAN = 1, CCF is set after the first four conversions are completed and remains set until a subsequent write to ADCTL ($1030). There is no interrupt for CCF. As such, polling operations must be used to monitor CCF. Once the microcontroller has completed the conversions, CCF is set. The data in ADR1 - ADR4 represents valid conversion values. It takes 128 machine cycles to make four eight-bit conversions. At 2 MHz, this is an impressive data acquisition rate.
There are many types of A/D conversion techniques. MC6811 uses a successive approximation technique. Some other types of A/Ds are the counter, integrative and flash A/Ds.
Direct current (DC) motors used in the lab have coils wound on the rotor and a permanent magnet stator. Current flowing through the rotor coils interacts with the magnetic field of the permanent magnet stator and generates an Ampere force, which turns the rotor. A collector is used to transfer the current from the stationary terminals of the DC motor to the rotating coils. In order to keep the DC motor rotating in the same direction, the collector switches (commutates) the rotor coils each half-cycle). DC motors are usually high speed, low torque motors.
Stepper motors used in the lab have coils wound on the stator, and a permanent magnet with multiple poles as a rotor. The stepper motors can achieve angular motion in finite steps. To make the stepper motor rotate, one has to send certain energizing patterns to the coils in a predetermined sequence. This is achieved with the microcontroller. The patterns can be coarse (full-steps) or fine (half-steps). Half-step patterns fall between the full-step patterns. The use of half steps gives better resolution. However, the half-step holding power is weaker than the full-step holding power, since only half of the coils are energized.