STM32与树莓派串口通信实现(简易教程,无需安装micro-ROS版)
2025-10-10 来源:cnblogs
零、预设:
本次实验是为了给ROS2模块小车的通信打基础,我们选择stm32f407和树莓派4B进行电机控制和数据处理,二者之间需要进行串口通信,找到一个比较方便的方法(无需安装micro-ROS)
一、基本思路:
和普通的串口通信其实都差不多,只是stm32发送的数据要用树莓派的ros系统上来接收,我们这次只是为了验证能否正常通信,于是树莓派的ros系统上我们就用cutecom串口收发助手来进行接收
二、具体操作:
1、接线:
我们使用TTL转串口来进行,注意stm32引出的串口RX、TX要和TTL转串口的TX、RX交错连接,引脚电平3v3,别忘了GND。
2、stm32端的代码编写:
我们使用串口1来进行收发数据
(1)串口1初始化(一般我们需要初始化串口的TX RX引脚、串口的波特率、数据的格式)
void uart1_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //Enable the gpio clock //使能GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //Enable the Usart clock //使能USART时钟
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10 ,GPIO_AF_USART1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10; //USART_Mode_Rx | USART_Mode_Tx
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF; //输出模式
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //高速50MHZ
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化
//UsartNVIC configuration //UsartNVIC配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
//Preempt priority //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
//Subpriority //子优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//Enable the IRQ channel //IRQ通道使能
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//Initialize the VIC register with the specified parameters
//根据指定的参数初始化VIC寄存器
NVIC_Init(&NVIC_InitStructure);
//USART Initialization Settings 初始化设置
USART_InitStructure.USART_BaudRate = bound; //Port rate //串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //The word length is 8 bit data format //字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //A stop bit //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //Prosaic parity bits //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //No hardware data flow control //无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Sending and receiving mode //收发模式
USART_Init(USART1, &USART_InitStructure); //Initialize serial port 1 //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //Open the serial port to accept interrupts //开启串口接受中断
USART_Cmd(USART1, ENABLE); //Enable serial port 1 //使能串口1
}
通过上面的初始化,我们将PA9、PA10分别设为我们的RX、TX引脚,并配置了下面的数据格式,格式的参数在树莓派接收数据时会使用到 。
波特率:通过函数参数bound动态设置波特率。
数据位长度:设置为8位(USART_WordLength_8b)。
停止位:设置为1个停止位(USART_StopBits_1)。
校验位:无校验位(USART_Parity_No)
(2)串口1接收中断
在这里我们开启了串口接收的中断回调函数,如果你原来的 usartx.c 文件中就已经有同名的回调函数了,可以在原回调函数里头写或者把原回调函数给注释掉。
在这里我们使用 data_smp来接收数据,flag_smp来做为状态机的标志位,状态机说得简单一点就是我们在中断函数中判断接收到了信息,通过对标志位flag_smp的标志后,再到主函数里头来收发数据(这里是选择了直接在串口中断回调函数中进行接收),因为我们要尽量少在中断函数中进行大量的函数使用。
//别忘了在 usartx.c 的最前端定义两个用于串口收发的变量
uint8_t data_smp = 0;
uint8_t flag_smp = 0; //标志位
int USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
data_smp = USART_ReceiveData(USART1);
flag_smp = 1;
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
return 0;
}
(3)串口1发送
我们为了测试方便,因此我们的串口发送就直接使用printf函数来进行,要查看你的printf函数定向输出到的是哪个串口,如果原来是输出到其他串口则需要调整fputc函数中的串口,如图所示,我们把串口全改为 USART1,那在使用printf函数返回接收到的数据时就会直接通过串口1来发送数据了。

在 main.c 中,我们需要使用刚刚写的初始化函数来进行初始化,这里波特率设为115200,并写上返回数据的逻辑。
//别忘了引用刚刚定义的两个变量
extern uint8_t data_smp;
extern uint8_t flag_smp;
int main(void)
{
//初始化串口1,用于发送数据给上位机
uart1_init(115200);
while(1)
{
if(flag_smp !=0)
{
flag_smp=0; //将标志位置为代表未接收的数值
printf('%drn',data_smp); //将收到的data_smp 数据返回
}
}
(4)将代码烧录进stm32f407中
3、树莓派4B端的代码编写:
我们使用cutecom来进行串口数据的接收
(1)下载cutecom
打开终端,输入
sudo apt update
sudo apt install cutecom
(2)配置cutecom
首先我们要确认我们和树莓派进行连接的端口是哪个?
使用
ls /dev/tty*
串口设备通常显示为 /dev/ttyUSB0 或 /dev/ttyS0 等
我们继续使用指令 打开cutecom
sudo cutecom
点击右上角的setting进入配置界面
1 配置好波特率(要和stm32代码中一致)
2 选择我们刚刚指令找到的端口
3 点击Open,即可在最下方查看到从stm32发送而来的数据
4 在此处输入数据回车来发送给stm32,由于我们的代码写了stm32的收到数据后返回的功能,因此可以看到刚刚发送的数据

最后我们就可以看到,A区是我们发送的信息,B区是我们接收到的stm32返回的数据。

三、升级的思路
由于我们这次代码只是为了验证stm32和树莓派串口通信的可行性,所以stm32发送数据用的只是prinf函数来进行,真正的收发数据就需要我们把想要发送的数据进行一定的“打包”
上一篇:STM32低功耗模式中RTC唤醒与PA0唤醒协同工作的实用指南
下一篇:STM32 HAL开发环境搭建指南:Keil MDK-ARM、STM32F1xx DFP与ST-Link工具链配置详解,结合STM32CubeMX使
- 东日热敏标签打印机拆解与内部结构分析
- 意法半导体携手华虹实现STM32 MCU本土量产交付!
- 嵌入式变电站烟雾预警系统的设计与实现
- 意法半导体中国本地造STM32微控制器启动规模量产
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 基于机智云与STM32的智能拐杖安全监测系统在养老物联网中的应用
- 内置全栈安全,一站式满足CRA法案与IEC 62443标准——米尔STM32MP257核心板
- 如何用 STM32 FLASH 实现等效 100 万次擦写的 EEPROM 功能?
- 实战解析:通过一个小项目掌握STM32所有外设




