Chapter 4: Advanced Assembly Programming EE383: Introduction to Embedded Systems University of Kentucky Samir Rawashdeh With slides based on material by H Huang Delmar Cengage Learning
Chapter Summery The same sequence of instructions often need to be executed in several places of the program The subroutine mechanism enables the programmer to group the common instruction sequence into a subroutine A subroutine can be called from many places The processor saves the return address in the stack during a subroutine call The subroutine restores the return address from the stack before it returns to the caller The subroutine can receive parameters from the caller to perform operations and may return result to the caller
The HCS2 CPU Registers 7 A 7 B 5 D 8-bit accumulator A and B or 6-bit double accumulator D 5 X Index register X Stack Pointer 5 Y 5 SP Index register Y Stack pointer 5 PC Program counter S X H I N Z V C Condition code register Carry Overflow Zero Negative I Interrupt mask Half-Carry (from bit 3) X Interrupt Mask Stop Disable Figure HCS2 CPU registers 3
The Stack Low address Top element SP High address Bottom element Figure 4 Diagram of the HCS2 stack
HCS2 Support for the Stack Data Structure - A 6-bit stack pointer (SP) - Instructions and addressing mode Table 4 HCS2 push and pull instructions and their equivalent load and store instructions Mnemonic pshb pshc pshd pshx pshy pulb pulc puld pulx puly Function push A into the stack push B into the stack push CCR into the stack push D into stack push X into the stack push Y into the stack pull A from the stack pull B from the stack pull CCR from the stack pull D from the stack pull X from the stack pull Y from the stack Equivalent instruction staa, -SP stab, -SP none std 2, -SP stx 2, -SP sty 2, -SP ldaa, SP+ ldab, SP+ none ldd 2, SP+ ldx 2, SP+ ldy 2, SP+
Example 4 Derive the stack contents after the execution of the following instruction Sequence: lds #$5 ldaa #$2 ldab #4 pshb ldx # pshx Solution: $28 $2 SP (= $4FC) Figure 42 The contents of the HCS 2 stack
What is a Subroutine? A sequence of instructions that can be called from many places of the program The program flow during a subroutine call is shown in Figure 43 Saving and restoring return address is the key for the subroutine mechanism to work caller subroutine _x <call> subroutine _x Figure 43 Program flow during a subroutine call <return >
Instructions that Support Subroutine Call bsr <sub>: branch subroutine <sub> is specified in relative addressing mode and is in the range of -28 to +27 bytes from the instruction immediately after the bsr <sub> instruction The return address is pushed into the stack jsr <sub>: jump subroutine <sub> is specified in direct, extended, indexed, and indexed indirect mode The subroutine being called can be within the range of 64 kb The return address is pushed into the stack call <sub>: call subroutine The <sub> field specifies the page number and the address of the subroutine within the page to be called The page number is to be loaded into the PPAGE register rts: return from subroutine restrieve the return address from the stack and return to the caller rtc: return from call This instruction retrieve the page number and the return address from the stack
Issues related to Subroutine Calls Parameter Passing Use CPU registers Use stack Use global memory 2 Result Returning Use CPU registers Use stack Use global memory 3 Local Variable Allocation Allocated in the stack Use the instruction leas -n,sp to allocate n bytes of space in stack Use the instruction leas n, SP to deallocate n bytes from stack
Saving CPU Registers in Stack The subroutine may use some CPU registers that were used by its caller The subroutine must save these registers in order to make sure the caller program can obtain correct result The subroutine must restore the saved registers before returning to the caller The order of register restoration must be reversed to that to which registers are saved if the saving order is pshx pshy pshd then the restoring order is puld puly pulx
Stack Frame - The region in the stack that holds incoming parameters, the subroutine return address, local variables, and saved registers is referred to as stack frame - The stack frame is also called activation record Local variables SP Saved registers Return address Incoming parameters Figure 49 Structure of the 68HC2 stack frame
Using the D-Bug2 Functions to Perform I/O Operations Table 42 D-Bug2 monitor (version 4xx) routines Subroutine far main ( ) getchar ( ) putchar ( ) printf ( ) far GetCmdLine ( ) far sscanhex ( ) isxdigit ( ) toupper ( ) isalpha ( ) strlen ( ) strcpy ( ) far out 2hex ( ) far out 4hex ( ) SetUserVector ( ) far WriteEEByte ( ) far EraseEE ( ) far ReadMem ( ) far WriteMem ( ) Function Start of D -Bug2 Get a character from SCI or SCI Send a character out to SCI or SCI Formatted string output -translates binary values to string Get a line of input from the user Convert ASCII hex string to a binary integer Check if a character (in B) is a hex digit Convert lowercase characters to uppercase Check if a character is alphabetic Returns the length of a NULL -terminated string Copy a NULL-terminated string Output 8-bit number as two ASCII hex characters Output a 6-bit number as four ASCII hex characters Set up a vector to a user 's interrupt service routine Write a byte to the on -chip EEPROM memory Bulk erase the on -chip EEPROM memory Read data from the HCS 2 memory map Write data to the HCS 2 memory map pointer address $EE8 $EE84 $EE86 $EE88 $EE8A $EE8E $EE92 $EE94 $EE96 $EE98 $EE9A $EE9C $EEA $EEA4 $EEA6 $EEAA $EEAE $EEB2
Subroutines for Creating Time Delays Example 4 Write a subroutine that can create a time delay of ms Solution: Delayms pshx ldx #6 ; 2 E cycles iloop ; 2 E cycles ; 2 E cycles ; 2 E cycles ; 2 E cycles ; 2 E cycles ; 2 E cycles ; 2 E cycles nop ; E cycle nop ; E cycle dbne x,iloop pulx rts
The previous subroutine can be modified to create a time delay that is a multiple of ms as follows (the multiple is passed in Y): delaybyms pshx eloop3 ldx #6 ; 2 E cycles iloop3 ; 2 E cycles ; 2 E cycles ; 2 E cycles ; 2 E cycles ; 2 E cycles ; 2 E cycles ; 2 E cycles nop ; E cycle nop ; E cycle dbne x,iloop3 dbne y,eloop3 pulx rts
Introduction to Parallel I/O Port and Simple I/O Devices A HCS2 device may have from 48 to 44 pins arranged in 3 to 2 I/O Ports An I/O port consists of a set of I/O pins and the registers required to control its operation An I/O pin can be configured for input or output An I/O pin usually serves multiple functions When it is not used as a peripheral function, it can be used as a general-purpose I/O pin Addressing the I/O Port Data Register When inputting or outputting data from or to an I/O port, the user read from or write to the port data register Each I/O port register is assigned to an address in the HCS2 memory space For example, Port A data register is assigned to address, the next instruction output $35 to Port A: movb #$35, ; address is Port A data register A name is also assigned to each register so that we can access a register by referring to its name: PTA equ movb #$35,PTA ; output $35 to Port A The name and address association is established by including the HCS2inc file to your program using the #include c:\\hcs2inc statement
Configuring I/O Pin Direction Each I/O port has a data direction register DDRx (x is the port name) that configures the direction of each pin By setting a bit of the DDRx register to, the corresponding I/O pin is configured for output By setting a bit of the DDRx register to, the corresponding I/O pin is configured for input Input and Output Operations movb #$FF,DDRB ; configure Port B for output staa PTB ; output the contents of A to port B movb #$67,PTB ; output the value $67 to Port B movb movb #,DDRC ; configure Port C for input PTC,ibuf ; read the contents of Port C and save it at the memory ; location represented by ibuf
The HCS2 I/O ports and Pin Names Table 45 Number of pins available in each paralle port Port Name No of Pins Pin Name A B E H J K M P S T PAD, PAD L U V W 8 8 8 8 4 7 8 8 8 8 6 8 8 8 8 PA7~PA PB7~PB PE7~PE PH7~PH PJ7~PJ PK4~PK PM7~PM PP7~PP PS3~PS PT7~PT PAD 5~PAD PL7~PL PU7~PU PV7~PV PW 7~PW
Interfacing with LEDs An LED has an anode and cathode terminal The anode terminal must at a voltage at least 6 V above that of the cathode terminal (forward biased) in order for the LED to be lighted The forward current required to light an LED is from a few to more than ma The I/O pin can drive an LED using one of the circuits shown in Figure 45 The resistors R, R2, are R3 are called current-limiting resistors VCC VCC Port pin R (a) Positive direct drive Port pin R2 (b) Inverse direct drive Port pin 74HC4 (c) Buffered drive R3 Figure 45 An LED connected to a CMOS inverter through a current -limiting resistor
Interfacing with Seven-Segment Displays Seven-segment displays are mainly used to display decimal digits and a small set of letters The HCS2 I/O port can drive a seven-segment display directly Buffer chips are used mainly to save excessive current draw from the HCS2 A example circuit for interfacing with seven-segment display is shown in Figure 47 Some people may use PB to PB6 to drive segment a to g instead The microcontroller must send an appropriate value to the output in order to display a certain value HCS2 PB6 PB5 PB4 PB3 PB2 PB PB 74HC244 47 each a b c f a g b d e e c f d g com m on cathode Figure 47 D riving a single seven -segm ent display
Table 47 Decimal to seven-segment decoder Decim al digit 2 3 4 5 6 7 8 9 Segm ents a b c d e f g Corresponding Hex Number Figure 47 circuit $7E $3 $6D $79 $33 $5B $5F $7 $7F $7B Dragon2 demo board $3F $6 $5B $4F $66 $6D $7D $7 $7F $67 Displaying Multiple Seven-Segment Displays A time-multiplexing technique is often used to display multiple digits The circuit in Figure 48 can display up to six digits simultaneous using the timemultiplexing technique The HCS2 lights one digit for a short period of time and then switches to the next digit Within one second, each digit is lighted in turn many times Due to the persistence of vision, all six digits appear to be lighted at the same time
8 a b 8 g # a b g # a b g #5 PB 74HC244 PB PB6 74HC367 common cathode common cathode common cathode PP A Y PP A Y HCS2 PP2 PP3 PP4 A2 A3 A4 Y2 Y3 Y4 PP5 A5 Y5 Figure 48 Port B and Port P together drive six seven -segment displays (MC9S2DG256) To display 7 on the display #5 movb #$FF,DDRB ; configure Port B for output movb #$3F,DDRP ; configure Port P for output movb #$F,PTP ; enable display #5 to be lighted movb #$7,PTB ; send out the segment pattern of 7
Example 45 Write a program to generate a -khz periodic square wave from the PT5 pin Solution: #include "c:\miniide\hcs2inc" org $5 start lds #$5 bset DDRT,BIT5 ; configure PT5 pin for output forever bset PTT,BIT5 ; pull PT5 pin to high ldy # ; wait for 5 ms jsr delayby5us ; bclr PTT,BIT5 ; pull PT5 pin to low ldy # ; wait for 5 ms jsr delayby5us ; bra forever #include "c:\miniide\delayasm" ; org $FFFE ; dcw start end
Example 46 Write a program to generate a two-tone siren that alternates between 25 Hz and 5 Hz with each tone lasting for half of a second #include "c:\miniide\hcs2inc" org $5 start lds #$5 bset DDRT,BIT5 ; configure PT5 pin for output forever ldx #25 ; repeat 5 Hz waveform 25 times tone bset PTT,BIT5 ; pull PT5 pin to high ldy # jsr delaybyms bclr PTT,BIT5 ldy # jsr delaybyms dbne x,tone ldx #25 ; repeat 25 Hz waveform for 25 times tone2 bset PTT,BIT5 ldy #2 jsr delaybyms bclr PTT,BIT5 ldy #2 jsr delaybyms dbne x,tone2 bra forever #include "c:\miniide\delayasm" end
Interfacing with DIP Switches A dual-in-line package can be connected any port with 8 pins A set of pull-up resistors are needed to pull the voltage to high on one side of the DIP V CC SW DIP-8 K PA PA PA2 PA3 PA4 PA5 PA6 PA7 HCS2 Figure 49 Connecting a set of eight DIP switches to Port A of the HCS 2 To read data into accumulator A movb #,DDRA ; configure port A for input ldaa PTA ; read into accumulator A
Tips for Program Debugging Involving Subroutine Calls What to do when the program gets stuck? Step Find out which subroutine gets stuck by setting a breakpoint immediately after the jsr or bsr instruction Step 2 Find out why the subroutine gets stuck - Forgetting to restore registers pushed onto the stack before return - Forgetting to deallocate local variables before return - There are some infinite loops in the subroutine - Calling other subroutines that do not return