Answerws to the final examination paper for ELE538, Fall 96 ========== Answers to Part A ================================================= A1. If the stack pointer is undefined, it may well be pointing at an unsuitable memory location (such as a ROM address, a void address, or a RAM address with insufficient depth). In these instances, any use of stack memory, such as JSR or interrupt of any kind, may result in a loss of return address, thus causing a program crash. A2. Failure of the ball to bounce from any wall has everything to do with the way the program detects the condition for the bounce. It is not always possible to have an exact match between the current ball position and the position of the wall when the ball speed is higher than 1. [In this instance, if the student uses the BEQ code, and say the speed is +3 and the ball's last position is 254, then the ball's next position should be 254 + 3 = 257, which becomes 1 because of the overflow for the 8-bit data. Hence the desired "bounce condition" took place, and the ball emerge from the opposite wall!] The solution is to change the bounce condition so that as long as the ball is within the wall by the amount of the speed component, it should bounce. A3. The problem is how to determine the point after the 16th character has been sent. There are two easy solution. We could introduce a local variable within the subroutine. This variable should be initialized to 0 and increased by 1 for every character sent. After that variable reaches 16, we switch the cursor to the second line of LED display. (counting from 16 to 0 works equally, if not better). [Another solution is to create a new value equal to the address parameter plus 16. Then when the address pointer finally matches this value. it is time to switch the cursor to the second line before any more character is to be displayed.] A4. string fcc "The output is " char_1 fcc "0." char_2 fcc "0 volts\0" form_ans psha lsra lsra lsra lsra ora #$30 ; same with adda #'0' staa char_1 pula anda #$0F ora #$30 staa char_2 rts A5. a. IRQ vector linkage have not been setup properly b. system mask (I-bit of the CCR) may never got cleared c. column outputs to the keypad have not been set to all 0's A6. Adding 10,000 to the value already stored in TOC2 causes the next interrupt to occur exactly 10,000 cycles from the last interrupt. Adding 10,000 to the current value taken from the main timer counter produces a slightly longer delay because it also includes the additional time from the moment of interrupt to the moment of reading the main timer counter. ========== Answer to Part B ================================================= B1. a) Possible required connections are: keyboard columns is driven from output pins of PC3-PC0. (a to PC0, b to PC1, c to PC2, d to PC3.) keyboard rows is sent to input pins of PC7-PC4. (e to PC4, f to PC5, g to PC6, h to PC7.) negative going IRQ signal (j) is sent to input pin of STRA. b) Required initializations are: configure the port C data direction ldaa #%00001111 staa DDRC configure the PIOC for interrupt by negative going STRA input ldaa #%01000000 staa PIOC initialize the IRQ vector org $00EE ; program in RAM | or org $FFF4 ;program in ROM jmp IRQ | fdb IRQ clear the STAF bit ldaa PIOC ldaa PORTCL clear the system I-mask cli initialize the column output to all LOW ldaa #0 staa PORTC c) to scan the leftmost column ldaa #%xxxx01111 staa PORTC to read back the row result from scan ldaa PORTC raw data for successful scanning of key "8" raw_data = %10110111 (different value for different connection) -------------------------------------------------------------------------- B2. a) In the conventional arrangement of connecting multiple IRQ signals to the same IRQ input bus, once any one of the I/O devices makes an interrupt request, the system must response by further polling inside the ISR in order to resolve the source of the intererupt request. Furthermore, interrupt priority amongst these devices comes by the order of the polling. In the case where additional IRQ channels are handled by the 6811's input capture channels, such arrangement offers the following features: 1. Each interrupt request has its own separate interrupt vector address. With polling being unnecessary, the response of the interrupt is faster. 2. The input capture channel can accommodate either active LOW or active HIGH signal. (IRQ input pin is always active LOW) 3. Individual interrupt priority is a built-in feature of the 6811. 4. The time of the active signal is also captured in a 16-bit register. b) - Determine what prescale factor is required, and set the PR1:PR0 bits at TMSK2 ($1024) accordingly. - Disable all interrupt by writing $00 to TMSK1 ($1022). (This measurement does not really need interrupt, if the pulse-with is within the range of the 16-bit value) - Program the EDG1B:EDG1A bits at TCTL2 ($1021) to rising edge (0:1) initially. (it will be set for the negative edge during the measurement) - Clear the IC1F bit by writing a '1' to that bit (bit-2 of TFLG1 at $1023) - Wait until ICIF is set, then save the captured time of the arrival of the rising edge from the TIC1 ($1010/1) register, reprogram the EDG1B:EDG1A bits at TCTL2 for the falling edge (1:0), and clear the IC1F flag bit. - Wait until ICIF is set again, then read the captured time of the arrival of the falling edge. - Result of the pulse-with measurement can be obtained by subtracting the rising_edge_time from the falling_edge_time (ignoring any under-flow) c) ldaa TMSK2 anda #%11111100 staa TMSK2 ;set the PR1:PR0 bits to 0:0 ldaa #0 staa TMSK1 ;disable all interrupt ldaa #%00010000 staa TCTL2 ;set the EDG1B:EDG1A bits to rising edge ldaa #%00000100 staa IC1F ;clear the IC1F bit wait_r ldaa TFLG1 ;4~ | wait_r brclr TFLG1,X,%00000100,wait_r 7~ bits #%00000100 ;2~ | beq wait_r ;3~ | ldd TIC1 ;5~ | ldd TIC1,X 5~ std rising_edge_time;5~ | std rising_edge_time 5~ ldaa #%00100000 ;2~ | ldaa #%00100000 2~ staa TCTL2 ;4~ | staa TCTL2,X 4~ ldaa #%00000100 ;2~ | staa TFLG1 ;4~ | bclr TFLG1,X,%11111011 7~ wait_f ldaa TFLG1 ; | wait_f brclr TFLG1,X,%00000100,wait_f bits #%00000100 ; | beq wait_f ; | ldd TIC1 ; | ldd TIC1,X subd rising_edge_time; | subd rising_edge_time std pulse_width ; | std pulse_width d) Minimum measurable pulse-width is determined by the minimum time it takes from the first time the TFLG1 flag is set to the second time it is set again. Base on the first set of 6811 code above, that time is 31~. The alternative code produces a minimum measurable pulse-width of 30~. -------------------------------------------------------------------------- B3. a) Minumum connections required for sending data from Computer A to Computer B are: - Tx data of Computer A to Rx data of Computer B - ground of Computer A to ground of Computer B - DTR of Computer B to DSR & DCD of Computer B b) RS232 levels: (H = +12v, L = D = -12v) Tx data = LLLHHHHLLLHHLHHLHHLLHHLLL (characters '82') s01234567Ss01234567S where s = start bit S = Stop bit 0-7 = data bit position Bit time = 1/9600 = 104.2 microsecond Each character takes 10 bit times (1 start + 8 data + 1 Stop), therefore, maximum rate of character stream = 9600/10 = 960 characters per second. c) Write %00110000 to BAUD register ($102B) ; 9600 baud at 2 MHz E clock Write %00000000 to SCCR1 register ($102C) ; M = 0 Write %00001000 to SCCR2 register ($102D) ; TE = 1, no interrupt d) send_data ldaa SCSR bpl send_data ; wait until TDR is empty (TDRE=1) ldaa 0,x beq exit ; exit on null terminating byte staa TDR ; otherwise transmit current character inx bra send_data ; repeat for next character in string exit rts -------------------------------------------------------------------------- B4. a) (answer coming) @ 1 Mhz, b) For an MCU write, output data would be valid by PWEL + tr +tDDW = 477 + 20 + 190.5 = 687.5 ns Thus, RAM setup time = Tcyc - 687.5 = 1000 - 687.5 = 312.5 ns. c) For MCU read, input data would be valid no later than Tcyc - tDSR - tf = 1000 - 30 - 20 = 950 ns. Addresses A7-A0 would be valid at PWEL - tAVM + tDlatch = 477 - 271.5 + 10 = 215.5 ns. Thus, address access time must be less than 950 - 215.5 = 734.5 ns.