前言
实现ubuntu系统下的ROS和STM32完成串口数据收发。
硬件
一、硬件设备
STM32F103ZE
ubuntu18.04
二、硬件连接
STM32串口 + TTL转USB模块(CH340)+ ubuntu18.04
说明:TTL转USB模块连接:RX接串口TX,TX接串口RX,GND接GND
三、驱动安装
1. 查看ubuntu对USB转串口设备的支持,看是否有ch340或ch34x
# lsmod | grep usbserial
2. 查看当前串口
# ls -l /dev/ttyUSB*
3. 给对应串口权限
sudo chmod 777 /dev/ttyUSB0(这里串口根据自己串口修改)
ROS
一、在ROS工作空间下创建功能包
catkin_ws/src# catkin_create_pkg serial_port roscpp std_msgs geometry_msgs
二、添加串口通信程序
1. serial_port.cpp
#include <ros/ros.h>
#include <ros/time.h>
#include <geometry_msgs/TransformStamped.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h>
#include <boost/asio.hpp>
#include <geometry_msgs/Twist.h>
#include "../include/serial_port.h"
using namespace std;
using namespace boost::asio;
//串口相关对象
boost::asio::io_service iosev;
boost::asio::serial_port sp(iosev, "/dev/ttyUSB0"); //串口号
boost::system::error_code err;
/********************************************************
串口发送接收相关常量、变量、共用体对象
********************************************************/
const unsigned char ender[2] = {0x0d, 0x0a}; //尾部
const unsigned char header[2] = {0x55, 0xaa}; //头部
/**
* 函数功能:串口参数初始化
* 入口参数:无
* 出口参数:void
*/
void serialInit()
{
sp.set_option(serial_port::baud_rate(115200)); //串口波特率
sp.set_option(serial_port::flow_control(serial_port::flow_control::none));
sp.set_option(serial_port::parity(serial_port::parity::none));
sp.set_option(serial_port::stop_bits(serial_port::stop_bits::one));
sp.set_option(serial_port::character_size(8));
}
/**
* 函数功能:串口发送数据
* 入口参数:unsigned char类型数组(以0x7b开头,以0x7d,0x0d,0x0a结尾)
* 出口函数:bool类型
*/
bool writeData()
{
//测试数据
unsigned char buff[15] = {0x7b, 0xaa, 0x11, 0x12, 0x11, 0x11, 0x11, 0x0d, 0x0a};
// 通过串口下发数据
boost::asio::write(sp, boost::asio::buffer(buff));
return true;
}
/**
* 函数功能:串口接收数据
* 入口参数:void
* 出口参数:bool类型
*/
bool readData()
{
unsigned char buff[11]={0};
uint8_t buffer[11]={0};
//此段代码可以读数据的结尾,进而来进行读取数据的头部
try
{
boost::asio::streambuf response;
boost::asio::read_until(sp, response, "",err);
copy(istream_iterator<unsigned char>(istream(&response)>>noskipws),
istream_iterator<unsigned char>(),
buff);
}
catch(boost::system::system_error &err)
{
ROS_INFO("read_until error");
}
//buffer = buff[0];
for(int i = 0; i < sizeof(buffer); i++)
{
buffer[i] = buff[i];
ROS_INFO("buffer[%d]: %d", i, buffer[i]);
}
return true;
}
2. serial_node.cpp
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "../include/serial_port.h"
int main(int agrc,char **argv)
{
ros::init(agrc,argv,"public_node");
ros::NodeHandle nh;
ros::Rate loop_rate(10);
//串口初始化
serialInit();
while(ros::ok())
{
ros::spinOnce();
//向STM32端发送数据
writeData();
//从STM32接收数据
readData();
}
return 0;
}
STM32
1. 通过串口中断来接收数据
usart.c文件
uint8_t STR_RX[200]; //定义接收数据数组
u16 STR_RX_NUM;
//接收以0x0d 0x0a结尾的数据
void USART1_IRQHandler(void) //串口1中断服务函数
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART_RX_STA&0x8000)==0) //接收未完成
{
if(USART_RX_STA&0x4000) //接收到0x0d
{
if(Res!=0x0a)USART_RX_STA=0; //接收不是0x0a表示接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成
}
else //还没收到oxod
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
STR_RX[STR_RX_NUM] = Res; //消息存入数组
USART_RX_STA++;
STR_RX_NUM++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误重新接收
}
}
}
}
}
2. 串口发送数据
main.c
if(USART_RX_STR&0x8000)
{
for(t=0; t <STR_RX_NUM; t++)
{
USART_SendData(USART1, STR_RX[t]);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET); //等待数据发送完成
}
STR_RX_NUM = 0; //接收字符串大小清零
USART_RX_STR = 0; //接收状态标志清零
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)