0% found this document useful (0 votes)
3 views

lec_11_SPI

The document provides an overview of the Serial Peripheral Interface (SPI), a synchronous serial communication protocol used for short-distance communication between microcontrollers and peripheral devices. It details the SPI signals, data transmission process, clock polarity and phase, and the configuration of the XMEGA SPI module. Additionally, it includes examples of interfacing with a shift register and programming routines for data transmission and reception using SPI.

Uploaded by

alexspammail123
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

lec_11_SPI

The document provides an overview of the Serial Peripheral Interface (SPI), a synchronous serial communication protocol used for short-distance communication between microcontrollers and peripheral devices. It details the SPI signals, data transmission process, clock polarity and phase, and the configuration of the XMEGA SPI module. Additionally, it includes examples of interfacing with a shift register and programming routines for data transmission and reception using SPI.

Uploaded by

alexspammail123
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 54

Microcontroller I

Serial Peripheral Interface (SPI)

By
Dr. Han-Way Huang
Minnesota State University, Mankato

05/13/2025 1
Overview of Serial Peripheral Interface (SPI)
 A synchronous serial communication interface specification used for
short distance communication between a MCU and a peripheral chip.
 Developed by Motorola.
 Devices in an SPI system are divided into the master and slaves. Only
the master device can initiate transfer.
 Four SPI signals:
 SCLK: serial clock (output from Master)
 MOSI: master out slave in (master output)
 MISO: master in slave out (slave output)
 SS: slave select (often active low)

05/13/2025 2
Overview of Serial Peripheral Interface (SPI)—(continued)
 SPI utilize the upper 4 pins of PORTC, D, E, and F
 Pin 7: SCLK, Pin 6: MISO, Pin 5: MOSI, Pin 4: SS pin
 These SPI modules are named as SPIC, SPID, SPIE, & SPIF.

05/13/2025 3
Overview of SPI—(continued)

SCLK SCLK
SPI MOSI MOSI SPI
Master MISO MISO Slave
SS SS

Figure 9S01Single SPI master and single slave connection

05/13/2025 4
SPI Data Transmission
 SPI master configures the clock—the frequency must be
supported by the slave device.
 The master selects a slave device—by asserting the SS
signal (low?).
 The SPI master starts a data transfer by writing into the
data register.
 The master sends a bit on the MOSI pin and the slave reads it
in every SCLK cycle, while the slave sends a bit on the MISO
line and the master reads it.
 Data is usually shifted out most significant bit first. The master
05/13/2025 5
SPI Data Transmission—(continued)

Master Slave

SCLK
MOSI
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
MISO

Figure S9.2 SPI data transfer operation

05/13/2025 6
Clock Polarity and Phase
 The SPI master must specify the SCLK clock polarity when
idle and phase in data transfer.
 The clock polarity and phase are named as CPOL and
CPHA.
 The combinations of CPOL and CPHA are given in Figure S9.3.
 The SCLK is idle low when CPOL = 0. Otherwise, SCLK is idle
high.
 CPHA determines when data (on MOSI and MISO) is sampled.
 When CPHA = 0, data (on MOSI and MISO) is sampled on the

05/13/2025
leading edge. Otherwise, data is sampled on the trailing edge 7
CPOL=0
SCLK

CPOL=1

Cycle # 1 2 3 4 5 6 7 8

CPHA=0 MISO 1 2 3 4 5 6 7 8 z

MOSI 1 2 3 4 5 6 7 8 z

Cycle # 1 2 3 4 5 6 7 8

CPHA=1 MISO 1 2 3 4 5 6 7 8 z

MOSI 1 2 3 4 5 6 7 8 z

Figure S9.3 SPI clock polarity and phase combinations

05/13/2025 8
The combinations of CPOL and CPHA are often referred to as
SPI modes (0 to 3). The available modes are listed in Table S9.1.
Atmel AVR XMEGA SPI modes follows Table S9.1b.

Table S9.1a SPI Modes (PIC & ARM) Table S9.1b SPI Modes (others, AVR)
Mode CPOL CPHA Mode CPOL CPHA
0 0 1 0 0 0
1 0 0 1 0 1
2 1 1 2 1 0
3 1 0 3 1 1

05/13/2025 9
SPI Bus Connection Method
 Two methods: parallel and serial method
 Parallel method is used when the master has the need to
select each individual SPI slave to perform data transfer (shown
in Figure S9.4).
 Serial method is used when multiple SPI slaves of the same
type are used at the same time and must receive/transfer data
from/to the master simultaneously (shown in Figure S9.5)—also
called daisy-chained method.

05/13/2025 10
SPI Parallel Connection Method

05/13/2025 11
SPI Serial Connection Method

05/13/2025 12
The XMEGA SPI Module
 Four SPI modules associated with PORTC, PORTD, PORTE,
and PORTF.
 These four SPI modules are named as SPIC, SPID, SPIE,
and SPIF, respectively.
 The upper four pins (pin 7 to 4) of these four ports are used
as SCLK, MISO, MOSI, and SS signals.
 Four registers are provided to support the functioning of
each SPI module. These registers are CTRL, INTCTRL,
STATUS, and DATA.

CTRL
05/13/2025Register 13
05/13/2025 14
Table 12.1 Relationship between SCK and the peripheral clock frequency
CLK2X PRESCALE[1:0] SCK frequency
0 00 CLKPER/4 8 MHz
0 01 CLKPER/16 2 MHz
0 10 CLKPER/64 0.5 MHz
0 11 CLKPER/128 0.25 MHz
1 00 CLKPER/2 16 MHz
1 01 CLKPER/8 4 MHz
1 10 CLKPER/32 1 MHz
1 11 CLKPER/64
0.5 MHz

05/13/2025 15
INTCTRL Register
This register enables/disables the SPI interrupt and sets its
priority.
7 6 5 4 3 2 1 0
Reset value
-- -- -- -- -- -- INTLVL[1:0] = 0x00
R R R R R R R/W R/W
INTLVL[1:0]: SPI interrupt level
00 = SPI interrupt disabled
01 = SPI interrupt at low level
10 = SPI interrupt at medium level
11 = SPI interrupt at high level
Figure 12.7 XMEGA SPI interrupt control register (INTCTRL)

05/13/2025 16
Status
Register
7 6 5 4 3 2 1 0 Reset value
IF WRCOL -- -- -- -- -- -- = 0x00
R/W R/W R R R R R R
IF: SPI interrupt flag
When a serial transfer is complete and one byte is completely shifted in/out of the
DATA register, the IF bit is set. If SS is an input and is driven low when the SPI is in
Master mode, this will also set the IF bit. This flag will be cleared when the IF
interrupt service routine is entered. It can also be cleared by first reading STATUS
followed by accessing the DATA register.
WRCOL: Write collision flag
The WRCOL bit is set if the DATA register is written during a data transfer. The
WRCOL bit is cleared by first reading the STATUS register with WRCOL set, and then
accessing the DATA register.
Figure 12.8 XMEGA SPI status register (STATUS)

05/13/2025 17
Port Pins assigned to SPI Signals
 Px4: SS’ x = C, D, E, or F
 Px5: MOSI
 Px6: MISO
 Px7: SCK

05/13/2025 18
Example 10.1. Write a subroutine to configure the SPI module
associated with PORTD to operate with the following parameters
assuming that peripheral clock is 32 MHz:
 4-MHz shift rate
 Interrupt disabled
 Master mode
 SPI enabled
 SCK idle low and sampled data on the rising edge
 Data shift most significant bit first
Solution:
05/13/2025 19
initSPID:ldi r16, 0xB0 ; configure PORTD pins 7, 5, & 4 for output
sts PORTD_DIRSET, r16; (SCK:7, MISO:6, MOSI:5, SS:4)
ldi r16, 0x40 ; configure PORTD pin 6 (MISO) for input
sts PORTD_DIRCLR, r16 ; “
ldi r16, 0xF1 ; set baud rate to 4 MHz, master mode, idle
sts SPID_CTRL, r16 ; low, sample data on rising edge
clr r16
sts SPID_INTCTRL, r16 ; disable SPI interrupt
ret

05/13/2025 20
Example 10.2 Write a subroutine to send out a byte passed in r16 via the
SPI module associated with PORTD.
Solution:
putcSPID_xmaster:
sts SPID_DATA, r16 ; write into data register
waitTxx:lds r20, SPID_STATUS ; wait for the byte to be shifted out
sbrs r20, 7 ; “ (check IF bit)
rjmp waitTxx
lds r22, SPID_DATA ; clear the IF flag
ret

05/13/2025 21
Example 10.3 Write a subroutine to read a byte from the SPI module associated
with PORTD and return the byte in r22.
Solution:
getcSPID_Xmaster:
sts SPID_DATA, r16 ; trigger SCLK pulses to shift in data byte
waitRxx: lds r20, SPID_STATUS ; wait for data to shift in
sbrs r20, SPI_IF_bp ; “
rjmp waitRxx
lds r22, SPID_DATA ; return data in r22
ret

05/13/2025 22
Interfacing with Shift Register 74HC595

16
VCC
14 15
QB 1 16 VCC DS QA
1 QB
QC 2 15 QA 2 QC
QD 3 14 DS 3 QD
Shift Latch 4
4 13 register QE
QE OE 5 QF
QF 5 12 LC 11 6 QG
SC
7 QH
QG 6 11 SC
QH 7 10 Reset
Reset 10 9
GND 8 9 SQH SQH
12
LC
13 GND
OE

Figure 12.9 The 74HC595 block diagram and pin assignment

05/13/2025 23
Pin Function
DS: serial data input
SC: Shift clock. Shift using the rising edge.
LC: Latch clock. Transfer data from shift register to output
buffer using the
rising edge of LC.
OE: Output enable. Asserted low to allow buffer to drive
external pins.
If not asserted (high), the output pins are in high
impedance state.
SQH: Serial data output. The 8th stage output of the shift
05/13/2025 24
Using Two 74HC595 to Drive Up to 8 Seven-Segment
Displays
3.3 V
#7 #6 #0
470  a a
reset QG . . . a
OE QF b b . . . b
. . .
. . .
74HC595 #1
. 470  .
g . g . . . g
QA
DS
SC LC SQH common common common
3.3 V cathode cathode cathode

IMAX

IMAX
MOSI reset

IMAX = 20.85 mA
DS QH
SCK SC
Q. G
.
PD0 LC .
.
. .
OE
QA
XMEGA128A1
IMAX =(3.3 – 0.1– 1.8 ) ¸0.47 ´7 =20.85 mA
74HC595 #2

Figure 12.10 Two 74HC595s together drive eight seven-segment displays

05/13/2025 25
How to sent data to 74HC595?
 The bit at the DS input is shifted into QA during the
first clock cycle.
 The bit first shifted in will reach QH after 8 clock
cycles.
 First, send out the digit select
 Second, send the segment pattern

05/13/2025 26
Example 10.4 Write a program to display 12345678 on displays #7…#0 in the
circuit shown in Figure 12.10.
Solution:
Use time-multiplexing technique to display these eight digits:
.include <atxmega128a1def.inc>
.def lpCnt = r19
.cseg
.org 0x00
jmp start
.org 0xF6
start: ldi r16, low(RAMEND)
out CPU_SPL, r16
ldi r16, high(RAMEND)
out CPU_SPH, r16
call setCPUClkto32Mwith32MIntOsc
call initSPID

05/13/2025 27
forever: ldi ZL,low(seg7Tab << 1)
ldi ZH,high(seg7Tab << 1)
ldi lpCnt,8
loop: lpm r16,Z+
call putcSPID_Xmaster  send out digit select value
lpm r16,Z+
call putcSPID_Xmaster  send out digit pattern
ldi r16,0x01 ; transfer data to output latch
sts PORTD_OUTCLR, r16 ; by generating a rising edge on the
LC pin
sts PORTD_OUTSET, r16 ; "
ldi r16, 1
call delayby1ms ; time-multiplexing delay
dec lpCnt
brne loop
jmp forever

05/13/2025 28
;
-------------------------------------------------------------------------------------------------------------
-----------------------
; This function configure SPID to master mode, enable it, set baud rate to
; 4 MHz, SCK idle low, sample data on rising edge. Disable interrupt.
;
-------------------------------------------------------------------------------------------------------------
-----------------------
initSPID: ldi r16, 0xB1 ; configure PORTD pins 7,5,4
sts PORTD_DIR, r16 ; for output and pin PD6 for input
ldi r16, 0xF1 ; set baud rate to 4 MHz, master mode,
idle
sts SPID_CTRL, r16 ; low, sample data on rising edge
clr r16
sts SPID_INTCTRL, r16 ; disable SPI interrupt
ret
.include "sysClock_xmega.asm"
.include "delays_xmega.asm"
05/13/2025 .include "spiUtil_xmega.asm" 29
MCP4922 Digital-to-Analog Converter
 12-bit resolution, SPI interface with 4.5 ms conversion
time
 Maximal data shift rate = 20 MHz
 Two-channel outputs
 Power supply from 2.7 V to 5.5 V

05/13/2025 30
CS SDI SCK LDAC VDD

Interface Logic

Power-on
Reset

AVSS
Input Input
Register A Register B

VDD 1 14 VOUTA DACA DACB


Register Register
NC 2 13 VREFA

CS 3 12 AVSS String String

VREFB
VREFA
DACA DACB
buffer buffer
SCK 4 11 VREFB Gain Gain
Logic Logic
SDI 5 10 VOUTB

Output
logic
NC 6 9 SHDN

NC 7 8 LDAC
VOUTA SHDN VOUTB

(a) Pin assignment (b)Functional block diagram


Figure 12.11 The MCP4922 DAC pins and block diagram
05/13/2025 31
Data Format for
MCP4922
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
A/B BUF GA SHDN D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

A/B: DACA or DACB select


0 = write to DACA
1 = write to DACB
BUF: VREF input buffer control
0 = unbuffered
1 = buffered
GA: output gain select bit
0 = gain is 2 (VOUT = 2 * VREF * D / 4096)
1 = gain is 1 (VOUT = VREF * D / 4096)
SHDN: output power down control bit
0 = output buffer is disabled. Output is in high impedance
1 = output buffer is enabled
D11: D0: DAC data bits
Figure 12.12 Input data format for the MCP4922 DAC

Most significant bit (A/B)is shifted in first.

05/13/202 32
5
Example 10.5 Let VDD = VREFA (or VREFB) = 3.3 V & set gain to 1,
reference voltage is
unbuffered. Compute the value to generate 2.5 V output from V OUTA

and VOUTB, respectively.


Solution:
The value to generate 2.5 V from VOUTA = (2.5 x 4095) / 3.3 = 3103
= 0xC1F.
Add the top 4 bits  0011  The 16-bit value to generate 2.5 V from
VOUTA is 0x3C1F.
Add the top 4 bits  1011  The 16-bit value to generate 2.5 V from
V OUTB is 0xBC1F.
05/13/2025 33
Circuit Connection for MCP4922

XMEGA128A1 MCP4922
3.3V

MOSI(PD5) SDI VDD


SCK(PD7) VREFA
SCK
SHDN
SS(PD4) CS VREFB
VOUTA
LDAC
VOUTB
AVSS

Figure 12.13 Circuit connection between the AVR and MCP4922

05/13/2025 34
Example 10.5 Write a program to generate the waveform shown in Figure
12.14 from the VOUTA pin using the SPI module associated with PORTD.

3.3 V

time
Figure 12.14 Waveform to be generated
Solution:
 Divide one cycle of waveform into 61 points (there are 60 segments in one
cycle).
 Calculate the code value corresponding to the voltage of each point (or use
the equation (j × 4095)/60, j = 0~60). (two points separate 68.25)
 Place the computed values in a table, stay in an infinite loop, and convert
these values into voltage by sending these values to the MCP4922.
05/13/2025 35
.include <atxmega128A1def.inc>
.def tmp = r18
.def lpCnt = r24
.cseg
.org 0x00
jmp start
.org 0xF6
start: ldi tmp, low(RAMEND)
out CPU_SPL, tmp
ldi tmp, high(RAMEND)
out CPU_SPH, tmp
call setCPUClkto32Mwith32MIntOsc
rcall initSPID

05/13/2025 36
forever: ldi lpCnt, 61
ldi ZL, low(sawtooth << 1)
ldi ZH, high(sawtooth << 1)
loop: lpm r17, z+
lpm r16, z+
call sendMCP4922
dec lpCnt
brne loop
jmp forever
;
-----------------------------------------------------------------------------------------------------
----------------------
; This subroutine enables XMEGA SPID module, shift data at 4 MHz,
select
; master mode, shift data most significant bit first & disable SPI
interrupt.
;
-----------------------------------------------------------------------------------------------------
----------------------
initSPID:ldi r19, 0xD1
05/13/2025 37
sts SPID_CTRL, r19
;
--------------------------------------------------------------------------------------------------------
--------------------------
; This subroutine sends 16-bit value passed in r16:r17 to the MCP4922.
;
--------------------------------------------------------------------------------------------------------
--------------------------
.equ SS = 0x10 ; select pin 4
sendMCP4922:
ldi r20, SS
sts PORTD_OUTCLR, r20 ; pull SS pin low to enable SPI
transfer
call putcSPID_Xmaster ; send the upper byte of the 16-bit
value
mov r16, r17
call putcSPID_Xmaster ; send the lower byte of the 16-bit
value
sts PORTD_OUTSET, r20 ; pull SS high to start DAC
ret
05/13/2025 .include “sysClock_xmega.asm” 38
sawtoothTable:
.dw 0x3000, 0x3044, 0x3089, 0x30CD, 0x3111
.dw 0x3155, 0x319A, 0x31DE, 0x3222, 0x3266
.dw 0x32AB, 0x32EF, 0x3333, 0x3377, 0x33BC
.dw 0x3400, 0x3444, 0x3489, 0x34CD, 0x3511
.dw 0x3555, 0x359A, 0x35DE, 0x3622, 0x3666
.dw 0x36AB, 0x36EF, 0x3733, 0x3777, 0x37BC
.dw 0x3800, 0x3844, 0x3889, 0x38CD, 0x3911
.dw 0x3955, 0x399A, 0x39DE, 0x3A22, 0x3A66
.dw 0x3AAB, 0x3AEF, 0x3B33, 0x3B77, 0x3BBC
.dw 0x3C00, 0x3C44, 0x3C89, 0x3CCD, 0x3D11
.dw 0x3D55, 0x3D9A, 0x3DDE, 0x3E22, 0x3E66
.dw 0x3EAB, 0x3EAB, 0x3F33, 0x3F77, 0x3FBC
.dw 0x3FFF

68.25 x 2 = 136.5137 = 0x89


68.25 x 3 = 205 = 0xCD

05/13/2025 39
TC72 Digital Temperature Sensor
 10-bit resolution (8 bits for integer, 2 bits for
fraction)
 With SPI interface
 Made by Microchip
 Has four registers—addressed by read and write
address

05/13/2025 40
TC72
VDD Internal
diode
temperature
sensor
Manufacturer
ID register
NC 1 8 VDD 10-bit
sigma Delta
CE 2 7 NC A/D converter
TC72 CE
SCK 3 6 SDI Serial SCK
port SDO
GND 4 5 SDO interface
Temperature SDI
register

GND Control
register

Figure 12.15 TC72 pin assignment and functional block diagram

05/13/2025 41
TC72 Registers
Table 12.3 Register for TC72

Read Write Bit Bit Bit Bit Bit Bit Bit Bit Value on
Register
address address 7 6 5 4 3 2 1 0 POR/BOR

Control 0x00 0x80 0 0 0 OS1 0 0 0 SHDN2 0x05


LSB temperature 0x01 N/A T1 T0 0 0 0 0 0 0 0x00
MSB temperature 0x02 N/A T9 T8 T7 T6 T5 T4 T3 T2 0x00
Manufacturer ID 0x03 N/A 0 1 0 1 0 1 0 0 0x54
1. OS is One-Shot.
2. SHDN is Shutdown.

Table 12.4 TC72 control register temperature conversion mode selection


Operation mode One-shot bit Shutdown bit
Continuous temperature conversion 0 0
Shut down 0 1
Continuous temperature conversion 1 0
One shot 1 1

05/13/2025 42
General Operation of TC72
 Temperature conversion modes: one-shot or continuous
mode.
 In continuous mode, TC performs temperature conversion
every 150 ms.
 Temperature conversion is started after writing into the control
register.
 To access a TC72 register, send out its read or write address.
 TC72 has a decrementing address pointer. By sending the
highest register address, the user can read all four registers out
of the TC72.
05/13/2025 43
Table 12.5 TC72 Temperature output data
Binary
Hex Temperature
High Byte/Low Byte

0010 0001/0100 0000 2140 33.25oC


0100 1010/1000 0000 4A80 74.5oC
0001 1010/1100 0000 1AC0 26.75oC
0000 0001/1000 0000 0180 1.5oC
0000 0000/0000 0000 0000 0oC
1111 1111/1000 0000 FF80 -0.5oC
1111 0010/1100 0000 F2C0 -13.25oC 0000 1101 01  -13.25
1110 0111/0000 0000 E700 -25oC 0001 1001 00  -25oC
1100 1001/0100 0000 C900 -54.75oC 0011 0110 11  -54.75oC

05/13/2025 44
Circuit Connection

TC72 XMEGA128A1U
VDD VDD
0.1F CE PD1
SCK SCK/PD7
SDO MISO/PD6
SDI MOSI/PD5
GND

Figure 12.16 Circuit connection between the TC72 and the XMEGA

05/13/2025 45
Example 10.6 Write an assembly program to read the temperature from the
TC72 every 200 ms.
Solution:
.include <atxmega128A1Udef.inc>
.dseg
.org 0x2000
buf: .byte 10 ; reserve 10 byes to hold temperature reading
.cseg
.org 0x00
jmp start
.org 0xF6
start: ldi r16, low(RAMEND)
out CPU_SPL, r16
ldi r16, high(RAMEND)
out CPU_SPH, r16
call setCPUClkto32Mwith32MIntOsc
call initSPID

05/13/2025 46
forever: ldi r16, 0x20 ; initialize buffer to
sts buf, r16 ; ^^0.00\0
sts buf+1, r16 ; "
ldi r16, 0x30 ; “ (ASCII code of 0)
sts buf+2, r16 ; "
sts buf+4, r16 ; "
sts buf+5, r16 ; "
ldi r16, 0x2E ; store period character
sts buf+3, r16 ; "
clr r16 ; terminate the string with a NULL character
sts buf+6, r16 ; "
call st_Temp_Conversion ; start one-shot mode temperature
conversion
ldi r16,2 ; wait for temperature conversion to
call delayby100ms ; complete
call readTemp ; read back the temperature (in r22:r23)
movw r16,r22 ; transfer temperature reading to r16:r17
ldi ZL,low(buf) ; Z points to buf
ldi ZH,high(buf) ; “
call bin2BCD ; convert to BCD string
05/13/2025 jmp forever 47
;
-----------------------------------------------------------------------------------------------------------------
---------
; This subroutine enables XMEGA SPID module, shift data at 4 MHz, select
; master mode, shift data most significant bit first.
;
-----------------------------------------------------------------------------------------------------------------
---------
initSPID: ldi r16, 0xB2
sts PORTD_DIRSET, r16 ; configure PD7, PD5, PD4, & PD1 for output
ldi r16, 0x40 ; configure PD6 for input
sts PORTD_DIRCLR, r16
ldi r19, 0xF1
sts SPID_CTRL, r19
clr r19
sts SPID_INTCTRL, r19 ; disable SPID interrupt
ret

05/13/2025 48
;
---------------------------------------------------------------------------------------------------------
--------------------------------------
; This subroutine starts a temperature conversion.
;
---------------------------------------------------------------------------------------------------------
--------------------------------------
st_Temp_Conversion:
ldi r16, 0x02 ; drive PD1 (CE signal) high to
sts PORTD_OUTSET, r16 ; enable SPI transfer
ldi r16, 0x80 ; send out control register write
address
call putcSPID_Xmaster ; "
ldi r16, 0x11 ; select one shot conversion
call putcSPID_Xmaster ; "
ldi r16, 0x02
sts PORTD_OUTCLR, r16; start temperature conversion
ret

05/13/2025 49
;
-------------------------------------------------------------------------------------------------------------
-----------
; This subroutine reads back the temperature value.
;
-------------------------------------------------------------------------------------------------------------
-----------
readTemp:
ldi r16,0x02 ; drive PD1 (CE signal) high
sts PORTD_OUTSET, r16 ; to enable SPI transfer
ldi r16, 0x02 ; send out temperature MSB read
address
call putcSPID_Xmaster ; "
call getcSPID_Xmaster ; read back the temperature high byte
mov r23, r22 ; transfer high byte to r23
call getcSPID_Xmaster ; read back the temperature low byte (in
r22)
ldi r16, 0x02
05/13/2025 sts PORTD_OUTCLR, r16 ; terminate the TC72 access. 50
;
---------------------------------------------------------------------------------------------------------------
-----------------------
; This subroutine converts the binary temperature reading into BCD ASCII
string.
;
---------------------------------------------------------------------------------------------------------------
-----------------------
bin2BCD: andi r16,0xC0 ; mask out bit 5 ~ bit 0 of
fraction
sbrs r17, 7 ; skip if sign bit is 1
rjmp normal
com r16 ; find one's complement
com r17 ; “
ldi r19,0x40 ; add 1 to lsb in temperature reading
add r16, r19 ; "
clr r19 ; add carry to upper byte
adc r17,r19 ; "
ldi r19,'-' ; save the minus sign to buffer
05/13/2025 st Z+, r19 ; " 51
ldi r18,0x32 ; fraction part is .25
sts buf+4,r18 ; "
ldi r18,0x35 ; "
sts buf+5,r18 ; "
jmp intpart
chk80: cpi r16,0x80
brne isC0
ldi r16,0x35 ; fraction is .5
sts buf+4,r16
clr r16 ; store a NULL character
sts buf+5,r16 ; “
jmp intpart
isC0: ldi r16,0x37 ; fraction is .75
sts buf+4,r16
ldi r16,0x35
sts buf+5,r16

05/13/2025 52
intpart: mov r16,r17 ; move integer part to r16
clr r17 ; "
ldi r18,10 ; set divisor to 10
clr r19 ; "
call div16U ; perform the division
ldi r19,0x30 ; find the ASCII code of the remainder
add r22,r19 ; "
sts buf+2,r22 ; save the one's digit in buffer
cpi r24,0 ; is the quotient 0?
breq done ; if quotient = 0, then done
mov r16,r24 ; transfer quotient to r17:r16
ldi r18,10 ; set divisor to 10
clr r19 ; "
call div16U ; separate ten's digit
ldi r19,0x30 ; find the ASCII code of ten's digit
add r22,r19 ; "
sts buf+1,r22 ; save the ten's digit in buffer
cpi r24,0 ; is hundred’s digit 0?

05/13/2025 53
breq done
ldi r19,0x31 ; hundred's digit is 1
sts buf, r19 ; save it in buffer
done: ret
.include "div16U.asm"
.include "delays_xmega.asm"
.include "spiUtil_xmega.asm"
.include "sysClock_xmega.asm"

05/13/2025 54

You might also like