当前位置: 首页 > news >正文

探索嵌入式系统中 STM32 与树莓派的高效通信方式

摘要: 本文深入探讨了在嵌入式系统中实现 STM32 与树莓派高效通信的多种方式。首先对 STM32 和树莓派进行了简要介绍,然后分别阐述了常见的通信接口如串口、SPI、I2C 等在两者之间的应用。通过详细的代码示例和硬件连接说明,展示了如何进行有效的数据传输和交互。同时,对不同通信方式的性能和适用场景进行了分析和比较,为开发者在实际项目中选择合适的通信方案提供了参考。

一、引言

随着嵌入式技术的不断发展,在一个系统中常常需要多个控制器协同工作以实现更复杂的功能。STM32 作为一款高性能、低功耗的微控制器,广泛应用于各种嵌入式终端设备;树莓派则以其强大的计算能力和丰富的接口资源,在嵌入式服务器和智能控制中心等领域发挥着重要作用。实现 STM32 与树莓派之间的高效通信,对于构建功能强大、性能优越的嵌入式系统具有重要意义。

二、STM32 与树莓派简介

(一)STM32
STM32 系列微控制器是意法半导体(STMicroelectronics)基于 ARM Cortex-M 内核推出的产品。它具有丰富的外设资源、较高的运行速度和较低的功耗,适用于工业控制、消费电子、医疗设备等众多领域。

(二)树莓派
树莓派是一款基于 Linux 操作系统的单板计算机,具有强大的处理能力、丰富的接口和开源社区支持。它常用于物联网、智能家居、教育等领域,作为控制中心或数据处理节点。

三、通信接口选择

(一)串口通信
串口通信是一种简单、常用的异步通信方式,只需要两根数据线(TX 和 RX)即可实现数据传输。但串口通信速度相对较慢,适用于数据量较小、对实时性要求不高的场景。

(二)SPI 通信
SPI(Serial Peripheral Interface)是一种同步串行通信接口,具有高速、全双工的特点。需要四根数据线(SCK、MOSI、MISO、CS),适用于高速数据传输,如传感器数据采集、显示驱动等。

(三)I2C 通信
I2C(Inter-Integrated Circuit)是一种两线式串行总线,只需 SDA 和 SCL 两根线即可连接多个设备。但 I2C 通信速度相对较低,适用于连接多个低速设备,如 EEPROM、温度传感器等。

四、串口通信实现

(一)硬件连接
将 STM32 的串口引脚(如 USART1 的 PA9 和 PA10)分别连接到树莓派的串口引脚(如 GPIO14 和 GPIO15)。

(二)STM32 串口配置代码

#include "stm32f10x.h"void USART1_Init(uint32_t baudrate)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);USART_InitStructure.USART_BaudRate = baudrate;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);
}void USART1_SendChar(char c)
{while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);USART_SendData(USART1, (uint8_t)c);
}void USART1_SendString(char *str)
{while (*str){USART1_SendChar(*str++);}
}

(三)树莓派串口配置(使用 Python)

import serialser = serial.Serial('/dev/ttyAMA0', 9600)  # 波特率 9600def send_data(data):ser.write(data.encode())def receive_data():if ser.in_waiting:return ser.readline().decode()else:return None

五、SPI 通信实现

(一)硬件连接
STM32 的 SPI 引脚(如 SPI1 的 SCK、MISO、MOSI、NSS)分别连接到树莓派对应的 SPI 引脚。

(二)STM32 SPI 配置代码

#include "stm32f10x.h"void SPI1_Init()
{GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef SPI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);
}void SPI1_SendData(uint8_t data)
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, data);
}uint8_t SPI1_ReceiveData()
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);return SPI_I2S_ReceiveData(SPI1);
}

(三)树莓派 SPI 配置(使用 Python)

import spidevspi = spidev.SpiDev()
spi.open(0, 0)  # 打开 SPI 设备def spi_send_data(data):spi.xfer2(data)def spi_receive_data():return spi.xfer2([0x00])[0]

六、I2C 通信实现

(一)硬件连接
将 STM32 的 I2C 引脚(如 I2C1 的 SCL 和 SDA)连接到树莓派对应的 I2C 引脚。

(二)STM32 I2C 配置代码

#include "stm32f10x.h"void I2C1_Init()
{GPIO_InitTypeDef GPIO_InitStructure;I2C_InitTypeDef I2C_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x00;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 100000;I2C_Init(I2C1, &I2C_InitStructure);I2C_Cmd(I2C1, ENABLE);
}void I2C1_WriteData(uint8_t slave_address, uint8_t *data, uint16_t size)
{while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, slave_address, I2C_Direction_Transmitter);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));while (size--){I2C_SendData(I2C1, *data++);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));}I2C_GenerateSTOP(I2C1, ENABLE);
}void I2C1_ReadData(uint8_t slave_address, uint8_t *data, uint16_t size)
{while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));I2C_Send7bitAddress(I2C1, slave_address, I2C_Direction_Receiver);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));while (size){if (size == 1){I2C_AcknowledgeConfig(I2C1, DISABLE);I2C_GenerateSTOP(I2C1, ENABLE);}while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));*data++ = I2C_ReceiveData(I2C1);size--;}I2C_AcknowledgeConfig(I2C1, ENABLE);
}

(三)树莓派 I2C 配置(使用 Python)

import smbusbus = smbus.SMBus(1)  # 选择 I2C 总线 1def i2c_write_data(slave_address, data):bus.write_byte_data(slave_address, 0, data)def i2c_read_data(slave_address):return bus.read_byte_data(slave_address, 0)

七、通信性能比较与应用场景分析

(一)串口通信
性能:速度较慢,一般在几十 kbps 到几 Mbps 之间。
应用场景:适用于简单的数据传输,如调试信息、少量控制指令等。

(二)SPI 通信
性能:速度较高,可达几十 Mbps。
应用场景:高速数据传输,如图像数据、音频数据等。

(三)I2C 通信
性能:速度相对较低,一般在几百 kbps 以下。
应用场景:连接多个低速设备,如传感器、EEPROM 等。

八、结论

通过对 STM32 与树莓派之间串口、SPI 和 I2C 通信方式的详细介绍和实现,我们可以根据具体的项目需求选择合适的通信接口。在实际应用中,还需要考虑通信速度、数据量、实时性要求以及硬件连接的复杂性等因素,以实现高效、稳定的嵌入式系统通信。

希望本文能够为您在嵌入式系统开发中实现 STM32 与树莓派的通信提供有益的参考和帮助。

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对error视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料


http://www.mrgr.cn/news/49665.html

相关文章:

  • 多线程(三):线程等待获取线程引用线程休眠线程状态
  • Python速成笔记——知识(GUI自动化处理屏幕和按键输出)
  • SQLI LABS | SQLI LABS 靶场初识
  • tkinter库的应用小示例:文本编辑器
  • linux命令之fold
  • Windows 安装Redis(图文详解)
  • python【函数】
  • 如何使用Pandas库处理大型数据集?
  • Qt获取磁盘信息+表格显示
  • 深入探索Spring Cloud Gateway:微服务网关的最佳实践
  • 计算机是如何输入存储输出汉字、图片、音频、视频的
  • Golang | Leetcode Golang题解之第477题汉明距离总和
  • Python | Leetcode Python题解之第477题汉明距离总和
  • 【软件考试】一文学会原码,反码与补码
  • C语言 | Leetcode C语言题解之第477题汉明距离总和
  • Python列表专题:list与in
  • C++ | Leetcode C++题解之第477题汉明距离总和
  • 第十届MathorCup高校数学建模挑战赛-D题:基于统计回归模型的新零售企业精准需求预测研究(续)(附MATLAB代码实现)
  • AI智能助理在企业内部的8大应用场景
  • HPMicro:PWM双更新