STM32与树莓派串口通信实现(简易教程,无需安装micro-ROS版)

零、预设:

        本次实验是为了给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("%d\r\n",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函数来进行,真正的收发数据就需要我们把想要发送的数据进行一定的“打包”,后续的“打包”教程我会继续更新,欢迎大家关注我接收最新的更新~

    作者:_元_

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32与树莓派串口通信实现(简易教程,无需安装micro-ROS版)

    发表回复