[ARM+Linux] 基于wiringPi库的串口通信

news2024/9/30 15:24:35

wiringOP-master/examples/serialTest.c中,wiringPi库中自带的串口程序:

#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <wiringPi.h>
#include <wiringSerial.h>

int main ()
{
    int fd ;
    int count ;
    unsigned int nextTime ;

    if ((fd = serialOpen ("/dev/ttyS2", 115200)) < 0)//打开在/dev.ttyS2路径下的文件,波特率配置成115200,如果返回值为-1说明打开失败
    {
        fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
        return 1 ;
    }

    if (wiringPiSetup () == -1)//初始化wiringPi库
    {
        fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
        return 1 ;
    }

    nextTime = millis () + 300 //这个函数返回 一个 从你的程序执行 wiringPiSetup 初始化函数(或者wiringPiSetupGpio ) 到 当前时间 经过的 毫秒数。返回类型是unsigned int,最大可记录 大约49天的毫秒时长。


    for (count = 0 ; count < 256 ; )
    {
        if (millis () > nextTime)
        {
            printf ("\nOut: %3d: ", count) ;
            fflush (stdout) ;//fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上。
            serialPutchar (fd, count) ;//将字符输出到串口
            nextTime += 300 ;
            ++count ;
        }

        delay (3) ;

        while (serialDataAvail (fd))
        {
            printf (" -> %3d", serialGetchar (fd)) ;//获取串口的数据
            fflush (stdout) ;
        }
    }

    printf ("\n") ;
    return 0 ;

(90条消息) fflush(stdio)、fflush(stdout)详解_hanxp001的博客-CSDN博客

根据官方的wiringPi库修改接收和发送串口数据

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <stdlib.h>
#include <unistd.h>
int fd ;

void* SendHandler()
{
    char *SendBuf;
    SendBuf = (char *)malloc(32*sizeof(32));
    while(1)
    {
        memset(SendBuf,'\0',32);
        scanf("%s",SendBuf);
        while(*SendBuf != NULL)
        {
            serialPutchar(fd, *SendBuf++);
        }
    }
}

void* RevHandler()
{
    while(1)
    {
        while (serialDataAvail(fd))
        {
            printf ("%c", serialGetchar(fd)) ;
            fflush (stdout) ;
        }
    }

}

int main ()
{
    int count ;
    unsigned int nextTime ;
    pthread_t idsend;//定义线程标识符
    pthread_t idrev;//定义线程标识符
    if ((fd = serialOpen ("/dev/ttyS5", 115200)) < 0)
    {
        fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
        return 1 ;
    }

    pthread_create(&idsend,NULL,SendHandler,NULL);//创建线程1发送数据
    pthread_create(&idrev,NULL,RevHandler,NULL);//创建线程2接收数据
    if (wiringPiSetup () == -1)
    {
        fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
        return 1 ;
    }

    while(1)
    {
        sleep(10);
    }
    printf ("\n") ;
    return 0 ;
}


 修改过后通过创建线程来接收和发送串口数据

    pthread_create(&idsend,NULL,SendHandler,NULL);//创建线程1发送数据
    pthread_create(&idrev,NULL,RevHandler,NULL);//创建线程2接收数据

(90条消息) Linux 线程_TX564的博客-CSDN博客

接收数据通过调用wiringPi库自带函数 serialGetchar(fd)来获取上位机通过串口发送的数据

通过scanf获取来自键盘输入的数据再通过serialPutchar(fd, *SendBuf++);发送数据

 (90条消息) wiringPI库_LEO-max的博客-CSDN博客

基于C库的原生开发串口主要是靠一个结构体实现所有的启动位,停止位,数据位,奇偶校验,波特率

 

根据wiringPi库自己写一个串口

先在桌面新建一个UartTool.c文件然后拖入Source Insight中编写

UartTool.c

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

#include "wiringSerial.h"


int MyserialOpen (const char *device, const int baud)
{
   struct termios options ;
   speed_t myBaud ;
   int	  status, fd ;

   switch(baud)
   	{
		case 9600: myBaud = B9600;break;
		case 115200: myBaud = B115200;break;
    }
   if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)//打开设备
    return -1 ;

   // Get and modify current options:

    tcgetattr (fd, &options) ;

    cfmakeraw   (&options) ;
    cfsetispeed (&options, myBaud) ;//波特率设置,进波特率
    cfsetospeed (&options, myBaud) ;//波特率设置,出波特率

    options.c_cflag |= (CLOCAL | CREAD) ;
    options.c_cflag &= ~PARENB ;//设置奇偶校验位
    options.c_cflag &= ~CSTOPB ;//停止位
    options.c_cflag &= ~CSIZE ;
    options.c_cflag |= CS8 ;//数据位,8位
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
    options.c_oflag &= ~OPOST ;

    options.c_cc [VMIN]  =   0 ;
    options.c_cc [VTIME] = 100 ;	// Ten seconds (100 deciseconds)
 
    tcsetattr (fd, TCSANOW, &options) ;

    ioctl (fd, TIOCMGET, &status);

    status |= TIOCM_DTR ;
    status |= TIOCM_RTS ;

    ioctl (fd, TIOCMSET, &status);

    usleep (10000) ;	// 10mS

  return fd ;
}


void serialSendstring (const int fd, const char *s)
{
	int ret;
	ret = write (fd, s, strlen (s));
	if (ret < 0)
		printf("Serial Puts Error\n");

}


int serialGetstring(const int fd,char*buffer)
{
	int n_read;
	n_read = read(fd,buffer,32);
	return n_read;
}


int serialDataAvail (const int fd)
{
  int result ;

  if (ioctl (fd, FIONREAD, &result) == -1)
    return -1 ;

  return result ;
}

 UartTool.h

   int MyserialOpen (const char *device, const int baud);
  
   void serialSendstring (const int fd, const char *s);
  
   int serialGetstring(const int fd,char*buffer);
  
   int serialDataAvail (const int fd);

UartTest.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
#include "UartTool.h"
#include <unistd.h>
#include <string.h>


int fd;

void* readSerial()
{
    char buffer[32] = {'\0'};
     while(1)
     {
        while(serialDataAvail(fd))//从串口读取一个字节(没有可用数据会等待10s)如果有的话返回数据,没有的话返回-1
        {
            memset(buffer,'\0',sizeof(buffer));
            serialGetstring(fd,buffer);
            printf("GET->%s\n",buffer);
        }
     }
}

void* sendSerial()
{
    char buffer[32] = {'\0'};
    while(1)
    {
        memset(buffer,'\0',sizeof(buffer));
        scanf("%s",buffer);
        serialSendstring(fd,buffer);
    }
}


int main(int argc,char** argv)
{
    char deviceName[32] = {'\0'};
    pthread_t readt;
    pthread_t sendt;
    if(argc < 2)
    {
        printf("uage:%s /dev/ttyS?\n",argv[0]);
        return -1;
    }

    strcpy(deviceName,argv[1]);

    if((fd =MyserialOpen(deviceName,115200)) == -1)
    {
        printf("open %s error!\n",deviceName);
        return -1;
    }
    pthread_create(&readt,NULL,readSerial,NULL);
    pthread_create(&sendt,NULL,sendSerial,NULL);


    while(1){sleep(10);}
}

通过以上操作就可以摆脱wiringPi库了 

 核心就是打开某个设备(文件),将参数配置好传给内核,内核驱动根据给的各个参数去配置硬件的寄存器,向串口写数据其实就是写文件操作,读数据其实就是读文件操作

基于串口开发一个小项目:用语音控制抖音上滑下滑点赞锁屏 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/437950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaSE-part1

文章目录 Day01 面向对象特性1.java继承注意点2.多态2.1多态概述2.2多态中成员的特点:star::star:2.3多态的转型:star::star: 3.Super4.方法重写:star::star:5.Object类:star::star: Day02 面向对象特性1.代码块:star:(主要是初始化变量&#xff0c;先于构造器)2.单例设计模式:…

服务器初始化

Linux基础系类 提示&#xff1a;个人学习总结&#xff0c;仅供参考。 一、Linux系统部署 二、服务器初始化 提示&#xff1a;文档陆续更新整理 服务器初始化 Linux基础系类简介一、配置IP地址二、配置YUM源&#xff08;yum本地源和yum网络源&#xff09;1.简介2.准备工作3.配置…

数据结构与算法——深度寻路算法

&#x1f4d6;作者介绍&#xff1a;22级树莓人&#xff08;计算机专业&#xff09;&#xff0c;热爱编程&#xff1c;目前在c&#xff0b;&#xff0b;阶段&#xff0c;因为最近参加新星计划算法赛道(白佬)&#xff0c;所以加快了脚步&#xff0c;果然急迫感会增加动力>——…

SQL Server的行级安全性

行级安全性 一、前言二、描述三、权限四、安全说明&#xff1a;侧信道攻击五、跨功能兼容性六、示例 一、前言 行级别安全性使您能够使用组成员身份或执行上下文来控制对数据库表中行的访问。 行级别安全性 &#xff08;RLS&#xff09; 简化了应用程序中的安全性设计和编码。…

MyBatis(一)

一、简介 1.1 什么是MyBatis MyBatis是一个持久层框架&#xff0c;既然和持久层有关那就可以简单理解成和数据库有关&#xff0c;既然是框架那么就肯定是为了简化数据库有关的操作。由于传统的JDBC代码处理数据库有关的代码太复杂&#xff0c;所以出现了MyBatis来快速处理数据…

RK3588调试CAN驱动记录

背景 汽车芯片公司&#xff0c;IP领导随机分配&#xff0c;主要任务是各种IP的硅前验证&#xff0c;包括uboot命令行和Linux kernel验证。工作两年半没什么外设经验也没做过CAN总线(前两年在一家芯片公司做各种加解密IP的开发)&#xff0c;一个人的摸索过程可以说是充满了坎坷…

花有约,春不迟|弘博创新2023塘朗山到梅林水库穿越活动

花有约,春不迟|弘博创新2023塘朗山到梅林水库穿越活动 花开有约&#xff0c;春日不迟 4月16日&#xff0c;正值春暖花开的季节&#xff0c;周末闲暇无事&#xff0c;弘博创新的朋友们相聚一起&#xff0c;从塘朗山龙珠门到梅林水库&#xff0c;体验一场感受大自然&#xff0c;开…

dsl语法

查询 1.查询所有&#xff08;默认有分页查询&#xff09; #查询所有 GET /hotel/_search {"query": {"match_all": {}} } 2.match查询&#xff08;条件查询&#xff09;-----包含四川和外滩的信息&#xff0c;信息匹配度越高越靠前&#xff0c;两者存在一…

知识库管理系统对于企业有哪些作用及优势?

知识库管理系统是一种通过集成多种技术手段&#xff0c;将企业内部知识进行收集、整理、存储、分析和共享的信息管理系统。知识库管理系统可以帮助企业管理和利用企业内部的知识&#xff0c;提高企业的创新能力和竞争力。 知识库管理系统的作用 1、促进企业内部知识的流通和共…

AutoGPT 安装指南,使用避坑要点

最近&#xff0c; AIGC 中最火的可能就当属于 AutoGPT 了吧&#xff0c;首先简单介绍一下AutoGPT 背景 AutoGPT 是基于 ChatGPT API 接口开发&#xff0c;项目首推 GPT-4 模型&#xff0c;但 OpenAI 账号 API 只有 gpt-3.5-turo 权限同样也可以使用。 项目在 github 上获取的…

Java多线程初阶(二)(图片+源码+超详细)

在这之前可以参照&#xff1a;Java多线程初阶&#xff08;一&#xff09;这篇文章&#x1f43b; 目录 1. 线程的状态 2. 线程安全问题 2.1 引出线程安全问题 2.2 线程安全问题出现的原因 2.3 解决线程安全问题的方法 2.4 synchronized关键字详解 2.5 volatile关键字详解…

【LeetCode】145.二叉树的后续遍历

1.问题 给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[3,2,1] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xff1a;roo…

Linux搭建我的世界MC服务器 - MCSM面板 【外网远程联机教程】

文章目录 1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 Linux使用MCS…

程序地址空间(上)

目录 &#xff1a; 1.C/C程序地址空间回顾&#xff08;C语言&#xff09; 2.通过一段代码&#xff08;引出进程虚拟地址空间&#xff09; 3.进程虚拟地址空间是什么 ------------------------------------------------------------------------------------------------------…

项目制作4

今天对文件录入,进行了测试,结构体录入还是非常的好用的 对地图也有了新的制作,但是地图上的鼠标操作遇到了问题 难以解决,一搞就是内存问题给我下坏了 哎我选择认了,用控制台来显示公告算了 for (int j 1;j < f->Points;j) fread(&f->drops[j], sizeof(drop…

微服务---Docker的基本使用

Docker 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署&#xff0c;环境不…

虹科分享 | 基于流的流量分类的工作原理 | 网络流量监控

许多ntop产品&#xff0c;如ntopng、nProbe和PF_RING FT等都是基于网络流的。然而&#xff0c;并不是所有的用户都详细知道什么是网络流&#xff0c;以及它在实践中是如何工作的。这篇博客文章描述了它们是什么以及它们在实践中是如何工作的。 什么是网络流量 网络流是一组具…

C++11新特性(下)

文章目录 1. 可变参数模板1.1 empalce相关接口函数 2. lambda表达式2.1 C98中的一个例子2.2 lambda表达式语法2.3 函数对象与lambda表达式 3. 包装器3.1 function包装器3.2 bind 1. 可变参数模板 C11的新特性可变参数模板能够让您创建可以接受可变参数的函数模板和类模板。相比…

Matlab与ROS---Action与Gazebo(六)

0. 简介 对于ROS1而言&#xff0c;其在Matlab当中相较于ROS2还有一些比较高级的用法&#xff0c;比如说我们接下来要说的Action和Gazebo仿真。 1. ROS Action ROS的Action行为模式当中也存在有一个客户端到服务器的通信关系。Action行为模式使用ROS主题将目标消息从客户机发…

【技巧】飞书多维表格零代码连接飞书多维表格,实现表单自动同步

飞书多维表格用户使用场景&#xff1a; 在公司日常工作中&#xff0c;各个部门使用飞书多维表格记录签订合同、文件审核、归档等事务&#xff0c;常需要行政人员辅助处理&#xff0c;将这些子表单的数据汇总到一个总表单中。但每个部门对应的事务较为复杂&#xff0c;子表单数量…