Lab2 SPI
Lab2 SPI
LABORATORY REPORT
DEVICE NETWORKS
0
Table of Contents
1. Project requirements: ..................................................................................................... 2
2. Hardware ....................................................................................................................... 2
2.1. Block diagram .......................................................................................................... 2
2.2. Wiring diagram ........................................................................................................ 3
2.3. Real diagram photo .................................................................................................. 3
3. Software ......................................................................................................................... 4
3.1. Microcontroller configuration ................................................................................... 4
3.2. Flowchart ............................................................................................................... 11
3.3. Code ...................................................................................................................... 11
4. Results ......................................................................................................................... 14
4.1. Testing plan............................................................................................................ 14
4.2. Results ................................................................................................................... 15
1
1. Project requirements:
This report details a laboratory exercise conducted as part of the Device Network course,
focusing on the practical implementation of the Two-way communication between one Master
(A) and two Slaves (B and C) using the SPI protocol
The Master (A) is equipped with two push buttons. Pressing each button will send a specific
message to the corresponding Slave:
Upon receiving the message, the respective Slave will respond back to the Master:
2. Hardware
2
2.2. Wiring diagram
3
3. Software
4
Enable SPI1 from “Connectivity” menu and choose “Full-Duplex Master”.
5
In STM32CubeMX, we choose these settings:
Basic parameters:
- Frame Format: Motorola. This is the standard SPI frame format. It supports Clock
Polarity (CPOL) and Clock Phase (CPHA), which are used to sync data correctly.
- Data Size: 8 Bits. Each SPI transfer will send/receive 8 bits (1 byte) of data. This is
typical for most SPI devices.
- First Bit: MSB First. Data is transmitted starting with the Most Significant Bit (bit 7
first, down to bit 0). Most SPI peripherals use this order.
Clock parameters:
- Prescaler (for Baud Rate): 64. This divides the main system clock to lower the SPI
clock. For example, if the system clock is 8 MHz:
> SPI Clock = 8 MHz / 64 = 125 KHz
- Baud Rate: 125.0 KBits/s. This is the effective data rate. Lower speeds are useful for
testing or communicating with slower peripherals (e.g., sensors, displays, or another
MCU).
- Clock Polarity (CPOL): Low. SPI clock idles at low level (0) when not transmitting.
- Clock Phase (CPHA): 1 Edge. Data is captured on the first edge of the clock signal
(rising edge if CPOL=Low).
6
In that case, we need to go to the “GPIO Settings” tab and
1. Set PA0 and PA1 to Input mode and pull their setting to pull-up.
2. Set PA3 and PA4 as Output mode with No pull (default is fine).
Slave B and C:
Slaves B and C are configured in SPI Slave mode, each with its own CS line connected to the
Master. They receive data via SPI1 and respond with predefined messages (“B hello A” or “C
hello A”). The slaves are programmed to echo back the received message or send their response
when selected by the Master.
7
Enable SPI1 from the “Connectivity” menu and choose “Full-Duplex Slave” and “Hardware
NSS Input Signal”. In this setting, the NSS pin acts as a hardware-controlled input:
● When NSS is low, the SPI slave is enabled and ready to communicate.
● When NSS is high, SPI communication is disabled.
8
We keep the “Preemption Priority” and “Sub Priorities” set to their default values 0.
The SPI1 interrupt handler will be triggered when an SPI event happens. The lowest number
means highest priority. This interrupt can preempt others with lower priority (higher number).
Sub Priority: 0 is used to resolve conflicts when two interrupts with the same preemption
priority occur. Lower sub-priority will be served first.
- PA4 (NSS): Used by the master to enable the slave. Set to Input mode. No internal pull-
up/down needed if externally controlled.
- PA5 (SCK): Clock line from master. Also Input mode. The slave listens for clock
pulses.
- PA6 (MISO): Slave sends data here. Set as Alternate Function, not input, because it's
an output pin from the slave's perspective.
- PA7 (MOSI): Master sends data. Set as Input mode, so the slave can receive it.
9
Basic parameters:
- Frame Format: Motorola. This is the standard SPI format with NSS, SCK,
MISO, and MOSI.
- First Bit: MSB First The most significant bit is transmitted first.
Basic parameters:
- Clock Polarity (CPOL): Low. Clock is low when idle (CPOL = 0).
- Clock Phase (CPHA): 1 Edge. Data is captured on the first clock edge (rising
edge, since CPOL = 0).
10
3.2. Flowchart
3.3. Code
Master A:
The code is added in between /* USER CODE BEGIN Includes */ and /* USER CODE END
Includes */. Insert this code in between:
11
#include <stdio.h>
#define sizeofBuff 12
uint8_t u8_SPI1_TxBuff[sizeofBuff] = "Master send";
uint8_t u8_SPI1_RxBuff[sizeofBuff];
uint8_t u8_SPI2_RxBuff[sizeofBuff];
uint8_t state = 1;
The code is added in between /* USER CODE BEGIN WHILE*/ and /* USER CODE END
WHILE*/. Insert this code in between:
#include <stdio.h>
#define sizeofBuff 12
uint8_t u8_SPI1_TxBuff[sizeofBuff] = "B hello A\n";
uint8_t u8_SPI1_RxBuff[sizeofBuff];
uint8_t Rx_slave[]={0};
uint8_t Count;
12
The code is added in between /* USER CODE BEGIN 0*/ and /* USER CODE END 0*/.
Insert this code in between:
The code is added in between /* USER CODE BEGIN 2*/ and /* USER CODE END 2*/.
Insert this code in between:
#include <stdio.h>
#define sizeofBuff 12
uint8_t u8_SPI1_TxBuff[sizeofBuff] = "C hello A\n";
uint8_t u8_SPI1_RxBuff[sizeofBuff];
uint8_t Rx_slave[]={0};
uint8_t Count;
The code is added in between /* USER CODE BEGIN 0*/ and /* USER CODE END 0*/.
Insert this code in between:
13
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hspi);
if(hspi->Instance == SPI1)
{
HAL_SPI_TransmitReceive_IT(&hspi1, u8_SPI1_TxBuff,
u8_SPI1_RxBuff, sizeofBuff);
}
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_SPI_RxCpltCallback should be implemented in the user file
*/
}
The code is added in between /* USER CODE BEGIN 2*/ and /* USER CODE END 2*/.
Insert this code in between:
4. Results
14
Error Handling Test
- Simulate unexpected or malformed messages (if possible).
- Verify that Slaves ignore unknown messages and do not respond incorrectly.
Simultaneous Press Test
- Press both buttons at the same time (if physically possible).
- Observe if the Master handles the collision or queueing of messages properly.
Response Timing Test
- Measure the time between sending the message and receiving the response.
- Confirm the communication is completed within an acceptable time frame (e.g., under
100ms).
4.2. Results
Master A:
Master A successfully sends “A hello B” to Slave B when button 1 (PA1) is pressed and “A
hello C” to Slave C when button 2 (PA0) is pressed. The Master receives and stores the
responses (“B hello A” or “C hello A”) in its receive buffer, verified via debugging or serial
output.
15
Figure: The debug screen of Master A after pushing button 2.
Slave B:
Slave B receives “A hello B” when its CS line is active and responds with “B hello A”. The
communication is stable, with no data corruption observed.
16
Figure: The debug screen of Slave B after pushing button 1. .
Slave C:
Slave C receives “A hello C” when its CS line is active and responds with “C hello A”. The
response is correctly received by the Master.
17
Figure: The debug screen of Slave C after pushing button 2.
18