Report 3 Interrupts =================== Jonathan Higgins 1. Introduction =============== 1.1. What is an Interrupt? -------------------------- An interrupt is an unexpected hardware initiated subroutine call or jump that temporarily suspends the running of the current program. Interrupts occur when a peripheral device asserts an interrupt input pin of the micro-processor. Provided the interrupt is permitted, it will be acknowledged by the processor at the end of the current memory cycle. The processor then services the interrupt by branching to a special service routine written to handle that particular interrupt. Upon servicing the device, the processor is then instructed to continue with what is was doing previously (by use of a special "return from interrupt" instruction). Interrupts are used to ensure adequate service response times by the processing. Sometimes, with software polling routines, service times by the processor cannot be guaranteed, and data may be lost. The use of interrupts guarantees that the processor will service the request within a specified time period, reducing the likelihood of lost data. Once the interrupt routine is completed, the interrupt mask bit should be cleared, enabling the servicing of other future or pending interrupts, then a special Return From Interrupt instruction should be executed. This instruction restores the machine registers to the state they were in before the interrupt occurred. When the processors registers are restored to their pre-interrupt state, the program counter will be pointing to the next instruction of the program which was interrupted. The processor will then fetch that instruction, decode and execute it, ie, continue executing the program from where it was interrupted. 2. Getting Started. =================== 2.1. What is needed? -------------------- The components needed are exactly the same as the previous report. Not all of these items listed will be used, but they may be useful in determining problems with your program, or your setup. The compiler and upload programs will be necessary. A terminal program will be needed to test the code that will be written. Windows 9x comes with a terminal emulator called Hyperterm. This program is very simple to use and basic instructions are available here. Parts needed: IBM compatible PC with serial ports Micro-Stamp11 MS11M32K-FRA Serial Cable Docking Module MS11DM-RA-M1 ribbon cable solder-less breadboard adapter disk 68HC11 Utilities 30 gauge Jumper Wires solder-less breadboard +5v Power Supply several LED's (8) piezo speaker 2.2. Using HyperTerminal ------------------------ On most Windows 95 machines, HyperTerminal should be installed without explicitly requesting it. If you need to install a copy of the standard Hyperterminal program, go to the Start menu, choose the Settings option, and click on Control Panels option. Double Click on the Add/Remove Programs icon and click on the Windows Setup tab at the top of the window. Hyperterminal is located in the Communications group. The program that starts HyperTerminal is HYPERTRM.EXE. It is located under Start Menu: Programs; Accessories: Hyperterminal. The ?HYPERTRM.EXE icon looks like a computer connected to a modem. Double-click on the icon to start the modem program. The first time you start HYPERTRM.EXE, you will be prompted for country code and area code. You do not have to fill in these codes. To avoid problems with the default value for the area code, uncheck the "Use country code and area code" box at the bottom of the dialog window. Choose OK to proceed and you will not encounter this screen again. HyperTerminal will then prompt you for information on the connection you would like to establish. On the line "Connect using:" click on the drop down menu and select the port that connects the PC to the MicroStamp11.(Direct to Com 2) Then press Ok. A Com port Properties window will open asking you to configure the port settings. Change the following parameters Bits per second: 9600 Data bits: 8 Parity: None Stop bits: 1 Flow control: Hardware Click on Ok to close this dialog box. Your terminal should be ready to communicate with the MicroStamp11. If you need to make changes to this connection, go to File:Properties: and then select the port that the connection is on or press Configure to change the parameters. Like many Windows applications, HyperTerminal has a button bar on the top of its screen that incorporates the most often-used features of the program. The functions of these buttons are as follows: New: Allows you to enter to a different phone number / group of settings.This process follows steps #1-#4 in the previous section. Open: Allows you to open a different phone number / group of settings that you have saved previously. Connect: If you are not already connected, this dials the current phone number. Disconnect: Hangs up a connection. Send: Sends a file from your local computer to the remote computer to which you are connected. If you are not sure where the file is you wish to send, click on the Browse button. You may also want to check to see if the protocol menu item is set to Zmodem (the transfer option most commonly used at CCSF). Receive: Once a file has been sent from the remote computer, click on this button to start receiving it on your local computer. Again, check to make sure the protocol matches the one used to send the file (typically Zmodem). Properties: Allows you to change the various configuration options for the session. 3. The Component Programs of our Interrupt Program ================================================== The following programs are provided as a reference for building an Interrupt Program on the MicroStamp11. The light program was provided earlier in report1, and the serial communication is available in report2. 3.1. Simple Light Program ------------------------- In previous reports a light routine called "Output" was used as a display process for controlling lights. This program will also use "Output". Refer to Report 1 for the light connection table. org $e000 begin: ldaa #$4 staa $3f lds #$ff ;initialize stack pointer setupD: ldaa #$3f ;This section will initialize staa $9 ; PortD for use loop: ldaa #$0 ;Load the decimal value 0 into Register A bsr L1 ;Branch to L1 bra loop ;Branch to Loop L1: bsr Output ;Branch to Output bsr Delay ;Branch to Delay inca ;increment the value in Register A bne L1 ;Branch if not equal to Zero rts ;Return to Subroutine Delay: ;This is the same delay function ldy #$8fff ; except this time we decrease the D1: dey ; delay. bne D1 rts Output: ;This is the function that puts the tab ; data in the correct locations to andb #$3f ; make the lights turn on and off stab $8 ; tab - transfers data from Register A to B tab ; andb - is a masking technique andb #$c0 ; stab - stores the data in B to a location rorb ; rorb - Rotates the data in B to the right rorb ; do this again stab $0 rts ;return from subroutine org $fffe fdb begin 3.2. Simple Serial Program -------------------------- The following program will send a string of characters to a terminal through serial communication. This program is similar to previous serial communication programs. org $0040 ;start at bottom of memory block charcnt rmb 1 ;Variable Definition reserving 1 byte org $e000 ;start at top of 8k EEPROM begin: ldaa #$04 ;disable COP in CONFIG register staa $3f lds #$ff ;initialize the Stack pointer to high memory ldaa #$30 ;load the bit-pattern 0011 0000 staa $2b ;Store this in the SCI Baud Rate Control ; Register, This will effectively set the ; baud rate for serial communication to 9600 ldaa #$8 ;load the bit-pattern 0000 1000 staa $2d ;Store this into the SCI Control Register 2 ; This will enable the Transmitter only clr charcnt ;initialize the variable (Not sure if this is ; needed) Print: clr $0 ldaa #endmsg-begmsg ;load A with the difference between the ; addresses of endmsg and begmsg cmpa charcnt ;Compare A to charcnt blo Here ;Branch if lower Trans: brclr $2e #$80 Trans ;Branch to Trans if $2e (SCI Status Register) ; matches the bit-pattern 1000 0000 ldx #begmsg ;load register X with the address of begmsg ldab charcnt ;load register b with the value in charcnt abx ;add the value in b to the value in x and ; store this in x ldaa 0,x ;load register a with x and 0 offset staa $2f ;store this value into $2f (SCI Data Register) inc charcnt ;increment the value in charcnt bra Print ;branch to subroutine Print Here bra Here ;loop until program stops begmsg fcc 'The program has started' ;This is the message to be ; printed fcb $0d ;line feed endmsg fcb $0a ;carriage return org $fffe ;define the reset vector to point to fdb begin ; the beginning of your code 4. Building the Interrupt Program ================================= 4.1. The Planning ----------------- The program will combine the 2 previous programs and introduce interrupts. The idea is to use the light program as the primary application and attempt to have it running 95% of the time. The light program will stop when a key is pressed on the keyboard. This key press is the interrupt and will the program will jump to the interrupt service routine. After completing the interrupt routine, the lights will start again. The lights program will need to be modified to make it fit into this application. The "Output" routine and connections to the lights will need to be changed, because PD0 and PD1 are RxD and TxD respectively, which are required for serial communication. The new light wiring configuration follows: Port LED PIN# ...................... ....................... ...................... PD2 8 18 PD3 7 17 PD4 6 16 PD5 5 15 PA3 4 5 PA4 3 4 PA5 2 3 PA6 1 2 The following is the new Output subroutine. Output: ;This makes the lights work tab ;transfer reg A to reg B rolb ;rotate the data in b to the left rolb ;rotate the data in b to the left stab $8 ;store B to PortD or PD tab ;transfer reg A to reg B rorb ;rotate the data in b to the right stab $0 ;store B to PortA or PA rts ;return from subroutine Other considerations for this program include, setting the correct bits in the SCCR2 (SCI Control Register 2) for either receive or transmit. 4.2. The Code ------------- The code for this program will increment the lights like a binary counter, and when a key is pressed on the terminal the string "The input character was " followed by the key that was pressed will be printed to the screen. The counter will have a brief pause during the printing of the message, but should continue to increment after the printing to the terminal has completed. **************************** *SETUP INTERRUPTS **************************** org $ffd6 ;org to Interrupt Vector fdb sciisr ;sci interrupt vector **************************** *VARIABLES **************************** org $0040 ;org to low memory charcnt rmb 1 ;num chars transmitted inchar rmb 1 ;reserved input char *************************** *MAIN PROGRAM *************************** org $e000 ;org to top of eeprom begin: ldaa #$04 ;load mask 0000-1000 into reg A staa $3f ;store in COP to Disable watchdog *************************** *INITIALIZATION *************************** lds #$ff ;Initialize Stack Pointer ldaa #$30 ;select bit-mask 0011-0000 staa $2b ;store a in BAUD for 9600 clr $2c ;set SCCR1 to 0 for 1,8,1 ldaa $2f ;Dummy read to clear the buffer ldaa #$24 ;set Rec and Rec Interrupt enable staa $2d clr charcnt cli ; turn on Interrupt System *************************** *Light Initialization *************************** ltsrt: ldaa #$8 ;load mask 0000 1000 staa $26 ;store in PACR to set PA3 to output ldaa #$3c ;load mask 0011 1100 staa $9 ;store in DDDR to set PD2-5 to output *************************** *WAIT FOR INTERRUPTS *************************** here: jmp start ; jump to light program * ; wait here for interrupt *************************** *SCI INTERRUPT SERVICE ROUTINE *************************** sciisr ;Starting point for Interrupt routine ldx #$0 ;clear X ldy $2f ;store the contents of $2f in register y ldaa #$08 ;set Trans enable staa $2d ; and store in SCCR2 Print: ldaa #endmsg-#strtmsg ;store the difference between the addr cmpa charcnt ;compare the value in register a to blo Pincom ; charcnt and branch to Pincom if the * ; value in A is smaller than charcnt Trans: brclr $2e #$80 Trans ;Branch to Trans if $2e (SCI Status Register) * ; matches the bit-pattern 1000 0000 ldx #strtmsg ;Load X with the address of strtmsg ldab charcnt ;load b with the value in charcnt abx ;add the value in b to x and store in x ldaa 0,x ;load register a with x and 0 offset staa $2f ;store A into $2f (SCI Data Register) inc charcnt ;increment the value in charcnt bra Print ;branch to subroutine Print Pincom: sty $2f ;Store Y into $2f (SCI Data Register) rep brclr $2e #$80 rep ;Branch to rep if $2e matches 1000 0000 ldaa carrtrn ;Load A with the value at carrtrn staa $2f ;Store A into $2f (SCI Data Register) rep2 brclr $2e #$80 rep2 ;Branch to rep2 if $2e matches 1000 0000 ldaa linefeed ;Load A with the value at linefeed staa $2f ;Store A into $2f (SCI Data Register) rep3 brclr $2e #$80 rep3 ;Branch to rep3 if $2e matches 1000 0000 clr $2f ;clear the SCI Data Register bra rtsci ;branch to rtsci routine ************************** *Return from SCI interrupt ************************** rtsci: cli ;Clear all interrupts ldaa #$24 ;set Rec and Rec interrupt enable staa $2d ;i and store it in SCCR2 clr charcnt ;reset charcnt to 0 rti **************************** *OUTPUT TO TERMINAL **************************** strtmsg: fcc 'The input character was ' ;text endmsg: carrtrn: fcb $0d ;carriage return linefeed: fcb $0A ;line feed ****************************** *Light Incrementing Program ****************************** start: ldaa #$8 ;load mask 0000 1000 staa $26 ;store in PACR to set PA3 to output ldaa #$3c ;load mask 0011 1100 staa $9 ;store in DDDR to set PD2-5 to output ldaa #$0 ;load 0000 0000 into reg A L1: bsr Output ;Branch to Output bsr Delay ;Branch to Delay inca ;increment the value in Register A bra L1 ;Branch to L1 to Repeat Delay: ;This is the same delay function ldy #$ffff ; from other our other programs except this D1: dey ; time we decrease the delay. bne D1 rts Output: ;This makes the lights work tab ;transfer reg A to reg B rolb ;rotate the data in b to the left rolb ;rotate the data in b to the left stab $8 ;store B to PortD or PD tab ;transfer reg A to reg B rorb ;rotate the data in b to the right stab $0 ;store B to PortA or PA rts ;return from subroutine ***************************** *end light program ***************************** org $fffe ;define the reset vector to point to fdb begin ; the beginning of code. Compile all of the previous programs with the Mstamp11 software and store them in eeprom to execute. Follow the example instructions from the first report to compiling and uploading of source code. 4.3. The explanation -------------------- Please read the comments next to each line of code. Take note that the program will stay inside the subroutine L1 until an interrupt occurs. This subroutine is inside the Light program portion of the code. The most important piece of information that is needed for this program to be successful, is to "cli" clear the interrupts during the "rtsci" subroutine. Without this command, the program may loop indefinitely. Lastly, if this program produces garbage on your terminal, restart your terminal session. This program is a bit more complex than some of the previous examples. It took several iterations of code before this program was completed. Remember to read the documentation about your MCU processor before attempting to write a program similar to the previous.