C语言——读取串口数据,并处理

本文主要内容包含:
1.接收串口数据程序的编程逻辑示意图;
2.接收串口数据程序要用到的通用函数模块(可直接引用,无需更改);
3.接收串口数据程序的示例。

1.接收串口数据程序的编程逻辑示意图:
在这里插入图片描述

2.与串口有关的函数模块及数组(可直接引用到自己的程序中):
main.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "openDev.h"

int main()
{
    int fd;
    int nread;
    char buffer[MAX_BUFF_SIZE];

    serial_parse phandle;
    phandle.rxbuffsize = 0;

    char *dev_name = "/dev/ttyUSB0";//根据实际情况选择串口

    while(1) 
    {  
        fd = OpenDev(dev_name); //打开串口 

        if(fd>0)
        {
            set_speed(fd,9600); //设置波特率
            printf("set speed success!\n");
        }     
        else  
        { 
            printf("Can't Open Serial Port!\n"); 
            sleep(1);  //休眠1s
            continue; 
        } 
        break;
    }

    if(set_Parity(fd,8,1,'N')==FALSE) //设置校验位 
    {
        printf("Set Parity Error\n"); 
        exit(1);
    }
    else
    {
        printf("Set Parity Success!\n"); 
    }

    while(1) 
    { 
        usleep(10000);  //休眠1ms
        nread = read(fd , phandle.buff + phandle.rxbuffsize, MAX_BUFF_SIZE - phandle.rxbuffsize);
        phandle.rxbuffsize += nread;
        phandle.buff[phandle.rxbuffsize] = '\0';
		/*
		处理 phandle.buff
		*/
	}

	return 0;
}

openDev.h

#ifndef OPENDEV_H
#define OPENDEV_H

#include <math.h>

#define TRUE 1
#define FALSE 0
#define MAX_BUFF_SIZE (256)

typedef struct _serial_parse
{
    char buff[MAX_BUFF_SIZE];
    int rxbuffsize;
}serial_parse;

int OpenDev(char *Dev);
void set_speed(int fd, int speed);
int set_Parity(int fd,int databits,int stopbits,int parity);

#endif

openDev.c

#include <termios.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "openDev.h"

#define TRUE 1
#define FALSE 0
 
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, };
 
int OpenDev(char *Dev)
{
  int fd = open(Dev,O_RDWR | O_NOCTTY | O_NONBLOCK);
  if(-1 == fd)
    {
      perror("Can't Open Serial PPPPort");
      return -1;
    } 
  else 
    {
      printf("Open com success!\n");
      return fd;
    }
} 

void set_speed(int fd, int speed)
{ 
  int i; 
  int status; 
  struct termios Opt;
 tcgetattr(fd, &Opt); 
  for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
   { 
      if (speed == name_arr[i]) 
        { 
          tcflush(fd, TCIOFLUSH); 
          cfsetispeed(&Opt, speed_arr[i]);
         cfsetospeed(&Opt, speed_arr[i]);
         status = tcsetattr(fd, TCSANOW, &Opt); 
          if (status != 0) perror("tcsetattr fd1");
         return;
       } 
    tcflush(fd,TCIOFLUSH);
    }
}

int set_Parity(int fd,int databits,int stopbits,int parity) 
{ 
  struct termios options; 
  if ( tcgetattr( fd,&options) != 0) 
  {
   perror("SetupSerial 1");
   return(FALSE);
 } 
  bzero(&options,sizeof(options)); 
  options.c_cflag |= CLOCAL | CREAD;
 options.c_cflag &= ~CSIZE; 
  switch (databits) 
  { 
    case 7: 
    options.c_cflag |= CS7;
   break;
   case 8:
   options.c_cflag |= CS8;
   break; 
    default: fprintf(stderr,"Unsupported data size\n");
   return (FALSE); 
  } 
  switch (parity) 
  {
   case 'n': 
    case 'N':
   options.c_cflag &= ~PARENB;
   options.c_iflag &= ~INPCK; 
    break; 
    case 'o':
   case 'O': 
    options.c_cflag |= (PARODD | PARENB);
   options.c_iflag |= (INPCK | ISTRIP); 
    break; 
    case 'e': 
    case 'E': 
    options.c_cflag |= PARENB;
   options.c_cflag &= ~PARODD; 
    options.c_iflag |= (INPCK | ISTRIP); 
    break; 
    case 'S': 
    case 's': 
    options.c_cflag &= ~PARENB; 
    options.c_cflag &= ~CSTOPB;
   break;
   default: fprintf(stderr,"Unsupported parity\n"); 
   return (FALSE); 
  } 
  switch (stopbits)
 { 
    case 1:
   options.c_cflag &= ~CSTOPB; 
    break; 
    case 2: 
    options.c_cflag |= CSTOPB;
   break; 
    default: fprintf(stderr,"Unsupported stop bits\n"); 
    return (FALSE); 
    } 
    if (parity != 'n') 
    options.c_iflag |= INPCK; 
    options.c_cc[VTIME] = 0;
   options.c_cc[VMIN] = 0;
   tcflush(fd,TCIFLUSH); 
    if (tcsetattr(fd,TCSANOW,&options) != 0)
   {  
        perror("SetupSerial 3"); 
        return (FALSE);
   } 
    return (TRUE);
}

以上。

参考:https://blog.csdn.net/wangqingchuan92/article/details/73497354/

  • 16
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在Ubuntu下使用C语言处理串口数据并发布到ROS话题中,您需要完成以下步骤: 1. 安装ROS:在Ubuntu上安装ROS,可以参考ROS官方文档进行安装。 2. 安装串口库:在Ubuntu上使用C语言处理串口数据需要使用串口库,可以使用libserial库或者termios库。您可以使用以下命令安装termios库: ``` sudo apt-get install libserial-dev ``` 3. 创建ROS包:使用ROS命令行工具,创建一个ROS包,该包将包含您的串口数据处理程序。例如: ``` cd ~/catkin_ws/src catkin_create_pkg serial_communication roscpp ``` 4. 编写C语言程序:在ROS包的src目录下,编写一个C语言程序来读取串口数据并发布到ROS话题中。可以使用以下代码作为参考: ``` #include <ros/ros.h> #include <serial/serial.h> #include <std_msgs/String.h> int main (int argc, char** argv) { ros::init(argc, argv, "serial_communication"); ros::NodeHandle nh; ros::Publisher pub = nh.advertise<std_msgs::String>("serial_data", 1000); serial::Serial ser; ser.setPort("/dev/ttyUSB0"); ser.setBaudrate(115200); serial::Timeout to = serial::Timeout::simpleTimeout(1000); ser.setTimeout(to); try { ser.open(); } catch (serial::IOException& e) { ROS_ERROR_STREAM("Unable to open port"); return -1; } if (ser.isOpen()) { ROS_INFO_STREAM("Serial port initialized"); } else { return -1; } while (ros::ok()) { if (ser.available()) { std_msgs::String msg; msg.data = ser.read(ser.available()); pub.publish(msg); } ros::spinOnce(); } return 0; } ``` 该程序使用serial库读取/dev/ttyUSB0串口数据,并将数据发布到ROS话题"serial_data"中。 5. 编译ROS包:使用ROS命令行工具,编译ROS包。例如: ``` cd ~/catkin_ws catkin_make ``` 6. 运行程序:在终端中运行ROS程序。例如: ``` rosrun serial_communication serial_communication ``` 此时,您的程序将读取串口数据并发布到ROS话题中。 注意,以上代码仅为示例,您需要根据实际情况进行修改。同时,还需要在ROS中创建一个订阅该话题的节点,以接收串口数据
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值