文章目录

  • 一. 前言
  • 二. 要掌握的知识
    • 2.1 struct termios 结构体
    • 2.2 c_iflag 输入模式标志
    • 2.2 c_oflag 输出模式标志
    • 2.3 c_cflag 控制模式标志
    • 2.4 c_lflag 本地控制模式
    • 2.5 c_cc[VTIME] , c_cc[VMIN]
    • 2.6 tcgetattr() 与 tcsetattr()
      • tcgetattr()
      • tcsetattr()
    • 2.7 tcflush()
    • 2.8 cfsetispeed() 与 cfsetospeed()
  • 三. 绘制流程图与设计代码
    • 3.1 串口的打开和关闭
    • 3.2 串口的初始化
    • 3.3 AT指令的发送及串口数据的接收
    • 3.4 主程序
  • 四. 运行截图
  • 五. 讨论

一. 前言

 在拿到我的EC20 4G模块后,可谓是迫不及待的去办了一张新的电话卡,可是在插上卡以后,登录我的树莓派,却始终存在一个问题,插上卡以后,使用AT命令

AT+CSQ

查看信号强度,一切正常,

AT+CPIN?

一切也都就绪,但是在使用

AT+CREG?

时,却出现了(0,2)的错误,我上一篇博客有提到,使用这个命令第二个参数出现2说明卡还没有注册上,但是处于正在注册状态,可是无论我怎么等,仍然处于这个状态,换了几张卡依然如此,能检查出卡,却大不了电话发不了短信,在网上找了各种解决方法,csdn,找了EC20 4G模块的淘宝客户,提供的方法都解决不了,在经过一天努力未果后,我决定放弃了,于是我拔下了模块的天线,可就是这时候,我看到了天线插口写着一个DIV,另一个插口写着一个MAIN(超级小),内心一颤,心想会不会是天线的原因,果不其然,在我跟换天线的插口位置以后,一切的问题全都解决了…
原来模块分为两个天线口,一个是主集天线,一个是分集天线,后者只能用来接收数据,所以在查看信号时时没问题的,让我压根没想到这俩天线还有差别,所以如果你也遇到AT+CREG?返回 +CREG: 0,2 不妨也试试 ……

二. 要掌握的知识

废话不多说,这次要写的,是一个用于串口通信的程序,类似于我们Linux中busybox的microcom工具,该工具用来实现与串口之间的通信,如图:
在这里插入图片描述
因为的我们在使用microcom的时候,接收到的数据与答复,都是通过肉眼来观察判断的,但如果通过程序实现,我们可以将接收到的数据进行处理并利用进程间通信或是socket发送至其他地方,又或者可以设置每隔多少时间发送一条短信,并且,在学习这个程序的编程中,将会慢慢的对串口通信更加了解,我之前的博客介绍了串口通信的基本知识,在掌握这些后,我们一起来看程序吧~

2.1 struct termios 结构体

通过termios结构体,我们可以更好地控制串口的属性,例如输入,输出或者一些特殊的要求我们都可以通过设置这个值来实现:

struct termios
{tcflag_t c_iflag;           //输入模式标志tcflag_t c_oflag;           //输出模式标志tcflag_t c_cflag;           //控制模式标志tcflag_t c_lflag;           //本地模式标志cc_t    c_cc[NCCS];        //控制字符speed_t c_isspeed;         //输入波特率speed_t c_ospedd;          //输出波特率
}

通过设定对应功能的结构体成员以达到控制串口属性的目的,属性的设置是通过标志位来实现的,通过与,或和取反等方式,来将对应的功能模块的标志位置0或者置1,从而告诉系统是否要有此功能,关于属性设置,分为输入,输出,控制等属性,下面一一来看他们都有哪些键值设置吧:

2.2 c_iflag 输入模式标志

  • IGNBRK
    忽略BREAK键输入

  • BRKINT
    如果设置了IGNBRK,BREAK键的输入将被忽略,如果设置了BRKINT ,将产生SIGINT中断

  • IGNPAR
    忽略奇偶校验错误

  • PARMRK
    标识奇偶校验错误

  • INPCK
    允许输入奇偶校验

  • ISTRIP
    去除字符的第8个比特

  • INLCR
    将输入的NL(换行)转换成CR(回车)

  • IGNCR
    忽略输入的回车

  • ICRNL
    将输入的回车转化成换行(如果IGNCR未设置的情况下)

  • IUCLC
    将输入的大写字符转换成小写字符(非POSIX)

  • IXON
    允许输入时对XON/XOFF流进行控制

  • IXANY
    输入任何字符将重启停止的输出

  • IXOFF
    允许输入时对XON/XOFF流进行控制

  • IMAXBEL
    当输入队列满的时候开始响铃,Linux在使用该参数而是认为该参数总是已经设置

2.2 c_oflag 输出模式标志

  • OPOST
    处理后输出

  • OLCUC
    将输入的小写字符转换成大写字符(非POSIX)

  • ONLCR
    将输入的NL(换行)转换成CR(回车)及NL(换行)

  • OCRNL
    将输入的CR(回车)转换成NL(换行)

  • ONOCR
    第一行不输出回车符

  • ONLRET
    不输出回车符

  • OFILL
    发送填充字符以延迟终端输出

  • OFDEL
    以ASCII码的DEL作为填充字符,如果未设置该参数,填充字符将是NUL(‘\0’)(非POSIX)

  • NLDLY
    换行输出延时,可以取NL0(不延迟)或NL1(延迟0.1s)

  • CRDLY
    回车延迟,取值范围为:CR0、CR1、CR2和 CR3

  • TABDLY
    水平制表符输出延迟,取值范围为:TAB0、TAB1、TAB2和TAB3

  • BSDLY
    空格输出延迟,可以取BS0或BS1

  • VTDLY
    垂直制表符输出延迟,可以取VT0或VT1

  • FFDLY
    换页延迟,可以取FF0或FF1

2.3 c_cflag 控制模式标志

  • CBAUD
    波特率(4+1位)(非POSIX)

  • CBAUDEX
    附加波特率(1位)(非POSIX)

  • CSIZE
    字符长度,取值范围为CS5、CS6、CS7或CS8

  • CSTOPB
    设置两个停止位

  • CREAD
    使用接收器

  • PARENB
    使用奇偶校验

  • PARODD
    对输入使用奇偶校验,对输出使用偶校验

  • HUPCL
    关闭设备时挂起

  • CLOCAL
    忽略调制解调器线路状态

  • CRTSCTS
    使用RTS/CTS流控制

2.4 c_lflag 本地控制模式

  • ISIG
    当输入INTR、QUIT、SUSP或DSUSP时,产生相应的信号

  • ICANON
    使用标准输入模式

  • XCASE
    在ICANON和XCASE同时设置的情况下,终端只使用大写。如果只设置了XCASE,则输入字符将被转换为小写字符,除非字符使用了转义字符(非POSIX,且Linux不支持该参数)

  • ECHO
    显示输入字符

  • ECHOE
    如果ICANON同时设置,ERASE将删除输入的字符,WERASE将删除输入的单词

  • ECHOK
    如果ICANON同时设置,KILL将删除当前行

  • ECHONL
    如果ICANON同时设置,即使ECHO没有设置依然显示换行符

  • ECHOPRT
    如果ECHO和ICANON同时设置,将删除打印出的字符(非POSIX)

  • TOSTOP
    向后台输出发送SIGTTOU信号

2.5 c_cc[VTIME] , c_cc[VMIN]

调用read()函数读取串口数据时,返回读取数据的数量需要考虑两个变量: MIN和TIME。MIN和TIME在termios结构的c_ cc成员的数组下标名为VMIN和VTIME。
MIN是指一次read调用期望返回的最小字节数。VTIME说明等待数据到达的分秒数(秒的1/10为分秒)。TIME与MIN组合使用的具体含义分为以下四种情形:

当MIN>0,TIME>0时
计时器在收到第-一个字节后启动,在计时器超时之前(TIME的时间到),若己收到MIN个字节,则read返回MIN个字节,否则,在计时器超时后返回实际接收到的字节。
注意:因为只有在接收到第一个字节时才开始计时,所以至少可以返回1个字节。这种情形中,在接到第一个字节之前,调用者阻塞。如果在调用read时数据已经可用,则如同在read后数据立即被接到一样。

当MIN>0,TIME=0时
MIN个字节完整接收后,read 才返回,这可能会造成read无限期地阻塞。

当MIN=0,TIME>0时
TIME为允许等待的最大时间,计时器在调用read时立即启动,在串口接到1字节数据或者计时器超时后即返回,如果是计时器超时,则返回0。

当MIN=0,TIME= 0时
如果有数据可用,则read最多返回所要求的字节数,如果无数据可用,则read立即返回0。

2.6 tcgetattr() 与 tcsetattr()

函数原型:

int tcgetattr(int fd,struct termios &termios_p);
int tcsetattr(int fd,int actions,const struct termios *termios_p);

tcgetattr()

  • 参数
    int fd: 打开串口文件后,获取到的文件描述符
    struct termios &termios_p: termios 类型的结构体,包含在 <termios.h> 头文件中,这里需要传地址或指针

  • 返回值:成功返回 0,失败返回 -1

  • 函数功能: 获取文件描述符对应串口的原始属性,并保存在第二个参数中,通常获取的原始属性需要进行备份,在程序退出之前要将其修改回来,否则无法继续使用串口。

tcsetattr()

  • 参数
    int fd: 要设置属性的文件描述符
    int actions: 设置属性时,可以控制属性生效的时刻,actions可以取下面几个值:
    TCSANOW: 立即生效
    TCADRAIN: 改变在所有写入fd 的输出都被传输后生效。这个函数应当用于修改影响输出的参数时使用。(当前输出完成时将值改变)
    TCSAFLUSH :改变在所有写入fd 引用的对象的输出都被传输后生效,所有已接受但未读入的输入都在改变发生前丢弃(同TCSADRAIN,但会舍弃当前所有值)。
    *termios termios_p: 用来设置的串口属性的结构体指针,通过目录2.2之后的属性设置好termios后,传入函数即可
  • 返回值: 成功返回 0 ,失败返回-1.

2.7 tcflush()

函数原型

int tcflush(int fd,int quene)
  • 参数
    fd: 要操作的文件描述符
    quene: 操作位置,可以取下面三个值:
    TCIFLUSH:清空输入队列
    TCOFLUSH:清空输出队列
    TCIOFLUSH:清空输入输出队列

在打开串口后,串口其实已经可以开始读取 数据了 ,这段时间用户如果没有读取,将保存在缓冲区里,如果用户不想要开始的一段数据,或者发现缓冲区数据有误,可以使用这个函数清空缓冲
需要注意,如果是在任务中,需要不停地写入数据到串口设备,千万不能在每次写入数据到设备前,进行flush以前数据的操作,因为两次写入的间隔是业务控制的,内核不会保证在两次写入之间一定把数据发送成功。flush操作一般在打开或者复位串口设备时进行操作。

返回值:成返回 0 ,失败返回 -1

2.8 cfsetispeed() 与 cfsetospeed()

函数原型

int cfsetispeed(struct termios *termios_p, speed_t speed);
int cfsetospeed(struct termios *termios_p, speed_t speed);
  • 参数
    termios_p: 通过结构体来设置串口通信的属性,这是指向该结构体的指针
    speed: 因为串口通信没有时钟线,是一种异步通信,要想达到通信双发收发信息的统一,就需要设置输入输出波特率相同,通过man手册,可以看到:
    在这里插入图片描述
    这些就是波特率可以选择的值。

三. 绘制流程图与设计代码

我所写的程序包含了3个功能模块,

  1. ComportOpen.c
    该模块包含了串口的打开与关闭两个函数: comport_open ,comport_close.
  2. ComportInit.c
    通过命令行参数传入的值,来设置串口的 波特率,停止位,奇偶校验,数据位以及一些为了通信必须设置的串口属性,以达初始化串口的所有功能,初始化后的串口便可立即使用了。
  3. ComportSwap.c
    用于与串口通信,封装了write() 和 read() 函数。

下面一起来看各个功能模块的流程图吧~

3.1 串口的打开和关闭

打开串口:
在这里插入图片描述
通过传入的文件名打开获取到文件描述符,最终成功后返回文件描述符。

关闭串口

在这里插入图片描述
关闭串口不能简单地close(fd),否则第二次运行程序将无法打开串口,需要重启模块才能再次使用。

ComportOpen.h

#ifndef  _COMPORTOPEN_H_
#define  _COMPORTOPEN_H_#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <termios.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>#define SERIALNAME_LEN 128typedef struct _st_MyAttr {int               fd;        //串口文件描述符int               BaudRate;  //波特率int               DataBits;  //数据位char              Parity;    //奇偶校验位int               StopBits;  //停止位int               mSend_Len; //单次最大发送长度char              SerialName[SERIALNAME_LEN];  //串口名称struct termios    OldTermios;  //串口的原始属性
}MyAttr;int comport_open(MyAttr *attr);
int comport_close(MyAttr *attr);#endif   /* ----- #ifndef _COMPORTOPEN_H_  ----- */

我将所有需要用到的串口属性封装在了一个结构体中,这样,我在设计后面的函数时,就可以直接传结构体指针,再根据功能的实际要求,使用自己需要的成员即可。

ComportOpen.c

/**********************************************************************************      Copyright:  (C) 2020 LuXiaoyang<920916829@qq.com>*                  All rights reserved.**       Filename:  ComportOpen.c*    Description:  This file Open or close the serial port*                 *        Version:  1.0.0(03/07/20)*         Author:  LuXiaoyang <920916829@qq.com>*      ChangeLog:  1, Release initial version on "03/07/20 17:50:09"* *      blog address:https://blog.csdn.net/weixin_45121946        *   ********************************************************************************/
#include "ComportOpen.h"int comport_open(MyAttr *attr)
{int                i;int                retval = -1;if(NULL == attr){printf("%s,Invalid parameter\n",__func__);return retval;}/* O_NOCTTY表示打开的是一个终端设备,程序不会成为该* 端口的控制终端,O_NONBLOCK使得read处于非阻塞模式 */attr->fd = open(attr->SerialName,O_RDWR | O_NOCTTY | O_NONBLOCK);if(attr->fd < 0){printf("%s,Open %s failed:%s\n",__func__,attr->SerialName,strerror(errno));return -1;}/* 检查串口是否处于阻塞态 */if((retval = fcntl(attr->fd,F_SETFL,0)) < 0){printf("%s,Fcntl check faile.\n",__func__);return -2;}printf("Starting serial communication process ");for(i = 0;i < 6;i++){printf(" . ");fflush(stdout);sleep(1);}printf("\n");  //这部分纯属搞笑if(0 == isatty(attr->fd))  //是否为终端设备{printf("%s:[%d] is not a Terminal equipment.\n",attr->SerialName,attr->fd);return -3;}printf("Open %s successfully.\n",attr->SerialName);return 0;
}int comport_close(MyAttr *attr)
{if(tcflush(attr->fd,TCIOFLUSH))  //清零用于串口通信的缓冲区{printf("%s,Tcflush faile:%s\n",__func__,strerror(errno));return -1;}/* 将串口设置为原有属性 */if(tcsetattr(attr->fd,TCSANOW,&(attr->OldTermios))){printf("%s,Set old options failed:%s\n",__func__,strerror(errno));return -2;}close(attr->fd);free(attr);return 0;
}

3.2 串口的初始化

在这里插入图片描述
根据思路来写函数

ComportInit.h

#ifndef  _COMPORTINIT_H_
#define  _COMPORTINIT_H_#include "ComportOpen.h"
#include <string.h>int comport_init(MyAttr *attr);#endif   /* ----- #ifndef _COMPORTINIT_H_  ----- */

因为我将串口设置的各项参数都进行了封装,所以函数的参数只用传一个结构体指针或者传结构体地址即可。

ComportInit.c

/**********************************************************************************      Copyright:  (C) 2020 LuXiaoyang<920916829@qq.com>*                  All rights reserved.**       Filename:  ComportInit.c*    Description:  This file is Init COm Port*                 *        Version:  1.0.0(03/07/20)*         Author:  LuXiaoyang <920916829@qq.com>*      ChangeLog:  1, Release initial version on "03/07/20 17:50:09"* *      blog address:https://blog.csdn.net/weixin_45121946        *   ********************************************************************************/
#include "ComportInit.h"int comport_init(MyAttr *attr)
{int                   retval;char                  baudrate[32] = {0};struct termios        NewTermios;memset(&NewTermios,0,sizeof(struct termios));memset(&(attr->OldTermios),0,sizeof(struct termios));if(!attr){printf("Invalid parameter.\n");return -1;}if(tcgetattr(attr->fd,&(attr->OldTermios))){printf("%s,Get termios to OldTermios failure:%s\n",__func__,strerror(errno));return -2;}if(tcgetattr(attr->fd,&NewTermios)){    printf("%s,Get termios to NewTermios failure:%s\n",__func__,strerror(errno));return -3;}  /* 修改控制模式,保证程序不会占用串口 */NewTermios.c_cflag |= CLOCAL;/*  For example:*   *      c_cflag:   0 0 0 0 1 0 0 0*      CLOCAL:  | 0 0 0 1 0 0 0 0*              --------------------*                 0 0 0 1 1 0 0 0*                *  Finally:**     c_flag = 0 0 0 1 1 0 0 0;** *//* 启动接收器,能够从串口中读取输入数据 */NewTermios.c_cflag |= CREAD;/*  CSIZE字符大小掩码,将与设置databits相关的标致位置零 */NewTermios.c_cflag &= ~CSIZE;/*  For example:**      CSIZE = 0 1 1 1 0 0 0 0 ---> ~CSIZE = 1 0 0 0 1 1 1 1**      c_cflag:    0 0 1 0 1 1 0 0*      ~CSIZE:  &  1 0 0 0 1 1 1 1     *              -----------------------*                  0 0 0 0 1 1 0 0** Finally:**     c_cflag = 0 0 0 0 1 1 00** */NewTermios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);/* * ICANON: 标准模式* ECHO: 回显所输入的字符* ECHOE: 如果同时设置了ICANON标志,ERASE字符删除前一个所输入的字符,WERASE删除前一个输入的单词* ISIG: 当接收到INTR/QUIT/SUSP/DSUSP字符,生成一个相应的信号** */NewTermios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);/* * BRKINT: BREAK将会丢弃输入和输出队列中的数据(flush),并且如果终端为前台进程组的控制终端,则BREAK将会产生一个SIGINT信号发送到这个前台进程组* ICRNL: 将输入中的CR转换为NL* INPCK: 允许奇偶校验* ISTRIP: 剥离第8个bits* IXON: 允许输出端的XON/XOF流控** *//* OPOST: 表示处理后输出,按照原始数据输出 */ NewTermios.c_oflag &= ~(OPOST);if(attr->BaudRate){sprintf(baudrate,"B%d",attr->BaudRate);cfsetispeed(&NewTermios,(int)baudrate); //设置输入输出波特率cfsetospeed(&NewTermios,(int)baudrate);}else {cfsetispeed(&NewTermios,B115200);cfsetospeed(&NewTermios,B115200);}/* 设置数据位 */switch(attr->DataBits){case '5':NewTermios.c_cflag |= CS5;break;case '6':NewTermios.c_cflag |= CS6;break;case '7':NewTermios.c_cflag |= CS7;break;case '8':NewTermios.c_cflag |= CS8;break;default:NewTermios.c_cflag |= CS8;  //默认数据位为8break;}/* 设置校验方式 */switch(attr->Parity){/* 无校验 */case 'n':case 'N':NewTermios.c_cflag &= ~PARENB;NewTermios.c_iflag &= ~INPCK;break;/* 偶校验 */case 'e':case 'E':NewTermios.c_cflag |= PARENB;NewTermios.c_cflag &= ~PARODD;NewTermios.c_iflag |= INPCK;break;/* 奇校验 */case 'o':case 'O':NewTermios.c_cflag |= PARENB;NewTermios.c_cflag |= PARODD;NewTermios.c_iflag |= INPCK;/* 设置为空格 */case 's':case 'S':NewTermios.c_cflag &= ~PARENB;NewTermios.c_cflag &= ~CSTOPB;/* 默认无校验 */default:NewTermios.c_cflag &= ~PARENB;NewTermios.c_iflag &= ~INPCK;break;}/* 设置停止位 */switch(attr->StopBits){case '1':NewTermios.c_cflag &= ~CSTOPB;break;case '2':NewTermios.c_cflag |= CSTOPB;break;default:NewTermios.c_cflag &= ~CSTOPB;break;}NewTermios.c_cc[VTIME] = 0;  //最长等待时间NewTermios.c_cc[VMIN] = 0;  //最小接收字符 attr->mSend_Len = 128;  //若命令长度大于mSend_Len,则每次最多发送为mSend_Lenif(tcflush(attr->fd,TCIFLUSH)){printf("%s,Failed to clear the cache:%s\n",__func__,strerror(errno));return -4;}if(tcsetattr(attr->fd,TCSANOW,&NewTermios) != 0){printf("%s,tcsetattr failure:%s\n",__func__,strerror(errno));return -5;}printf("Comport Init Successfully......\n");return 0;}

3.3 AT指令的发送及串口数据的接收

和串口通信其实就是write 和read,通过获取到的文件描述符,在加上一些串口所特有的属性,从而完成通信。
发送:
在这里插入图片描述
这里要注意了,我在前面一篇博客总结说明了AT指令集发送的实质,例如,当我们发送AT时,其实是发送了" AT\r ",所以,当我们获取到要发送的指令时,需要在指令的最后面加上一个 \r(CR) ,串口才能接收到信息,后面的讨论会提到一个问题。
接收的程序较为简单,这里就直接贴代码了。

ComportSwap.h

#ifndef  _COMPORTSWAP_H_
#define  _COMPORTSWAP_H_#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "ComportOpen.h"int comport_send(MyAttr *attr,char *sbuf,int sbuf_len);
int comport_recv(MyAttr *attr,char *rbuf,int rbuf_len,int timeout);#endif   /* ----- #ifndef _COMPORTSWAP_H_  ----- */

ComportSwap.c

/**********************************************************************************      Copyright:  (C) 2020 LuXiaoyang<920916829@qq.com>*                  All rights reserved.**       Filename:  ComporSwap.c*    Description:  This file is communicate with com port*                 *        Version:  1.0.0(03/07/20)*         Author:  LuXiaoyang <920916829@qq.com>*      ChangeLog:  1, Release initial version on "03/07/20 17:50:09"* *      blog address:https://blog.csdn.net/weixin_45121946        *   ********************************************************************************/
#include "ComportSwap.h"int comport_send(MyAttr *attr,char *sbuf,int sbuf_len)
{char     *ptr,*end;int       retval;if(!attr || !sbuf || sbuf_len <= 0){printf("%s,Invalid parameter.\n",__func__);return -1;}if(sbuf_len > attr->mSend_Len){ptr = sbuf;end = sbuf + sbuf_len;do{if(attr->mSend_Len < (end - ptr)){retval = write(attr->fd,ptr,attr->mSend_Len);if(retval <= 0 || retval != attr->mSend_Len){printf("Write to com port[%d] failed:%s\n",attr->fd,strerror(errno));return -2;}ptr += attr->mSend_Len;}else {retval = write(attr->fd,ptr,(end - ptr));if(retval <= 0 || retval != (end - ptr)){printf("Write to com port[%d] failed:%s\n",attr->fd,strerror(errno));return -3;}ptr += (end - ptr);}}while(end > ptr);}  else {  retval = write(attr->fd,sbuf,sbuf_len);if(retval <= 0 || retval != sbuf_len){printf("Write to com port[[%d] failed:%s\n",attr->fd,strerror(errno));return -4;}}  return retval;
}      int comport_recv(MyAttr *attr,char *rbuf,int rbuf_len,int timeout)
{      int                   retval;fd_set                rset;struct timeval        time_out;if(!rbuf || rbuf_len <= 0){  printf("%s,Invalid parameter.\n",__func__);return -1;}  if(timeout) //指定延时等待{    time_out.tv_sec = (time_t)(timeout / 1000);time_out.tv_usec = 0;FD_ZERO(&rset);FD_SET(attr->fd,&rset);retval = select(attr->fd + 1,&rset,NULL,NULL,&time_out);if(retval < 0){printf("%s,Select failed:%s\n",strerror(errno));return -2;}else if(0 == retval){printf("Time Out.\n");return 0;}}usleep(1000);retval = read(attr->fd,rbuf,rbuf_len);if( retval <= 0){printf("%s,Read failed:%s\n",__func__,strerror(errno));return -3;}return retval;}     

3.4 主程序

接下来就是写主程序了,因为要不断和串口通信,所以应该使用一个while循环,从标准输入获取命令,加上\r 发送,同时还要读fd,所以这里采用select多路复用来实现监听标准输入与用于与串口通信的fd。

在这里插入图片描述
comport.c

/**********************************************************************************      Copyright:  (C) 2020 LuXiaoyang<920916829@qq.com>*                  All rights reserved.**       Filename:  comport.c*    Description:  This file *                 *        Version:  1.0.0(04/07/20)*         Author:  LuXiaoyang <920916829@qq.com>*      ChangeLog:  1, Release initial version on "04/07/20 03:02:28"*                 ********************************************************************************/
#include <stdlib.h>
#include <signal.h>
#include <getopt.h>
#include "ComportOpen.h"
#include "ComportInit.h"
#include "ComportSwap.h"int g_stop = 0;void sig_handler(int sig_num)
{if(sig_num == SIGINT)g_stop = 1;
}void adjust_buf(char* buf);
void help_information();int main(int argc, char *argv[])
{int              retval;int              ch;char             sbuf[128] = {0};char             rbuf[128] = {0};fd_set           rset;MyAttr*          attr = NULL;struct option    options[] = {{"help",no_argument,NULL,'h'},{"baudrate",required_argument,NULL,'b'},{"databits",required_argument,NULL,'d'},{"parity",required_argument,NULL,'p'},{"stopbits",required_argument,NULL,'s'},{"name",required_argument,NULL,'n'},{NULL,0,NULL,0}};attr = (MyAttr*)malloc(sizeof(MyAttr));memset(attr,0,sizeof(MyAttr));while((ch = getopt_long(argc,argv,"hb:d:p:s:n:",options,NULL)) != -1){switch(ch){case 'h':help_information();return 0;case 'b':attr->BaudRate = atoi(optarg);break;case 'd':attr->DataBits = atoi(optarg);break;case 'p':attr->Parity = optarg[0];break;case 's':attr->StopBits = atoi(optarg);break;case 'n':strncpy(attr->SerialName,optarg,SERIALNAME_LEN);break;}}if(strlen(attr->SerialName) == 0){printf("Parameter warning:\n");printf("\tAt least need to enter the serial port name,You can specify the serial port name with -n.\n");return 0;}if(comport_open(attr) != 0){printf("Open %s failed!\n",attr->SerialName);return -1;}retval = comport_init(attr);if(retval < 0)goto cleanup;signal(SIGINT,sig_handler);fflush(stdin);printf("Start to communicate with com port......\n");while(!g_stop){FD_ZERO(&rset);FD_SET(STDIN_FILENO,&rset);FD_SET(attr->fd,&rset);/*  使用多路复用监听标准输入和串口fd */retval = select(attr->fd + 1,&rset,NULL,NULL,NULL);if(retval < 0){printf("Program exit......\n");break;}if(retval == 0){printf("Time Out.\n");goto cleanup;}if(FD_ISSET(STDIN_FILENO,&rset)){memset(sbuf,0,sizeof(sbuf));/* 从标准输入读取命令 */fgets(sbuf,sizeof(sbuf),stdin);/* 处理要发送的数据 */  adjust_buf(sbuf);if(comport_send(attr,sbuf,strlen(sbuf)) < 0){printf("Write failed.\n");goto cleanup;}fflush(stdin);}if(FD_ISSET(attr->fd,&rset)){memset(rbuf,0,sizeof(rbuf));retval = comport_recv(attr,rbuf,sizeof(rbuf),0);if(retval <= 0){printf("Read failed:%s\n",strerror(errno));break;}printf("%s",rbuf);fflush(stdout);}}cleanup:comport_close(attr);return 0;}void adjust_buf(char *buf)
{int i = strlen(buf);strcpy(&buf[i-1],"\r");
}void help_information()
{printf("\t-b   Set BaudRate\n");printf("\t-d   Set Databits\n");printf("\t-p   Set Parity,0 for no parity,1 for Odd parity,2 for Evev parity\n");printf("\t-s   Set StopBits\n");printf("\t-n   Set the name of the serial port you want to use\n");printf("\t     Ctrl + c to exit the program\n");printf("\n\tIf you do not specify parameters,The default parameters of the program are as follows:\n");printf("\tBaudRate: 1115200\n\tDatabits: 8bits\n\tParity:   no parity\n\tStopBits: 1bits\n");
}

makefile

(CC) = gcccomport: comport.c ComportOpen.o ComportInit.o ComportSwap.o ComportSwap.o$(CC) comport.c ComportOpen.o ComportInit.o ComportSwap.o -o comport -Werror -WallComportOpen.o: ComportOpen.c$(CC) -c ComportOpen.cComportInit.o: ComportInit.c$(CC) -c ComportInit.cComportSwap.o: ComportSwap.h$(CC) -c ComportSwap.cclear:rm *.o comport

四. 运行截图

在这里插入图片描述
help_msg:
在这里插入图片描述
通过参数传入设置:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五. 讨论

  1. 主程序中为了让数据成功发送,我使用了一个 adjust_buf的函数,其目的实在命令尾部加上一个 \r ,保证串口可以正常接收,可是,当我们从标准输入输入完成后,会敲 Enter 键,这时,其实是把 \n(亲测)一并加到了要发送的buf中,而c_oflag中有一个功能就是将输入的换行符全部替换成 \r (CR),不过我做过尝试还是无法完成指令的发送,才发现他把吧\n 转换成了 \r\n,也就是<CR><LF>,有没有其他方法呢?
  2. 就目前,程序还不能直接实现发送短信这一功能,关于Ctrl+Z发送短信这一指令还正在研究,将会持续更新代码,如果想完成收发短信,定时发送短信,查看信息并解析获取有用信息,可以修改comport.c文件,在了解AT指令是如何发短信后,直接将要发送给串口的命令写进程序里,像串口发送要发短信的几条命令,是可以实现短信发送的。

参考:
https://blog.csdn.net/weixin_45121946/article/details/107032711
https://blog.csdn.net/onion_lwl/article/details/81293266
https://blog.csdn.net/morixinguan/article/details/80898172
https://blog.csdn.net/wumenglu1018/article/details/53098794/

2020.7.5 持续更新…

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Java完成1~50的累加和计算

    实现累加,即使用循环嵌套函数即可,此处声明一个static函数来完成这项工作,使用if语句判断当前值是否小于1,小于则停止计算。实现代码如下: /** To change this license header, choose License Headers in Project Properties.* To change this template file, choose Too…...

    2024/5/8 12:37:02
  2. git 国外镜像下载慢的解决方案

    git clone https://gitclone.com/github.com/xxx/yyy.git 加速clone。比如: threejs的github地址是:https://github.com/mrdoob/three.js.git 在终端里输入:git clone https://gitclone.com/github.com/mrdoob/three.js.git...

    2024/4/16 10:48:13
  3. JS笔记(五)_JS闭包

    JS闭包是一个绕不过去的知识点,这里主要是为了记一下闭包相关的知识点,以及闭包的简单实现和原理1.作用域、作用域链参照《JS高级程序设计》这本书中(PS:对比了一下犀牛书与这本书的关于闭包的解释,个人觉得JS高程的阐述更加容易理解,不喜勿喷):<--“执行环境”是JS中…...

    2024/5/8 11:43:41
  4. Adnan and the Burned drivers

    题目链接:Adnan and the Burned drivers显然维护正反字符串的哈希值,那么直接判断即可。 由于有修改,所以用线段树维护。AC代码: #pragma GCC optimize("-Ofast","-funroll-all-loops") #include<bits/stdc++.h> #define int long long using na…...

    2024/4/16 10:49:30
  5. C++常见面试题(九)——派生类指针赋值给基类指针问题

    在C++继承中,很容易遇到一个问题,那就是将派生类指针赋值给基类指针(向上转型)的情况,下面我们就来举例分析:举一个多继承的例子:#include <iostream> using namespace std;//基类A class A { public:A(int a); public:void display(); protected:int m_a; }; A::A(…...

    2024/4/16 10:48:28
  6. 解决element-ui的时间选择器选择的时间传入后端有时区问题和时间异常的问题

    解决element-ui的时间选择器选择的时间传入后端有时区问题和时间异常的问题**异常说明****解决方法****效果说明** 异常说明 前端页面选择的时间为: 2020-07-28 00:00:00 element-ui传入后端的数据为 2020-07-27T16:00:00:000Z,存在时区问题,并且有时候传输到后台的日和前端选…...

    2024/4/16 10:49:35
  7. Go 命令行参数基本使用

    命令行参数基本使用看一个需求我们希望能够获取到命令行输入的各种参数,该如何处理? 如图:=> 命令行参数基本介绍os.Args 是一个 string 的切片,用来存储所有的命令行参数演示案例:请编写一段代码,可以获取命令行各个参数package main import ("fmt""o…...

    2024/4/16 10:48:59
  8. 微服务之Nacos+GateWay

    Nacos的下载和使用请参考官网文档: https://github.com/alibaba/spring-cloud-alibaba/wiki 项目代码地址: https://gitee.com/yuld/springcloudalibaba.git 一 相关技术1 Nacos Discovery 服务注册发现 2 Nacos Config 配置中心 3 SpringCloud GateWay 网关 4 SpringCloud Ope…...

    2024/4/16 10:48:18
  9. Java-Iterator遍历

    1.1 代码 List<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); Iterator iterator = list.iterator(); while (iterator.hasNext()){System.out.println(iterator.next()); }1.2 程序执行结果...

    2024/4/20 5:54:30
  10. Error creating bean with name ‘bootstrapper‘: Unsatisfied dependency expressed through field ‘identi

    之前新建了一个数据库表,启动flowable-ui-idm等模块过程中报错,把新建表删除了,还是报错Error creating bean with name bootstrapper: Unsatisfied dependency expressed through field identi新建了一个新的数据库,在flowable中配置为新数据库启动,不再报错。...

    2024/5/6 11:27:04
  11. Unable to locate package tree问题解决

    apt-get install tree时Unable to locate package tree 使用sudo apt-get update 再进行apt-get install tree...

    2024/4/20 16:49:47
  12. 长沙VR 丨云图正在慢慢的改变城市!

    移动互联网的高速发展,其背后近万亿元的市场规模更是直接引来各路资本的追逐,但随着市场不断扩大,用户需求不断提升,领域也在不断细分。这其中,接入VR技术的表现得尤为突出。VR行业的发展,将很多行业带来了新的机遇,除了我们所知道的VR游戏、VR电影等,VR正在渐渐的融入…...

    2024/4/18 11:31:36
  13. mac上安装virtualenv使用虚拟环境

    在使用Django时,听从大神的意见使用了虚拟环境来搭建Django框架,这样可以避免项目使用的不同版本影响到系统上安装的版本使用pip install virtualenv来安装虚拟环境Jason-MacBook-Pro:python虚拟环境 wangying$ pip install virtualenv Looking in indexes: http://mirrors.a…...

    2024/4/16 10:50:06
  14. 深度学习网络模型可视化netron

    很多时候,复现人家工程的时候,需要了解人家的网络结构。但不同框架之间可视化网络层方法不一样,这样给研究人员造成了很大的困扰。 前段时间,发现了一个可视化模型结构的神奇:Netron...

    2024/4/26 18:37:07
  15. CDH5.3.6在centos6.5上集群安装测试步骤

    0、下载 CDH 组件环境 http://archive.cloudera.com/cdh5/cdh/5/jdk-7u79-linux-x64.tar.gz http://archive.cloudera.com/cdh5/cdh/5/hadoop-2.5.0-cdh5.3.6.tar.gz http://archive.cloudera.com/cdh5/cdh/5/hive-0.13.1-cdh5.3.6.tar.gz http://archive.cloudera.com/cdh5/cd…...

    2024/4/16 10:50:16
  16. [Leetcode][第44题][JAVA][通配符匹配][贪心][动态规划]

    【问题描述】[困难]【解答思路】1. 动态规划 第 1 步:设计状态 dp[i][j]dp[i][j] 表示字符串 ss 的前 ii 个字符和模式 pp 的前 jj 个字符是否能匹配 第 2 步:状态转移方程第 3 步:考虑初始化 boolean[][] dp = new boolean[m + 1][n + 1];第 4 步:考虑输出 dp[m][n];时间复…...

    2024/4/20 5:43:02
  17. SylixOS 大型操作系统 配置网络

    SylixOS 大型操作系统 配置网络 临时配置配置过程 配置 IP地址 ifconfig en1 inet 192.168.7.100 配置 子网掩码 ifconfig en1 netmask 255.255.255.0配置 默认网关 ifconfig en1 gateway 192.168.7.1查看 网卡信息 ifconfig en1重启机器后,网卡信息失效,所以需要下方永久配置…...

    2024/5/6 21:16:25
  18. 运行时数据区域—方法区

    一、方法区概述 以Person person = new Person()为例,看一下栈、堆、方法区(元空间)之间的关系《Java虚拟机规范》中明确说明:‘尽管所有的方法区在逻辑上属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。’但对于HotSpot而言,方法区还有一个别…...

    2024/5/7 6:08:58
  19. 【消息中间件】RabbitMQ入门基础篇

    一、消息通信模型生产者创建消息,消费者接收这些消息。消息的媒介为建立在真实TCP连接上的虚拟信道(channel)。二、什么是信道?为什么要建立信道?发布消息到RabbitMQ,首先需要先连接到RabbitMQ,才能消费或发布消息。此时,在应用程序和RabbitMQ代理服务器之间创建一条TCP连…...

    2024/4/20 16:17:59
  20. wordpress主题Vieu主题V4.5

    wordpress主题Vieu主题V4.5无授权无限制版 WordPress主题vieu基于Dux主题二次开发!的一款专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。适用范围:wordpress主题、WordPress博客主题 地址:https://www.piaodoo.com/10359.html...

    2024/4/18 7:32:04

最新文章

  1. Google Earth Engine谷歌地球引擎计算遥感影像在每个8天间隔内的多年平均值

    本文介绍在谷歌地球引擎&#xff08;Google Earth Engine&#xff0c;GEE&#xff09;中&#xff0c;求取多年时间中&#xff0c;遥感影像在每1个8天时间间隔内的多年平均值的方法。 本文是谷歌地球引擎&#xff08;Google Earth Engine&#xff0c;GEE&#xff09;系列教学文章…...

    2024/5/9 2:04:45
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. 基于单片机的数字万用表设计

    **单片机设计介绍&#xff0c;基于单片机的数字万用表设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的数字万用表设计概要是关于使用单片机技术来实现数字万用表功能的一种设计方案。下面将详细概述该设计的各个…...

    2024/5/8 7:24:20
  4. 02 OSI和TCP/IP参考模型

    OSI参考模型优点&#xff1a; 1. 分层结构&#xff1a;OSI参考模型将网络通信划分为七个不同的层次&#xff0c;每个层次都有特定的功能和责任。这样的分层结构使得网络通信变得模块化&#xff0c;易于理解、设计和维护。 2. 标准化&#xff1a;OSI参考模型的制定依据了通信领…...

    2024/5/7 10:05:52
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/8 6:01:22
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/7 9:45:25
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/7 14:25:14
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/7 11:36:39
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/8 20:48:49
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/7 9:26:26
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/8 19:33:07
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/8 20:38:49
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/6 21:42:42
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57