Serial Communications 8051 Serial I/O: One Subroutine For Two Conditions

Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

Serial Communications 8051 Serial I/O

Serial Data (8 or 9 bit) is asynchronous (not synchronized The 8051 has:


to system clock): • sending and receiving shift registers

• logic for generating the clocks

• bytes can arrive an any time • logic to detect if the STOP bit is present

• the CPU has two status bits in PSW to inform the user • status bits to indicate when data has been received,

when either of these conditions occur: • status but showing sending data has finished being

shifted out
• RI – (Receive) - set if a new byte has arrived
• TI – (Transmit) - set if another byte may be send Serial Interface is controlled by two registers:

SCON - serial control register


Handling Unpredictable Events SBUF - serial data buffer register

• Polling – the software periodically checks the status


bits to see if: SCON (memory address 98H)
• a new byte has arrived – RI will be set
• a new byte may be sent – TI will be set Has bits to define:
- number of bits sent (mode bits)
• Interrupts – the CPU calls a subroutine automatically - optional 9th send and receive bits
if either RI or TI are set: - Receive enable bit (REN)
- TI – the transmit interrupt flag
one subroutine for two conditions: (TI is set when char sent)
à the subroutine must the check to see which - RI – the receive interrupt bit
condition (RI/TI/both) caused the interrupt (RI is set when character has been received)

SBUF (99H) – one name - two registers


- when read, accesses last character received
- when written, stores byte to be sent via the Send Shift
Register (here just part of the Serial port subsystem)
Serial I/O and Interrupts 1 Copyright 2005 Giovanni Moretti Serial I/O and Interrupts 3 Copyright 2005 Giovanni Moretti

Sending Data Serially & Asynchronously SCON – Serial Port Control Register
To send parallel data serially (one bit at a time), a shift
register can be used:
SM0 SM1 SM2 REN TB8 RB8 TI RI
Q0 Serial Bit 7 Bit 0
data
Parallel Load SR out
Clock SR Shift Register SM0 SCON.7 Serial Port Mode see below
SM1 SCON.6
1 D7 D6 D5 D4 D3 D2 D1 D0 0
SM2 SCON.5 Enables Multiprocessor I/O in mode
Parallel Data In
2&3
REN SCON.4 Receive Enable if REN=1
If only two wires are used, the clock can't be sent BUT if TB8 SCON.3 9th Data bit to send in 9bit mode
clock period is known, then using START and Stop bits and RB8 SCON.2 in Modes 2 & 3, 9th data bit received
synchronising on falling edge of START bit will suffice. TI SCON.1 Transmit Interrupt Flag – sending
Start D0 D1 D2 D3 D4 D5 D6 D7 Stop finished
TI must be reset by software
RI SCON.0 Receive Interrupt Flag – new byte
Start 1 1 0 0 1 0 1 0 Stop available
RI must be reset by software

Start 1 1 1 1 1 1 1 1 Stop
SM0-1 Mode Bit Definition
SM0 SM1 Mode Description Baud Rate
Start 0 0 0 0 0 0 0 0 Stop
00 0 Shift Register Clock/12
X x x x x x x x x X
01 1 8 Bit UART Variable
10 2 9 Bit UART Clock/32 or 64
Wait for this edge
11 3 9 Bit UART Variable
Delay ½ bit time – then clock Receiving Shift Register at these points
dddddd UART – Universal Asynchronous Receiver/Transmitter
All of this logic is built into the 8051 Serial: Shift-registers & Stop/Start & control logic

Serial I/O and Interrupts 2 Copyright 2005 Giovanni Moretti Serial I/O and Interrupts 4 Copyright 2005 Giovanni Moretti
Polling Serial I/O Demo Interrupts
è Interrupts are Hardware-Initiated Subroutine Call
org 00h
; Set up Timer 1 to act as clock for Serial Port
to a predefined location.

mov tmod,#20h ; Set Timer1 to Mode 2


mov th1,#0fdh ; Reload value
;================================================ Interrupts map Events to Subroutines
; SETUP SERIAL PORT

mov scon,#50h ; Serial Mode Either:


mov tcon,#40h ; Start Timer
;================================================ ♦ Different subroutine address called for each event
; Save char to memory – as a Log
mov r0,#$60 ; Serial Buffer ptr
;================================================ or
; Setup Done, Main Program starts here

lup: acall getch ; Get char from keybd


♦ each event has a (set of) distinct status bits
mov @r0,a ; put into Log buffer these bits are tested by subroutine to determine
inc r0 ; inc log pointer what action to take.
clr c
subb a,#32 ; convert to upper case
acall putch ; Display Character
sjmp lup ; do again
;================================================ 8031 processor supports both methods
; GETCH – get a character
getch: jnb ri,getch ; Character arrived?
mov a,sbuf ; Get it
clr ri ; Clear Ch Ready flag
ret ; return char in A
;================================================
; PUTCH – Output a character

putch: clr ti ; Reset TI bit


mov sbuf,a ; Store ch in A to Output
gone: jnb ti,gone ; Wait until it's gone
ret ; return

Serial I/O and Interrupts 5 Copyright 2005 Giovanni Moretti Serial I/O and Interrupts 7 Copyright 2005 Giovanni Moretti

Interrupts Sources of Interrupt on 8051


I/O operations can be controlled in two ways – by Polling
and or under Interrupt IE0 - External pin A changed state
TF0 - Timer Flag 0 (timer counter overflow)
IE1 - External Pin B changed state
Polling TF1 - Timer Flag 1 (timer 1 counter overflow)
The processor continually checks the status of the RI+TI - Serial Port needs attention
device (polls) to see if some condition is satisfied

Interrupt Vectors
Interrupts The address jumped to by the hardware for each source of
Hardware-forced subroutine call – can happen between interrupt is fixed.
any two instructions.
Interrupt Vector Address
Reset 0000H (not really an Interrupt)
// Start address of Program code
Polling vs Interrupts
Polling Advantages IE0 0003H
TF0 000BH
♦ simple
IE1 0013H
♦ no unexpected events TF1 001BH
♦ easy to program/debug SBUF (TI or RI) 0023H
♦ Fast response

Multiple Events on One Interrupt


Polling Disadvantages
• There is one vector for the serial I/O device, but two
♦ Wastes CPU sources of interrupt
♦ Nothing else happens until event has
occurred • The Serial Interrupt Handler must test either RI or TI to
♦ Hard to have more than one pending event determine what caused the interrupt.
(programming becomes complex)
Serial I/O and Interrupts 6 Copyright 2005 Giovanni Moretti Serial I/O and Interrupts 8 Copyright 2005 Giovanni Moretti
CPU Action upon an Interrupt Pending Interrupts
Although a device may request attention, an interrupt may
♦ May clear interrupt flag not happen immediately, or at all.

♦ Push PC onto stack (so can get back) Interrupts will be delayed:

♦ Jump to location corresponding to interrupt source until end of current instruction


(replace PC with vector address) OR
until end of higher priority interrupt handler
♦ Start executing Interrupt Service Routine (ISR)

The usual sources of Interrupt (RI, TI, Timer Flag bits)


won’t cause an interrupt if:

Returning from Interrupt Global interrupt bit (EA) = 0 // All Interrupts Suppressed
The RETI instruction must be used (not RET)
OR
The RETI Instruction:
Device interrupt enable bit = 0 // Specific Device
// Interrupt suppressed
• pops PC off the stack (restores the PC)

• informs the interrupt subsystem that the handler has


completed.
The Device Status bits are Always Valid
Changes in the state of the processor's I/O devices will
always be shown by the status bits (eg RI or TI),
à but these conditions may not cause Interrupts.

Serial I/O and Interrupts 9 Copyright 2005 Giovanni Moretti Serial I/O and Interrupts 11 Copyright 2005 Giovanni Moretti

When Can Interrupts Occur? Minimal Serial Interrupt Demo


;-------------------------------------------
An interrupt will be acknowledged at the end of the current ; Everything under interrupt - there is no mainline
instruction IF: ; It uppercases characters and echoes them
; and also stores them at internal data ram location 60 …
Device’s Flag is set ;-------------------------------------------
à the Device has Requested Attention org 00h
sjmp main
;-------------------------------------------
AND ; Put an code at serial interrupt vector
Interrupts are Enabled
à Global Interrupt Enable Bit (EA/IE.7) is set org $23
sjmp serint
AND ;-------------------------------------------
Device’s Interrupt Enable bit is set org 30h
main: mov tmod,#20h ; Timer1 Mode 2
à programmer is allowing this Device to Interrupt
mov th1,#0fdh ; Reload value
mov scon,#50h ; Serial Mode
AND NONE of the following are true: mov tcon,#40h ; Start Timer

• an interrupt of same/greater priority is being serviced mov r0,#$60h ; Display pointer


à stop Interrupt subroutines from being interrupted
mov sp,#10h ; Define stack area
• an RETI is in progress
;-------------------------------------------
à let the Interrupt handler return to the mainline ; INTERRUPT INITIALISATION
setb ES ; Serial interrupts ON
• the current instruction is modifying IP or IE setb EA ; Master interrupt ON
à interrupt enable/priority registers being updated
; INTERRUPTS ARE NOW ACTIVE
• the current instruction has not completed
; Main Program
à only acknowledge interrupts between instructions
dead: sjmp dead ; Sit in Infinite Loop
; or a more useful program
Serial I/O and Interrupts 10 Copyright 2005 Giovanni Moretti Serial I/O and Interrupts 12 Copyright 2005 Giovanni Moretti
Serial Interrupt Handler Common problems using Interrupts
There will be a Serial Interrupt whenever the user presses a
key: • not allowing for increased stack use caused by interrupt
handler
SerInt: • leaving interrupts active when no longer required
; What caused Interrupt • interrupt happen unexpectedly
jb ri,RCV_ch ; Is RI set, à must protect shared variables (simplest
; Yes - char arrived technique is to temporarily disable interrupts)

clr ti
; No - must be TI Danger of Shared Variable Access
reti ; Ignore Transmit
; Interrupts If specific measures aren't taken to stop unexpected access
;------------------------------------------- to variables shared between (or accessed by both) Interrupt
; RECEIVE INTERRUPT HANDLER Subroutines and the main program, unexpected results will
almost certainly be obtained.
RCV_ch: push psw ; Save Registers
push acc
This is because, mentally, the programmer expects
mov a,sbuf ; Get the char statements to execute in the order they're written, but
clr ri ; Clear Rcv flag between any pair of statements, an Interrupt may occur.

mov @r0,a ; Put char in IRAM This produces an unexpected (and unpredictable) change in
inc r0 the order statements are executed.
clr c
subb a,#32 ; ch to uppercase This can result in:
• unexpected changes in data values
mov sbuf,a ; now send char so
• erratic program behaviour (different each time you
; user can see it
run the program)
Exit: pop acc ; Restore Acc pop
pop psw ; and PSW These bugs are very difficult to diagnose. It is best to stop
such bugs happening rather than try and find them later
reti ; return to mainline

Serial I/O and Interrupts 13 Copyright 2005 Giovanni Moretti Serial I/O and Interrupts 15 Copyright 2005 Giovanni Moretti

Interrupts – System Setup Example of Shared Variables & Interrupts


Consider a Clock Interrupt Routine invoked via interrupt
Initialisation every second, using globals to hold the current time-of-day:
Setting up conditions that will allow interrupts to
happen var hours, minutes, seconds; //Globals:current time

Interrupt Handler procedure Clock_Interrupt_Handler ; // called every second


Taking appropriate action on each interrupt begin
inc(seconds)
Termination if seconds = 60
Ensuring that interrupts won’t happen if they’re no second:= 0
longer needed (eg a TI interrupt must be deactivated if inc(minutes);
If time is 8:59:59:
there’s no more data to send) if minutes = 60 then
minutes:= 0; after: h:=hours
inc(hours) a Clock Interrupt
if hours = 24 then occurs!!!
Initialisation hour:= 0
end; Interrupt Handler
- Define the interrupt handler subroutine
then updates all
- it must preserve any registers that it uses // User access to Time of hours, minutes,
- Save registers on entry to routine Procedure GetTime(var h,m,s); & seconds to
- restore them just before RETI begin 9:0:0
h:= hours;
- Put a Jump to subroutine instruction at the interrupt m:= minutes;
s:= seconds; Returned time
vector location for that specific interrupt
end; will be will 8:0:0
WRONG!
- Make sure Stack pointer is defined
Guarantee Exclusive Access to Hours, Minutes & Seconds:
Procedure GetTime(var h,m,s);
- Set Device-specific Interrupt-enable bit
begin
Disable_Interrupts;
All is now set up: h:= hours; m:= minutes s:= seconds;
- Allow Interrupts: Enable_Interrupts;
Set Master Interrupt Enable bit // System is LIVE end;
Serial I/O and Interrupts 14 Copyright 2005 Giovanni Moretti Serial I/O and Interrupts 16 Copyright 2005 Giovanni Moretti

You might also like