- STM32F103C8中的SPI
- Arduino中的SPI引脚
- 所需组件
- STM32 SPI教程的电路图和连接
- STM32 SPI编程
- Master STM32 SPI编程说明
- 从Arduino SPI编程说明
在之前的教程中,我们了解了两个Arduino板之间的SPI和I2C通信。在本教程中,我们将用STM32F103C8的Blue Pill板替换一块Arduino板,并将使用SPI总线与Arduino板通信。在此STM32 SPI示例中,我们将使用Arduino UNO作为从设备,并使用STM32F103C8作为主机,并将两个16X2 LCD显示屏分别连接在一起。两个电位计还分别与STM32(PA0)和Arduino(A0)连接,通过改变电位计来确定从主机到从机以及从机到主机的发送值(0到255)。
STM32F103C8中的SPI
在Arduino和STM32F103C8 Blue Pill板上比较SPI总线,STM32中有2条SPI总线,而Arduino Uno有一条SPI总线。Arduino Uno中具有ATMEGA328微控制器,而STM32F103C8具有ARM Cortex-M3,这使其比Arudino开发板更快。
要了解有关SPI通信的更多信息,请参阅我们以前的文章
- 如何在Arduino中使用SPI:两个Arduino板之间的通信
- 与PIC单片机PIC16F877A的SPI通信
- 通过位敲击进行SPI通信
- 使用SPI模块的Raspberry Pi热水箱检漏仪
- 使用DS3231模块的ESP32实时时钟
STM32 SPI引脚STM32F103C8
SPI线1 | STM32F103C8的引脚 |
MOSI1 | PA7或PB5 |
MISO1 | PA6或PB4 |
SCK1 | PA5或PB3 |
SS1 | PA4或PA15 |
SPI线2 | |
MOSI2 | PB15 |
MISO2 | PB14 |
SCK2 | PB13 |
SS2 | PB12 |
Arduino中的SPI引脚
SPI线 |
固定在Arduino中 |
摩西 |
11或ICSP-4 |
味噌 |
12或ICSP-1 |
SCK |
13或ICSP-3 |
SS |
10 |
所需组件
- STM32F103C8
- Arduino的
- LCD 16x2-2
- 10k电位器– 4
- 面包板
- 连接线
STM32 SPI教程的电路图和连接
下表显示了用于与Arduino进行STM32 SPI通信的连接引脚。
SPI引脚 |
STM32F103C8 |
Arduino的 |
摩西 |
PA7 |
11 |
味噌 |
PA6 |
12 |
SCK |
PA5 |
13 |
SS1 |
PA4 |
10 |
下表显示了分别与STM32F103C8和Arduino连接的两个LCD(16x2)的引脚。
LCD针 |
STM32F103C8 |
Arduino的 |
VSS |
地线 |
地线 |
VDD |
+5伏 |
+5伏 |
V0 |
至电位计中心PIN以获得LCD对比度 |
至电位计中心PIN以获得LCD对比度 |
RS |
PB0 |
2 |
读写器 |
地线 |
地线 |
Ë |
PB1 |
3 |
D4 |
PB10 |
4 |
D5 |
PB11 |
5 |
D6 |
PC13 |
6 |
D7 |
PC14 |
7 |
一种 |
+5伏 |
+5伏 |
ķ |
地线 |
地线 |
重要:
- 不要忘记将Arduino GND和STM32F103C8 GND连接在一起。
STM32 SPI编程
编程类似于Arduino代码。相同
在此STM32 SPI示例中,我们将使用Arduino UNO作为从设备,并使用STM32F103C8作为主机,并将两个16X2 LCD显示屏分别连接在一起。两个电位计还分别与STM32(PA0)和Arduino(A0)连接,通过改变电位计来确定从主机到从机以及从机到主机的发送值(0到255)。
旋转电位器可在STM32F10C8引脚PA0(0至3.3V)处获取模拟输入。然后,此输入值将转换为模拟到数字值(0到4096),并且由于我们一次只能通过SPI通信仅发送8位(字节)数据,因此该数字值被进一步映射到(0到255)。
类似地,在从机端,我们使用电位计在Arduino引脚A0上从(0至5V)获取模拟输入值。再次将该输入值转换为模拟到数字值(0到1023),然后将该数字值进一步映射到(0到255)
本教程有两个程序,一个用于主STM32,另一个用于从Arduino。 双方的完整计划均在该项目的最后给出了 演示视频。
Master STM32 SPI编程说明
1.首先,我们需要 包括 使用SPI通信功能的SPI库和使用LCD功能的LCD库。同时为16x2 LCD定义LCD引脚。在此处了解有关将LCD与STM32接口的更多信息。
#包括
2.在无效的setup()中
- 以9600波特率启动串行通信。
Serial.begin(9600);
- 接下来开始SPI通信
SPI.begin();
- 然后设置时钟分频器进行SPI通信。我已经设置了分频器16。
SPI.setClockDivider(SPI_CLOCK_DIV16);
- 接下来,将SS引脚设置为高电平,因为我们没有开始向从属arduino进行任何传输。
digitalWrite(SS,HIGH);
3.在void loop()中
- 在将任何值发送到从站之前,我们需要将从站选择值设为LOW,以开始从主站传输到从站。
digitalWrite(SS,LOW);
- 接下来,从连接到引脚PA0的主STM32F10C8 POT中读取模拟值。
内部电位器= AnalogRead(PA0);
然后以一个字节(0到255)的形式转换此值。
字节MasterSend = map(pot,0,4096,0,255);
- 这是重要的一步,在以下语句中,我们将存储在 Mastersend 变量中的转换后的POT值发送到从Arduino,还从从Arduino接收值并将其存储在 mastereceive 变量中。
Mastereceive = SPI.transfer(Mastersend);
- 接下来,以500微秒的延迟显示从从arduino接收到的那些值,然后连续接收并显示这些值。
Serial.println(“将Arduino从奴隶为STM32”); Serial.println(MasterReceive lcd.setCursor(0,0); lcd.print(“ Master:STM32”); lcd.setCursor(0,1); lcd.print(“ SalveVal:”); lcd.print(MasterReceive delay (500); digitalWrite(SS,HIGH);
注意: 我们使用serial.println()在Arduino IDE的Serial Motor中查看结果。
从Arduino SPI编程说明
1.与主机一样,首先我们需要 包括 使用I2C通信功能的SPI库和使用LCD功能的LCD库。同时为16x2 LCD定义LCD引脚。
#包括
2.在无效的setup()中
- 我们以9600波特率开始串行通信。
Serial.begin(9600);
- 下面的语句将MISO设置为OUTPUT(必须将数据发送到Master IN),因此数据通过Slave Arduino的MISO发送。
pinMode(MISO,OUTPUT);
- 现在通过使用SPI控制寄存器以从机模式打开SPI
SPCR-= _BV(SPE);
- 然后打开中断以进行SPI通信。如果从主机接收到数据,则调用中断服务程序,并从SPDR(SPI数据寄存器)获取接收值。
SPI.attachInterrupt();
- 来自master的值取自SPDR,并存储在 Slavereceived 变量中。这发生在以下中断例程功能中。
ISR(SPI_STC_vect){从机接收= SPDR;收到=真;}
3.无效循环中的下一个()
- 从连接到引脚A0的从Arduino POT读取模拟值。
积分罐= AnalogRead(A0);
- 以1字节为单位将值转换为0到255。
Slavesend = map(pot,0,1023,0,255);
- 接下来的重要步骤是将转换后的值发送到Master STM32F10C8,因此将其值放置在SPDR寄存器中。SPDR寄存器用于发送和接收值。
SPDR =从机发送;
- 然后以500微秒的延迟在LCD上显示来自Master STM32F103C8的接收值( SlaveReceive ),然后连续接收并显示这些值。
lcd.setCursor(0,0); lcd.print(“奴隶:Arduino”); lcd.setCursor(0,1); lcd.print(“ MasterVal:”); Serial.println(“ Master STM32 to Slave Arduino”); Serial.println(SlaveReceived); lcd.print(SlaveReceived); 延迟(500);
通过 旋转电位器的一侧,您可以在另一侧的LCD上看到变化的值:
这就是 STM32中SPI通信的方式。现在,您可以将任何SPI传感器与STM32板连接。
主STM32和从Arduino的完整编码在下面给出了演示视频