NivaarExam PrepOfficial exam papers ↗

22-Elec-A4 Digital Systems and Computers · May 2015

Question 5 of 6: Interrupt-driven serial echo and RS-232 waveforms

Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)

Notes on this paper

Paper format. National Exams, May 2015 — 07-Elec-A4 Digital Systems & Computers. Three hours, closed book, one approved Casio or Sharp calculator. Six questions are printed and five constitute a complete exam; every question is worth 12 marks, with the per-part split printed in the marking scheme on page 1. A flip-flop excitation table and a Boolean-identity sheet are attached to the paper. All six questions are solved below, so that the set works as a complete study resource.

Reference texts.

Question 5 (12 marks) — Interrupt-driven serial echo and RS-232 waveforms

Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.

Given. A memory-mapped asynchronous serial port already initialised at 9600 baud, 8 data bits, no parity, one stop bit; a blocking receive subroutine inchar at $\mathtt{FFCD}_{16}$ returning the character in ACCA; status, control, transmit-data and receive-data registers at known addresses; and the received character ‘U’ $=\mathtt{55}_{16}$, whose lower-case partner ‘u’ $=\mathtt{75}_{16}$. CMOS levels apply on the board.

Find. (a) the algorithm of a program that receives one character, inverts its letter case, and transmits it under interrupt control; (b) labelled time waveforms of the transmitted frame, on the board and on the RS-232 cable, with both scales marked.

Approach. Exploit the ASCII property that case is a single bit, so the conversion is one exclusive-OR; then split the program into a foreground routine that arms the transmitter and an interrupt service routine that performs the single write, which is what “using interrupts” requires. For part (b) compute the bit time from the baud rate and lay the frame out in the order the UART shifts it.

  1. Establish the case-conversion rule. In ASCII the upper-case letters occupy $\mathtt{41}_{16}$–$\mathtt{5A}_{16}$ and the lower-case letters $\mathtt{61}_{16}$–$\mathtt{7A}_{16}$; the two ranges differ only in bit 5. Checking the given pair, $\mathtt{55}_{16}\oplus\mathtt{20}_{16}=\mathtt{75}_{16}$, so $\boxed{\text{case inversion}=\text{ACCA}\oplus\mathtt{20}_{16}}$ — a single EORA #$20 instruction that works in both directions, which is exactly what “to lowercase if uppercase, or vice versa” asks for. A compare-and-branch on the ranges would also work but costs several instructions and one conditional branch.
  2. Set up the vector and the flag. Before anything else the program writes the address of the transmit interrupt service routine into the serial-port interrupt vector, clears a one-byte RAM flag TXBUSY, and enables the CPU's global interrupt mask (CLI). The transmitter interrupt enable bit in CR stays off at this point: an idle UART asserts “transmit data register empty” permanently, so enabling it before there is anything to send would cause an immediate and useless interrupt.
  3. Main routine.
    1. JSR $FFCD — call inchar; it blocks until a character arrives and returns it in ACCA.
    2. EORA #$20 — invert the case.
    3. STAA TXCHAR — save the converted character in a RAM buffer that the ISR will read.
    4. Set TXBUSY, then set the transmit-interrupt-enable bit in CR (a read-modify-write of CR, so that the receiver's control bits are not disturbed).
    5. Wait on TXBUSY (or simply proceed with other work) — the transfer now completes in the background.
  4. Transmit interrupt service routine. The UART requests an interrupt as soon as TDR is empty. The ISR then: reads SR (which is also how most UARTs arm the flag clear); confirms the transmit-empty bit is the cause, and if not, chains to the receive handler; writes TXCHAR to TDR, which both loads the shift register and clears the request; clears the transmit-interrupt-enable bit in CR so no further interrupt is raised once this one character has gone; clears TXBUSY; and returns with RTI. Because exactly one character is to be sent, disabling the enable bit inside the ISR is essential — otherwise the ISR would be re-entered endlessly on the permanently-empty TDR.
  5. Additional routines needed. Only three: inchar (supplied), the transmit ISR described above, and a short initialisation block that installs the vector and clears the flag. No transmit polling loop appears anywhere in the program, which is the point of the question.
  6. (b) Compute the bit time. At 9600 baud with one bit per symbol, $$t_{\text{bit}}=\frac{1}{9600\ \text{baud}}=104.17\ \mu\text{s}.$$ The frame is one start bit, eight data bits and one stop bit, so its total length is $10\times104.17\ \mu\text{s}=1.0417\ \text{ms}$.
  7. Lay out the transmitted pattern. The character actually sent is the converted one, ‘u’ $=\mathtt{75}_{16}=01110101_2$. A UART shifts the least significant bit first, so the data bits leave in the order $b_0\dots b_7=1,0,1,0,1,1,1,0$. The complete line pattern, in time order, is therefore $$\boxed{\underbrace{0}_{\text{start}}\;\underbrace{1\,0\,1\,0\,1\,1\,1\,0}_{b_0\dots b_7\ \text{of}\ \mathtt{75}_{16}}\;\underbrace{1}_{\text{stop}}}$$ with the line idling at logic 1 (mark) before and after.
  8. Assign the two voltage scales. On the board, CMOS levels apply: a mark (logic 1) is $+3.3\ \text{V}$ and a space (logic 0) is $0\ \text{V}$, with the line idling high. On the cable, the RS-232 driver both inverts and shifts to a bipolar swing: a mark becomes a negative voltage and a space a positive one, typically $\pm 9\ \text{V}$ for a driver into a $3\ \text{k}\Omega$ load (the standard requires the driver to exceed $\pm 5\ \text{V}$ and permits up to $\pm 15\ \text{V}$). The start bit is therefore the first positive excursion on the cable, and the idle line sits negative.
(i) TxD on the board, before the RS-232 driver (CMOS levels, 9600 baud)+3.3 V mark = 10 V space = 0St0b01b10b21b30b41b51b61b70Sp1idleidle(ii) the same stream on the RS-232 transmit line (after the driver)+9 V space = 0-9 V mark = 1St0b01b10b21b30b41b51b61b70Sp1idleidle10 bit times = 1.0417 ms1 bit = 104.17 μs
Question 5(b) — the transmitted frame for ‘u’ $=\mathtt{75}_{16}$, before the driver (top) and on the RS-232 cable (bottom). Both scales are marked; note the inversion between the two.
Question 5 — final results
QuantityValue
Case conversion$\text{ACCA}\oplus\mathtt{20}_{16}$; check $\mathtt{55}_{16}\oplus\mathtt{20}_{16}=\mathtt{75}_{16}$
Character transmitted‘u’ $=\mathtt{75}_{16}=01110101_2$
Bit time$104.17\ \mu\text{s}$
Frame length10 bits $=1.0417\ \text{ms}$
Line pattern (time order)$0\;1\,0\,1\,0\,1\,1\,1\,0\;1$ (start, $b_0\dots b_7$, stop)
Board levels (CMOS)mark $=+3.3\ \text{V}$, space $=0\ \text{V}$, idle high
Cable levels (RS-232)mark $=-9\ \text{V}$, space $=+9\ \text{V}$, idle negative (inverted)