天天看點

stm32與linux序列槽通訊,C++檔案與STM32進行序列槽通信例程

前幾日有學弟問我,ros如何跟下位機通信呢?

stm32與linux序列槽通訊,C++檔案與STM32進行序列槽通信例程

我的第一反應就是rosserial通信協定,rosserail是用于非ROS裝置與ROS裝置進行通信的一種協定。它為非ROS裝置的應用程式提供了ROS節點和服務的釋出/訂閱功能,使在非ROS環境中運作的應用能夠通過序列槽或網絡能夠輕松地與ROS應用進行資料互動。

學弟聽後興高采烈地就去找資料學習去了,不過過了幾個小時回來就對我說:學長,你說的這個也太麻煩了,有沒有一下就學會的速成寶典之類的。我不敢說自己有什麼速成寶典,但确實有所謂好了解的東西。

因為我們知道,在接手一個新的通信協定後肯定會花一點時間去研究,上手,了解之後才能掌握。但是如果使用我們自己之前學過的協定來實作,那會大大減少工作的難度。

序列槽通信協定是我們常見的通信協定,在學單片機時這也是作為一個很重要很基礎的部分,是以像這種通信協定對我們而言是比較熟悉友善的。

stm32與linux序列槽通訊,C++檔案與STM32進行序列槽通信例程

首先介紹一下Serial,

Serial is a cross-platform, simple to use library for using serial ports on computers. This library provides a C++, object oriented interface for interacting with RS-232 like devices on Linux and Windows.

Want to use it with ROS(Robot Operating System)? No problem, it compiles as a unary stack.

用到的主類就是Serial

serial::Serial Stm32_Serial; //聲明序列槽對象

Stm32_Serial.setPort("/dev/sensor");//選擇哪個口,如果選擇的口沒有接序列槽外設初始化會失敗

Stm32_Serial.setBaudrate(9600);//設定波特率

serial::Timeout _time = serial::Timeout::simpleTimeout(2000);//逾時等待

Stm32_Serial.setTimeout(_time);

Stm32_Serial.open();//序列槽開啟

以上就是相應的序列槽初始化

然後我們再看看要發送的内容以及确定的格式

unsigned char *a; //定義unsigned char*類型

a=(unsigned char *)malloc(sizeof(unsigned char)*3); //大小

a[0]='1';

a[1]=0x0d;

a[2]=0x0a;

Stm32_Serial.write(a,3); //發送函數

stm32與linux序列槽通訊,C++檔案與STM32進行序列槽通信例程

這個是Serial::serial類的成員,我們用到的就是建圖所指,第一個參數是a指針,第二個為大小。a[1]和a[2]是32usart接收函數需要的,預設我們隻發1這個字元,這樣發送某個字元就完成了。

那麼接下來說一下接收代碼

char x,y,m,n;

string rec_buffer; //string類型

const char *Receive_Data_Pr; //

rec_buffer=Stm32_Serial.readline(4,"\n");//讀序列槽資料

Receive_Data_Pr=rec_buffer.data(); //轉換類型

for(i=0;i<4;i++)

{

if(i==0) x=Receive_Data_Pr[i];

if(i==1) y=Receive_Data_Pr[i];

if(i==2) n=Receive_Data_Pr[i];

if(i==3) m=Receive_Data_Pr[i];

}

stm32與linux序列槽通訊,C++檔案與STM32進行序列槽通信例程

首先将接受的資料轉換成string類型,緊接着将資料轉換成char類型,進而完成了字元串的接收以及分離出字元。之後将字元進行處理無論轉換成那種格式都會比較友善了。

這裡我貼一下源碼(這個是當時做的一個工程檔案裡的一部分,大家根據自己實際需求自行修改)

#include "ros/ros.h"

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using std::string;

string rec_buffer; //序列槽資料接收變量

int main()

{

FILE *pf=NULL;

int i;

char x,y,m,n;

unsigned char *a;

a=(unsigned char *)malloc(sizeof(unsigned char)*3);

serial::Serial Stm32_Serial; //聲明序列槽對象

const char *Receive_Data_Pr;

float num;

Stm32_Serial.setPort("/dev/sensor");//選擇哪個口,如果選擇的口沒有接序列槽外設初始化會失敗

Stm32_Serial.setBaudrate(9600);//設定波特率

serial::Timeout _time = serial::Timeout::simpleTimeout(2000);//逾時等待

Stm32_Serial.setTimeout(_time);

Stm32_Serial.open();//序列槽開啟

a[0]='1';

a[1]=0x0d;

a[2]=0x0a;

Stm32_Serial.write(a,3);

for(i=0;i<1;i++)

{

Stm32_Serial.write(a,3);

sleep(1);

rec_buffer=Stm32_Serial.readline(4,"\n");//讀序列槽資料

Receive_Data_Pr=rec_buffer.data();

for(i=0;i<4;i++)

{

if(i==0) x=Receive_Data_Pr[i];

if(i==1) y=Receive_Data_Pr[i];

if(i==2) n=Receive_Data_Pr[i];

if(i==3) m=Receive_Data_Pr[i];

}

pf=fopen("/home/tcuzel/FBIwenjian/1.txt", "w" );//假設test.txt檔案為空

if(!pf)

{

printf("打開檔案失敗,程式退出!");

exit(1);

}

fprintf(pf,"%c%c.%c%c\n",x,y,n,m);//寫入,test.txt檔案内容為10 12.345000 testinfo

sleep(1);

}

Stm32_Serial.close();//關閉序列槽

ROS_INFO_STREAM("Shutting down");//close

return 0;

}