本帖最后由 八月十五 于 2025-5-19 16:14 编辑
STM32F4与树莓派(Raspberry Pi)的通讯可以通过多种接口实现,常见的包括UART串口、SPI、I2C等。
1. UART串口通讯 特点: - 简单易用,适合调试和低速数据传输。 - 树莓派和STM32F4均支持UART接口。 实现步骤: 1. 硬件连接: - 树莓派的UART引脚(如GPIO14/TXD、GPIO15/RXD)与STM32F4的UART引脚(如PA9/TX、PA10/RX)交叉连接。 - 确保两端的GND连接在一起。 2. 树莓派配置: - 启用UART接口:
选择 `Interfacing Options > Serial > No`(禁用登录shell)和 `Yes`(启用硬件串口)。 - 重启树莓派。 3. STM32F4配置: - 使用STM32CubeMX配置UART外设(如USART1),设置波特率(如115200)、数据位、停止位等。 - 生成代码后,在用户代码中实现数据收发逻辑。 4. 代码示例: - 树莓派(Python): import serial
import time
# 配置串口
ser = serial.Serial(
port='/dev/ttyAMA0', # 树莓派的串口设备文件
baudrate=115200, # 波特率
bytesize=serial.EIGHTBITS, # 数据位
parity=serial.PARITY_NONE, # 无校验位
stopbits=serial.STOPBITS_ONE # 停止位
)
try:
while True:
# 发送数据
send_data = 'Hello, STM32!'
ser.write(send_data.encode())
print(f'Sent: {send_data}')
# 接收数据
if ser.in_waiting > 0:
receive_data = ser.readline().decode().strip()
print(f'Received: {receive_data}')
time.sleep(1)
except KeyboardInterrupt:
print('Communication stopped by user.')
finally:
ser.close()
- STM32F4: #include "main.h"
#include "usart.h"
#include "gpio.h"
uint8_t rx_data;
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
while (1)
{
// 接收数据
if (HAL_UART_Receive(&huart1, &rx_data, 1, 100) == HAL_OK)
{
// 回显接收到的数据
HAL_UART_Transmit(&huart1, &rx_data, 1, 100);
}
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
2. SPI通讯 特点: - 高速全双工通讯,适合需要较高带宽的应用。 - 树莓派作为SPI主机,STM32F4作为从机。 实现步骤: 1. 硬件连接: - 树莓派的SPI引脚(MOSI、MISO、SCLK、CE0)与STM32F4的SPI引脚(如PA7/MOSI、PA6/MISO、PA5/SCK、PA4/CS)连接。 2. 树莓派配置: - 启用SPI接口:
选择 `Interfacing Options > SPI > Yes`。 3. STM32F4配置: - 使用STM32CubeMX配置SPI外设(如SPI1),设置为从机模式。 4. 代码示例: - 树莓派(Python,使用spidev库): import spidev
spi = spidev.SpiDev()
spi.open(0, 0) # 打开SPI总线0,设备0
spi.max_speed_hz = 1000000 # 设置时钟频率
response = spi.xfer2([0x01, 0x00, 0x00, 0x00]) # 发送并接收数据
print(response)
- STM32F4: <pre style="overflow-wrap: initial; background: rgb(248, 248, 250); border-radius: 4px; font-size: 0.9em; overflow: auto; padding: calc(0.888889em); word-break: initial; color: rgb(25, 27, 31);"><code class="language-text" style="background-color: inherit; border-radius: 0px; font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; font-size: inherit;">
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);
}</code></pre>
3. I2C通讯 特点: - 多主多从架构,适合连接多个设备。 - 树莓派作为I2C主机,STM32F4作为从机。 实现步骤: 1. 硬件连接: - 树莓派的I2C引脚(SDA、SCL)与STM32F4的I2C引脚(如PB9/SDA、PB8/SCL)连接。 2. 树莓派配置: - 启用I2C接口: ```bash sudo raspi-config ``` 选择 `Interfacing Options > I2C > Yes`。 3. STM32F4配置: - 使用STM32CubeMX配置I2C外设(如I2C1),设置为从机模式,并设置唯一设备地址。 4. 代码示例: - 树莓派(Python,使用smbus库): import smbus
bus = smbus.SMBus(1) # 使用I2C总线1
bus.write_byte(0x48, 0x01) # 向地址0x48的设备写入数据
data = bus.read_byte(0x48) # 从地址0x48的设备读取数据
print(data)
- STM32F4: <pre style="overflow-wrap: initial; background: rgb(248, 248, 250); border-radius: 4px; font-size: 0.9em; overflow: auto; padding: calc(0.888889em); word-break: initial; color: rgb(25, 27, 31);"><code class="language-text" style="background-color: inherit; border-radius: 0px; font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace; font-size: inherit;">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);
}</code></pre>
4. 其他通讯方式 - USB通讯: - STM32F4可以通过USB-OTG接口模拟为虚拟串口(CDC)或HID设备,与树莓派通过USB线直接通讯。 - 以太网/Wi-Fi: - 树莓派和STM32F4均可通过以太网或Wi-Fi模块(如ESP8266)实现TCP/IP通讯,适合需要长距离或复杂网络协议的场景。
选择建议 简单调试:使用UART串口。 高速数据传输:使用SPI。 多设备连接:使用I2C。 复杂网络应用:使用以太网或Wi-Fi。
注意事项 1. 电平匹配: - 树莓派的GPIO为3.3V电平,STM32F4通常也为3.3V电平,无需电平转换。 - 如果使用5V设备,需使用电平转换模块。 2. 供电问题: - 确保树莓派和STM32F4的供电稳定,避免因电流不足导致通讯异常。 3. 调试工具: - 使用逻辑分析仪或示波器检查信号波形,确保通讯正常。 通过以上方法,可以灵活实现STM32F4与树莓派之间的通讯,满足不同应用场景的需求。
|