You are on page 1of 21

Laboratory Short Course

SERIAL I/O The Serial Peripheral


Interface

www.freescale.com/universityprograms

Freescale and the Freescale logo are trademarks of Freescale Semiconductor, Inc.
All other product or service names are the property of their respective owners
Freescale Semiconductor, Inc. 2006.
Document Number: LABS12DT256INTRO31 /REV 0

Reading this Document


Answers provided to the Instructor assume that the reader is using Freescale HCS12DT256 Family Student Learning
Kit, and CodeWarrior development software.

This short course has been created using an adapted version of the Process Oriented Guided Inquiry Learning (POGIL)
method. For more information visit www.pogil.org

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

Software
Development

Applications / Solutions / Products

Overview

Focus and Motivate:

High speed data digital input and output, such as can be achieved with parallel I/O, is not needed in many
applications. In these cases a serial I/O interface may fit your requirements. There are a variety of serial I/O
interfaces and protocols, including the asynchronous serial communications interface (SCI), synchronous
peripheral interface (SPI), universal serial bus (USB), controller area network (CAN), and the interintegrated circuit (IIC).

This module helps the


student to use the SPI
in a simple singlemaster/slave
application. It does not
cover multiple masters,
bidirectional operation
or mode fault
detection.

Although many applications where multiple devices are connected together use the USB, CAN or IIC
interfaces, the SPI gives us a simple, easy to understand method to communicate that can send and
receive data faster than some of the other serial I/O protocols. This module will help you learn the
fundamentals of the synchronous serial peripheral interface SPI.

Learning Objectives
In this module we will help you learn about the SPI. To successfully apply it you need to understand the
fundamentals of the synchronous operation of the interface. We will help you discover these and learn how
the SPI in the HCS12 microcontroller is programmed for use.

Success Criteria
When you complete this module you will be able to use the SPI port to connect your microcontroller to
another device with an SPI interface.

More Resources and Further Information


Cady, Fredrick M., Software and Hardware Engineering: Assembly and C Programming for the
Freescale HCS12 Microcontroller, 2nd edition. (New York: Oxford University Press, Inc., 2008), Chapter 15
HCS12 Serial I/O SCI and SPI.

The Basics of Synchronous Serial Communications

Teach:

The SPI transfers data between a device acting as a master and one acting as a slave. The master
controls all data transfer between it and the slave by providing a clock to synchronize the data transfer.
Figure 1 shows two SPIs that allow data to be interchanged between two microcontrollers. Each SPI has a
buffer register that you write your data into or read data from. There are two shift registers and the master
generates a shift clock, SCK, to control when a bit is shifted out from and in to each of the shift registers.

To indicate an activelow signal we append


"_L" to the signal
name. Thus, SS_L is
an asserted-low signal.

PM 4
S h i f t R e g is t e r

PM 2

M OSI
M IS O

PM4
PM2

S h ift R e g is te r

B u ffe r R e g is te r

B u ff e r R e g is te r

S h ift C lo c k

PM5

V DD

M 68H C S12 M ASTER


SS_L

Freescale Semiconductor

SCK

PM 5

PM 3

M 68H C S12 SLAVE


PM3

SS_L

LABS12DT256INTRO31, Rev 0

Figure 1 Serial Peripheral Interface (reprinted with permission of Oxford


University Press, Inc.)

SPI Terminology
MOSI: Master Out/Slave In signal. Also called Serial Data Out (SDO) in some devices.
MISO: Master In/Slave Out signal. Also called Serial Data In (SDI) in some devices.
SCK: Shift Clock. Generated by the master. It controls the shifting of data out of and in to the shift
registers.
SS_L: Slave Select (active low) signal. On an HCS12 this external connection activates the SPI to be a
slave when its MSTR control bit is zero.
Explore 1.

Answers:

1.

See Instructor's Notes


below.

Search the internet and generate a list of the different types of devices that have SPI capability.

Explore 2.

Answers:

1.

See Instructor's Notes


below.

Search the internet and generate a list of manufacturers of SPI devices.

SPI Control Registers


The SPI has a variety of control registers, like all of our programmable devices, and programming it for a
single master single slave operation is fairly simple.
Explore 3.

Answers:

1.

1) for S12DT256,
SPI0DR: Base +
$00DD; SPI1DR: Base
+ $00F5; SPI2DR:
Base + $00FD

The SPIDR is the SPI Data Register that you use to write and read data.
a.

What is the address of the SPIDR?

Explore 4.

Answers:

1.

See Instructor's Notes


below.

Any of SPInCR1 SPI Control Register 1 has eight bits.


a.

Give the name and function of each bit:


Bit 7:
Bit 6:
Bit 5:

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

Bit 4:
Bit 3:
Bit 2:
Bit 1:
Bit 0:
b.
2.

What is the address for SPI1CR1?

What bits are used and how are they initialized to enable the SPI, set it for master mode, and send
the least significant bit first?

Explore 5.

Answers:

1.

See Instructor's Notes


below.

Any of SPInCR2 SPI Control Register 2 has four bits.


a.

Give the name and function of each bit:


Bit 4:
Bit 3:
Bit 1:
Bit 0:

b.

What is the address for SPI0CR2?

Explore 6.

Answers:

1.

See Instructor's Notes


below.

The data rate (bits per second) is set by initializing an SPInBR SPI Baud Rate Register.
a.

What is the address for SPI2BR?

b.

If you assume an 8 MHz bus clock, what is the fastest data rate available in your
microcontroller?

c.

What is the slowest?

d.

With what value will you initialize the baud rate register to achieve a data rate of 500 kHz?

SPI Clock Phases

Teach:

The SPI was designed to be able to be connected to a variety of devices other than other microcontrollers
such as digital-to-analog and analog-to-digital converters, real-time clocks, and memory. Because a strict
timing protocol has not been specified to identify when, relative to the data being valid, the shift clock is
asserted, the master SPI can generate four different data latch timing protocols to accommodate different
timing requirements of other SPI devices.

It is useful to review
with the students the
different types of
latches, positive or
negative, edge and
level triggered, that are
available. This serves
to illustrate why
different clocking
schemes are needed.
The need for setup and
hold times for the
latches is important
too.

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

ID L E

D A T A T R A N S M IS S IO N

ID L E

SS_L

M O S I/M IS O
CPHA CPOL
0

0
S a m p le

S a m p le

S a m p le

S a m p le

1
C lo c k P h a s e w it h C P H A = 0

M O S I/M IS O

0
S a m p le

S a m p le

S a m p le

S a m p le

S a m p le

1
C lo c k P h a s e w it h C P H A = 1
Figure 2 SPI clocks (reprinted with permission, Oxford University Press, Inc.)

Figure 2 shows that two bits, CPHA and CPOL, control when, and on what edge, data bits are latched. The
SPI starts its data shift sequence by asserting SS_L. When CPHA = 0 the MOSI data becomes valid at this
time and rising or falling edges are selected by CPOL. Some serial shift register devices require the device
to be selected (by the SS_L signal) before MOSI has valid data. In this case CPHA = 1 and we see a halfcycle delay. Again CPOL selects rising or falling edges.
Explore 7.
The programmer may control how the SS_L signal is used. Review your information on the SPInCR1 and
SPInCR2 registers.
1.

What two bits control how the SS_L signal is used by the master SPI?

2.

How must they be initialized so that the SS_L is asserted when the master sends data as shown in
Figure 2?

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

Problem 1

Resources:

A design is required to connect a 74HC595 8-Bit Serial-Input/Serial or Parallel-Output Shift Register with
Latched 3-State outputs to your SPI.

The data sheet for the


MC74HC595 from
www.onsemi.com
shows pinouts as
shown on the
Freescale student
project board. The TI
and Phillips data
sheets for the
SN74HC595 use
different pin
nomenclature. It may
be a useful exercise for
students to sort out the
difference.

1.

Find a data sheet for the 74HC595 shift register.

2.

To which pin on the 74HC595 will you connect the MOSI signal?

3.

To which pin on the 74HC595 will you connect the MISO signal?

4.

To which pin on the 74HC595 will you connect the SCK signal?

5.

Which edge of the SCK clock signal shifts data into the shift register?

6.

If you wish the three-state outputs to be permanently enabled, which pin would you use and to what
level (high or low) will you tie it?

7.

What are your options for the Reset signal on pin 10?

8.

The system design requires the parallel outputs to be latched when all 8 data bits have been shifted
in. What signal from the SPI would you use and to which pin on the 74HC595 will you connect it?

9.

Referring to Figure 2, how will you initialize CPOL and CPHA? Why did you make this choice?

10.

Which is to be the first bit shifted? How should LSBFE be initialized?

11.

Refer to the AC Electrical Characteristics of the 74HC595 shift register.


a.

What is the maximum clock frequency allowed? Under what conditions?

b.

Can the SCK frequency of your microcontroller be programmed to be lower than the maximum
allowed frequency?

c.

What is the minimum pulse width for the 74HC595 shift clock? Under what conditions?

d.

When your microcontroller is programmed for the fastest SPI data rate, what is its minimum
pulse width?

e.

What is the minimum setup time for the serial data input to the shift clock? Under what
conditions?

f.

When your microcontroller is programmed for the fastest SPI data rate, what will be the setup
time for the serial data output to the SCK edge in use?

The ON
Semiconductor data
sheet does not show
the assertion levels for
the signal names so
the student must
carefully read the data
sheet to understand
what is active-high and
what is active-low. The
TI data sheet uses the
conventional * to
indicate an active-low
signal.
Answers:
See Instructor's Notes
below.

Explore 8.

Answers:

1.

See Instructor's Notes


below.

The SPInSR SPI Status Register has three bits giving status information.
a.

Give the name and function of each bit:


Bit 7:
Bit 5:
Bit 4:

b.
2.

What is its address?

What bit must be monitored to ensure you do not try to write to the SPInDR until the last data transfer
is complete? What state is the bit when it is safe to send new data?

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

Problem 2

Resources:

You are to now connect a 74HC595 shift register to the SPI port on your microcontroller and demonstrate
that you can send and receive data from it.

The Freescale Project


Board uses a
74HC595 shift register
for its LCD interface. A
student could use this
to demonstrate
mastery of the SPI.
See Instructor's Notes
below.

1.

Prepare a written test plan to show that you have implemented this and that it works correctly.

Research 1

Enrichment:

1.

Expand the design required in Problem 1 to allow up to eight 74HC595 shift registers, all connected to
the SPI. Draw a block diagram showing how you would connect these to be able to write to each one
independently without disturbing data in any of the others.

2.

What changes are needed in your software?

The students have to


recognize that each of
the devices must be
addressed in some
way. Using a 74HC138
decoder as shown
below is one way to do
that.
The students should
see that the serial data
output is not a threestate output so it
should not be
connected to MISO
unless a three-state
buffer is used.
Once the students
have solved the
addressing problem in
this exercise, the way
in which other serial
interfaces, such as the
IIC, address devices
can start to be
explored.

Research 2

Enrichment:

Another way to achieve an SPI-like serial output without the SPI is to use what is known as "bit banging".
By using four bits of a parallel port you can simulate the MOSI, MISO, SCK and SS_L signals. You must
meet the receiving device's setup and hold times and supply the proper clock edge. A downside of this
approach is that it requires some software overhead and is generally slower than a true SPI.

A student completing
this exercise shows
that a complete
understanding of the
SPI has been gained.

1.

Using four bits from a parallel port (Port M is a good choice because it is all ready being used for the
required signals), create an SPI-like data transfer to the 74HC595 shift register using bit banging and
verify that it works properly.

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

Answers:
1) See Instructor's

2.

How would you determine what data rate (bits/sec) you can achieve with this technique?

Notes below.
2) The assembly
solution below
achieves about 26 KHz
and the C solution
about 150 kHz. These
times were found by
measuring the SS_L
time with an
oscilloscope.

Communication Reporting
1.

You and your laboratory partner are to prepare a design report documenting what you have learned in
this module. It should include the following:
a.

Answers for all exploration questions and for Problem 1

b.

Your written test plan and any modifications you had to make to ensure you tested your modules
adequately.

c.

A source listing of your test program.

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

Instructor's Notes
Explore 1.
Analog-to-digital converter, analog switch, audio mixer, controller area network (CAN) controller, digital potentiometer, digital
signal processor, digital-to-analog converter, EEPROM, flash memory, LCD controller, LED display driver, high voltage display
driver, microcontroller, multimedia card, multiplexer pressure sensor, real-time clock, temperature sensor, touch screen
controller, UART, USB controller
Explore 2.
AKM Semiconductor, Altera, Analog Devices, Atmel, Cirrus Logic, Fairchild Semiconductor, Freescale Semiconductor, Infineon
Technologies, Intel, Intersil, Lattice Semiconductor, Linear Technology, Maxim, Microchip Technology, National Semiconductor
(Microwire), ON Semiconductor, Ramtron International, SanDisk, STMicroelectronics, Texas Instruments, Winbond Electronics,
Xilinx, Zilog
Explore 4.
1.

Any of SPInCR1 SPI Control Register 1 has eight bits.


Give the name and function of each bit:

a.

Bit 7: SPIE: SPI Interrupt Enable.


Bit 6: SPE: SPI System Enable.
Bit 5: SPTIE: SPI Transmit Interrupt Enable.
Bit 4: MSTR: SPI Master/Slave Mode Select.
Bit 3:BIT2: CPOL, CPHA: SPI Clock Polarity and Clock Phase.
Bit 1: SSOE: Slave Select Output Enable.
Bit 0: LSBFE: SPI Least Significant Bit First.
What is the address for SPI1CR1? BASE + $00F0

b.
2.

What bits are used and how are they initialized to enable the SPI, set it for master mode, and send the least significant bit
first?? SPE = 1, MSTR = 1, LSBFE = 0.

Explore 5.
1.

Any of SPInCR2 SPI Control Register 2 has four bits.


a.

Give the name and function of each bit:


Bit 4: MODFEN: Mode Fault Enable.
Bit 3: BIDIROE: Output Enable in Bidirectional Mode.
Bit 1: SPISWAI: SPI Stop in Wait Mode.
Bit 0: SPC0: Serial Pin Control Bit 0

b.

What is the address for SPI0CR2? BASE + $00D9

Explore 6.
1.

The data rate (bits per second) is set by initializing an SPInBR SPI Baud Rate Register.

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

2.

a.

What is the address for SPI2BR? BASE + $00FA

b.

If you assume an 8 MHz bus clock, what is the fastest data rate available in your microcontroller? 4 MHz

c.

What is the slowest? 3.91 kHz

With what value will you initialize the baud rate register to achieve a data rate of 500 kHz? 1610

Explore 7.
The programmer may control how the SS_L signal is used. Review your information on the SPInCR1 and SPInCR2 registers.
1.

What two bits control how the SS_L signal is used by the master SPI? SSOE in SPICR1 and MODFEN in SPICR2.

2.

How must they be initialized? SSOE = 1, MODFEN = 1.

Problem 1
A design is required to allow you to connect a 74HC595 8-Bit Serial-Input/Serial or Parallel-Output Shift Register with Latched
3-State outputs to your SPI.
1.

Find a data sheet for the 74HC595 shift register. The ON Semiconductor data sheet is very useful as it gives VCC ranges
from 2 to 6 volts. All answers below are from this data sheet.

2.

To which pin on the 74HC595 will you connect the MOSI signal? Pin 14

3.

To which pin on the 74HC595 will you connect the MISO signal? Pin 9

4.

To which pin on the 74HC595 will you connect the SCK signal? Pin 11

5.

Which edge of the SCK clock signal shifts data into the shift register? Rising edge.

6.

If you wish the three-state outputs to be permanently enabled, which pin would you use and to what level (high or low)
will you tie it? Pin 13 tied low.

7.

What are your options for the Reset signal on pin 10? There are three possibilities. Reset could be controlled by the
microcontroller with a spare output bit, it can be connected to a power-on reset signal, or it can be tied high.

8.

The system design requires the outputs to be latched when all 8 data bits have been shifted in. What signal from the SPI
would you use and to which pin on the 74HC595 will you connect it? Use SS_L and connect it to pin 12.

9.

Referring to Figure 2, how will you initialize CPOL and CPHA? Why did you make this choice? You can choose CPOL=0,
CPHA=0 or CPOL=1, CPHA=1. These both give a rising edge after the serial data is stable.

10.

Which is to be the first bit shifted? How should LSBFE be initialized? Most significant bit first, LSBFE = 0.

11.

Refer to the AC Electrical Characteristics of the 74HC595 shift register.


a.

What is the maximum clock frequency allowed? Under what conditions? For operation at 3.0 volts, -55 to 25C, fmax
= 15 MHz.

b.

Can the SCK frequency of your microcontroller be programmed to be lower than the maximum allowed frequency?
For the HCS12 with bus clock = 8 MHz, the maximum SCK frequency is 4 MHz.

c.

What is the minimum pulse width for the 74HC595 shift clock? Under what conditions? For operation at 3.0 volts,
-55 to 25C, tw = 40 ns.

d.

When your microcontroller is programmed for the fastest SPI data rate, what is its minimum pulse width? Assuming
50% duty cycle and 4 MHz clock, tw = 125 ns.

e.

What is the minimum setup time for the serial data input to the shift clock? Under what conditions? For operation at
3.0 volts, -55 to 25C, tSU = 40 ns.

f.

When your microcontroller is programmed for the fastest SPI data rate what will be the setup time for the serial data

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

10

output to the SCK edge in use? 125 ns.

Explore 8.
1.

The SPInSR SPI Status Register has three bits giving status information.
a.

Give the name and function of each bit:


Bit 7: SPIF: SPI Interrupt Flag.
Bit 5: SPTEF: SPI Transmit Empty Interrupt Flag.
Bit 4: MODF: Mode Fault Flag.

b.
2.

What is the address for SPI0SR? BASE + $00DB

What bit must be monitored to ensure you do not try to write to the SPInDR until the last data transfer is complete? What
state is the bit when it is safe to send new data? SPIF = 1.

Problem 2
You are to now connect a 74HC595 shift register to the SPI port on your microcontroller and demonstrate that you can send
and receive data from it.
1.

Prepare a written proposal including a test plan to show that you have implemented this and that it works correctly.
There are a variety of proposals the students might come up with depending on the hardware you are using. They could
connect a 74HC595 chip to the SPI and use the outputs to drive LEDs and demonstrate that the LEDs change value
according to an output sequence. If your students are using the Freescale project board with the SPI being used for the
LCD interface, a 74HC595 is on the board. The students can output data and check signal levels with an oscilloscope or
they could output a sequence of changing values and by reading the data register in between each they would see that
the value read was the last value output, thus verifying the circular shift register operation. Here is some example code
that does this. Their test plan should explicitly state what is expected each time they write to and read from the SPInDR.
For the program given below when a breakpoint is set at the nop, the expected results are the following:

Breakpoint

Output Value (A)

1
2
3
etc

0
1
2
etc.

Input Value (B)


Unknown, variable
0
1
etc.

Metrowerks HC12-Assembler
(c) COPYRIGHT METROWERKS 1987-2003
; Testing the SPI using the Freescale Project Board
; export symbols
XDEF Entry, main
; we use export 'Entry' as symbol. This allows us to
; reference 'Entry' either in the linker .prm file
; or from C/C++ later on
; symbol defined by the linker for the end of the stack
XREF __SEG_END_SSTACK

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

11

; variable/data section
MY_EXTENDED_RAM: SECTION
; Insert here your data definition.
BIT7:
SET
%10000000
BIT6:
SET
%01000000
BIT5:
SET
%00100000
BIT4:
SET
%00010000
BIT3:
SET
%00001000
BIT2:
SET
%00000100
BIT1:
SET
%00000010
BIT0:
SET
%00000001
ALLBITS:
SET
%11111111
BASE:
SET
0
;********************************
; Register definitions
;********************************
; SPI Control Registers
SPICR1:
SET
BASE+$00D8
SPIE:
SET
BIT7
SPE:
SET
BIT6
SPTIE:
SET
BIT5
MSTR:
SET
BIT4
CPOL:
SET
BIT3
CPHA:
SET
BIT2
SSOE:
SET
BIT1
LSBFE:
SET
BIT0
SPICR2:
SET
BASE+$00D9
MODFEN:
SET
BIT4
BIDIROE:
SET
BIT3
SPISWAI:
SET
BIT1
SPCO:
SET
BIT0
SPIBR:
SET
BASE+$00DA
SPISR:
SET
BASE+$00DB
SPIF:
SET
BIT7
SPTEF:
SET
BIT5
MODF:
SET
BIT4
SPIDR:
SET
BASE+$00DD
; code section
MyCode:
SECTION
main:
Entry:
LDS #__SEG_END_SSTACK
bset SPICR1,SPE|MSTR|SSOE
bclr SPICR1,CPOL|CPHA
bset SPICR2,MODFEN
clr
clra
staa

SPIBR

brclr
ldab
nop
inca
staa
bra

SPISR,SPIF,wait_1
SPIDR

SPIDR

main_loop:
wait_1:

Freescale Semiconductor

SPIDR
main_loop

;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

Control Register 1
SPI Interrupt Enable
SPI Enable
Transmit Interrupt Enable
Master/Slave Select
Clock Polarity
Clock Phase
Slave Select Output Enable
LSB-First Enable
Control Register 2
Mode Fault Enable
Bidirectional Output Enable
SPI Stop in Wait Mode
Serial Pin Bit Control
SPI Baud Rate Register
SPI Status Register
SPI Interrupt Flag
Transmit Empty Int Flag
Mode Fault Flag
SPI Data Register

;
;
;
;
;
;
;
;
;

initialize the stack pointer


Enable SPI, master mode
CPOL=0, CPHA=0
Enable SS_L slave select output
to assert the output latch signal
Set 4 MHz data rate
Initialize test data value
Send the first value
DO WHILE SPI is busy

;
;
;
;
;

ENDWHILE SPI is busy


Read data to reset the SPIF
To use the debugger for testing
Change to the next output value
Write a data value

LABS12DT256INTRO31, Rev 0

12

Problem 2 Solution in C
/* C program to test the operation of the SPI */
/***********************************************************/
#define p_SPICR1 (unsigned char *) 0x00D8
#define p_SPICR2 (unsigned char *) 0x00D9
#define p_SPIBR (unsigned char *) 0x00DA
#define p_SPISR (unsigned char *) 0x00DB
#define p_SPIDR (unsigned char *) 0x00DD
#define SPE 0x40
#define MSTR 0x10
#define CPOL 0x08
#define CPHA 0x04
#define SSOE 0x02
#define MODFEN 0x10
#define SPIF 0x80
/***********************************************************/
void main(void) {
static unsigned char spi_tx_data = 0;
static unsigned char volatile spi_rx_data;
/* Initialize I/O
* Enable SPI, master mode, CPOL=0, SPHA=0 */
*p_SPICR1 |= SPE | MSTR | SSOE;
*p_SPICR1 &= ~(CPOL|CPHA);
/* Enable SS_L slave select to assert the output latch */
*p_SPICR2 |= MODFEN;
/* Set 4 MHz data rate */
*p_SPIBR = 0;
/* Send the first value */
*p_SPIDR = spi_tx_data;
for(;;) {
/* Wait until SPI is not busy */
while ((*p_SPISR & SPIF) == 0);
/* Get the current data */
spi_rx_data = *p_SPIDR;
/* Send the next data */
*p_SPIDR = ++spi_tx_data;
/* Set a breakpoint here */
} /* wait forever */
}

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

13

Research 1
MOSI
M IS O

SPI

SCK

V DD

SS_L

V DD
CS1
CS3
A0
A1
A2
74H C 138
CS2

C h ip S e le c t
B its f r o m a
S p a re I/O
P o rt

T o O th e r
L a tc h C lo c k s

R eset

V DD
SQH

R eset

SQH

SCK

QH

SCK

QH

L a tc h C lo c k

QG

L a tc h C lo c k

QG

74H C 595

QE

74H C 595

QE

QF

QD

U p to 7
M o re
74H C 595s

QF

QD

QC

QC

QB

QB

O u tp u t E n a b le Q A

O u tp u t E n a b le Q A

The student's software must output the shift registers "address" (0 7) to the 74HC138 to select which register is to be written
to.
Research 2 Solution in Assembly
Metrowerks HC12-Assembler
(c) COPYRIGHT METROWERKS 1987-2003
; Testing the SPI using the Freescale Project Board
; export symbols
XDEF Entry, main
; we use export 'Entry' as symbol. This allows us to
; reference 'Entry' either in the linker .prm file
; or from C/C++ later on
; symbol defined by the linker for the end of the stack
XREF __SEG_END_SSTACK, delay_X_ms
; variable/data section
MY_EXTENDED_RAM: SECTION
; Insert here your data definition.
BIT7:
SET
%10000000
BIT6:
SET
%01000000
BIT5:
SET
%00100000
BIT4:
SET
%00010000
BIT3:
SET
%00001000
BIT2:
SET
%00000100
BIT1:
SET
%00000010
BIT0:
SET
%00000001
ALLBITS:SET
%11111111

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

14

BASE:
SET
0
;********************************
; Register definitions
;********************************
; Port M registers
; Use Port M because they are connnected to
; the 74HC595 on the project board
PTM:
SET
BASE+$0250
DDRM:
SET
BASE+$0252
MISO:
SET
BIT2
; Port M2
SS_L:
SET
BIT3
; Port M3
MOSI:
SET
BIT4
; Port M4
SCK:
SET
BIT5
; Port M5

; code section
MyCode:
SECTION
main:
Entry:
LDS #__SEG_END_SSTACK
bset DDRM,SS_L|MOSI|SCK
bclr PTM,MOSI|SCK
bset PTM,SS_L
clra
main_loop:
jsr
send_spi
nop
inca
bra main_loop

; initialize the stack pointer


; Set Port M bits 3, 4, and 5 for output
; Initialize intial values for MOSI, SCK and SS_L
; Initialize test data value
; Write next data value

; To use the debugger for testing


; Change to the next output value

;********************************
; send_spi subroutine
; Inputs:
;
A = data to send
; Outputs:
;
B = data received
; Registers Modified: B, CCR
;********************************
send_spi:
pshx
psha
bclr
ldx

PTM,SS_L
#8
; To send/rece

; Assert SS_L
; Use X reg as a counter

do_start:
;
;
;
;

Get the bit on MISO


You have to do this before
shifting the first bit in.
IF MISO = 1

brclr PTM,MISO,rec_0

sec

Freescale Semiconductor

; THEN set the carry bit to rotate in B

LABS12DT256INTRO31, Rev 0

15

bra

endif_2

rec_0:

; ELSE clear the carry


clc

endif_2:

;
;
;
;

rolb

rola
bcc
bset
bra

send_0
PTM,MOSI
endif_1

bclr

PTM,MOSI

send_0:

ENDIF MISO = 1
Rotate the bit into B
Now output the current bit
Rotate bits in A into the car

; IF Carry = 1
; THEN send a 1
; ELSE send a 0

endif_1:
; ENDIF Carry = 1
; Toggle SCK (rising edge for 74HC595
bset
bclr
dex
bne
bset
pula
pulx
rts

PTM,SCK
PTM,SCK
do_start
PTM,SS_L

; Done now, Deassert SS_L

Research 2 Solution in C
/* C bit bang program to simulate the operation of the SPI */
/***********************************************************/
/* Use Port M register bits */
#define p_PTM (unsigned char *) 0x0250
#define p_DDRM (unsigned char *) 0x0252
#define MISO 0x04 /* Port M bit 2 */
#define SS_L 0x08 /* Port M bit 3 */
#define MOSI 0x10 /* Port M bit 4 */
#define SCK 0x20
/* Port M bit 5 */
#define BIT0 0x01 /* Bit 0 in a char */
#define BIT7 0x80 /* Bit 7 in a char */
unsigned char spi_send( unsigned char );
/***********************************************************/
void main(void) {
unsigned char spi_tx_data = 0;
volatile unsigned char spi_rx_data;
/* Initialize I/O
* Set Port M bits 3, 4, and 5 for ouput */
*p_DDRM |= SS_L|MOSI|SCK;
/* Set initial values for MOSI, SCK and SS_L */
*p_PTM |= SS_L;
*p_PTM &= ~(MOSI|SCK);
for(;;) {
spi_rx_data = spi_send( spi_tx_data );
++spi_tx_data;
} /* wait forever */

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

16

}
/***********************************************************
* spi_send subroutine
* unsigned char = spi_send (unsigned char );
**********************************************************/
unsigned char spi_send( unsigned char data_to_send ){
unsigned char count;
unsigned char rx_data;
/* Assert SS_L */
*p_PTM &= ~SS_L;
for (count = 0; count < 8 ; ++count){
/* Get the bit on MISO and shift into rx_data */
if ((*p_PTM & MISO) == MISO) { /* Have found a 1 */
rx_data |= BIT0;
}
else { /* Have found a 0 */
rx_data &= ~BIT0;
}
/* Shift the bits in rx_data left */
if (count < 7) rx_data = 2*rx_data;
/* Send the data most sig bit first */
if ((data_to_send & BIT7) == BIT7){
*p_PTM |= MOSI; /* Have found a 1 */
}
else {
*p_PTM &= ~MOSI; /* Have found a 0 */
}
/* Shift the send data left */
data_to_send = 2 * data_to_send;
/* Toggle the SCK */
*p_PTM |= SCK;
*p_PTM &= ~SCK;
}
/* Deassert SS_L */
*p_PTM |= SS_L;
return( rx_data );
}

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

17

Revision History
Revision

Comments

Author

Initial Release

Fred Cady

Updated for use with PBMCUSLK


and CSM12DT256B MCU Module

Dmitri Yudanov, Ken Hsu

(2/8/2008)

Freescale Semiconductor

LABS12DT256INTRO31, Rev 0

RIT

18

How to Reach Us:


Home Page:
www.freescale.com
Web Support:
http://www.freescale.com/support
USA/Europe or Locations Not Listed:
Freescale Semiconductor, Inc.
Technical Information Center, EL516
2100 East Elliot Road
Tempe, Arizona 85284
+1-800-521-6274 or +1-480-768-2130
www.freescale.com/support
Europe, Middle East, and Africa:
Freescale Halbleiter Deutschland GmbH
Technical Information Center
Schatzbogen 7
81829 Muenchen, Germany
+44 1296 380 456 (English)
+46 8 52200080 (English)
+49 89 92103 559 (German)
+33 1 69 35 48 48 (French)
www.freescale.com/support

Information in this document is provided solely to enable system and software implementers
to use Freescale Semiconductor products. There are no express or implied copyright
license granted hereunder to design or fabricate any integrated circuits or integrated circuits
based on the information in this document.
Freescale Semiconductor reserves the right to make changes without further notice to any
products herein. Freescale Semiconductor makes no warranty, representation or guarantee
regarding the suitability of its products for any particular purpose, nor does Freescale
Semiconductor assume any liability arising out of the application or use of any product or
circuit, and specifically disclaims any and all liability, including without limitation
consequential or incidental damages. Typical parameters which may be provided in
Freescale Semiconductor data sheets and/or specifications can and do vary in different
applications and actual performance may vary over time. All operating parameters, including
Typicals must be validated for each customer application by customers technical experts.
Freescale Semiconductor does not convey any license under its patent rights nor the rights
of others. Freescale Semiconductor products are not designed, intended, or authorized for
use as components in systems intended for surgical implant into the body, or other
applications intended to support or sustain life, or for any other application in which the
failure of the Freescale Semiconductor product could create a situation where personal
injury or death may occur. Should Buyer purchase or use Freescale Semiconductor
products for any such unintended or unauthorized application, Buyer shall indemnify and
hold Freescale Semiconductor and its officers, employees, subsidiaries, affiliates, and
distributors harmless against all claims, costs, damages, and expenses, and reasonable
attorney fees arising out of, directly or indirectly, any claim of personal injury or death
associated with such unintended or unauthorized use, even if such claim alleges that
Freescale Semiconductor was negligent regarding the design or manufacture of the part.

Japan:
Freescale Semiconductor Japan Ltd.
Headquarters
ARCO Tower 15F
1-8-1, Shimo-Meguro, Meguro-ku,
Tokyo 153-0064
Japan
0120 191014 or +81 3 5437 9125
support.japan@freescale.com
Asia/Pacific:
Freescale Semiconductor Hong Kong Ltd.
Technical Information Center
2 Dai King Street
Tai Po Industrial Estate
Tai Po, N.T., Hong Kong
+800 2666 8080
support.asia@freescale.com
For Literature Requests Only:

Freescale and the Freescale logo are trademarks of Freescale Semiconductor, Inc. All other
product or service names are the property of their respective owners. ARM is the registered
trademark of ARM Limited. ARM9, ARM11, and ARML210 are the trademarks of ARM Limited.
Java and all other Java-based marks are trademarks or registered trademarks of Sun Microsystems,
Inc. in the U.S. and other countries. The PowerPC name is a trademark of IBM Corp. and used
under license.
Freescale Semiconductor, Inc. 2006.
Document Number: LABS12DT256INTRO31 /REV 0

Freescale Semiconductor Literature


Distribution Center
P.O. Box 5405
Denver, Colorado 80217
1-800-441-2447 or 303-675-2140
Fax: 303-675-2150

LDCForFreescaleSemiconductor@hibbertgroup.com

Freescale and the Freescale logo are trademarks of Freescale Semiconductor, Inc. All other
product or service names are the property of their respective owners. ARM is the registered
trademark of ARM Limited. ARM9, ARM11, and ARML210 are the trademarks of ARM Limited.
Java and all other Java-based marks are trademarks or registered trademarks of Sun Microsystems,
Inc. in the U.S. and other countries. The PowerPC name is a trademark of IBM Corp. and used
under license.
Freescale Semiconductor, Inc. 2006.
Document Number: LABS12DT256INTRO31 /REV 0