linux c 串口 调用命令,Linux系统C语言串口收发
Linux系统C语言串口收发
Linux系统对串口提供了很好的支持,使我们很容易就能用C语言编写出串口收发程序。
先简单说明一下编写串口收发程序前的准备工作。首先串口收发需要有硬件上的串口,在Linux系统中串口是以ttySn(如ttyS0对应串口1,ttyS1对应串口2)文件的形式存放于/dev目录下的,因此我们会看到程序中将串口设备定义为char
*dev = "/dev/ttyS6";
。但是现在的笔记本电脑已经不再带有9针串口,因此我们需要一个USB转串口的工具。U转串的工具在Linux系统下会被识别成ttyUSBn文件,同样存在于/dev目录下。比如我虚拟机的Linux系统只连接了一个U转串,则/dev目录下就多出了一个ttyUSB0文件。
有了硬件的支持,我们还需要使用现有的工具测试一下,以便确定出问题时是我们的程序不行还是硬件不行。minicom是Linux系统下常用的串口工具,可以通过
sudo apt-get install minicom
命令安装(操作串口最好在root权限下,否则可能会提示无法打开串口)。安装完后输入
minicom -s
命令配置串口。需要配置Serial port setup选项中的Serial
Device为我们已有的串口,我的是ttyUSB0,因此这一项为
A - Serial
Device :
/dev/ttyUSB0
然后是波特率,我用115200,8位数据位,无奇偶校验,1位停止位,因此为
E - Bps/Par/Bits : 115200 8N1
之后去掉硬件流控(这个一般不需要)
F - Hardware Flow Control : No
然后保存退出即可
Save setup as dfl
输入minicom即可打开minicom,按ctrl+A,然后按Z可打开帮助菜单。如果出现
minicom: cannot open /dev/ttyUSB0:
没有那个文件或目录
而/dev目录下确实有ttyUSB0这个文件的话,对不起,重启Linux系统吧,重要提示,如果使用minicom时强制退出了,或运行自己写的程序时强制退出,而没有关闭串口,就可能出现串口无法使用的情况,这时可以看看/var/lock目录下是否有对应的lock文件,有就删了再试试,再不行就重启系统吧。如果你发现了不用重启就能解决的办法,非常欢迎能够教教我。
串口可以正常使用后就可以编写程序了!
***********************************************************
首先需要包含头文件
#include
#include
#include
#include
#include
#include
#include
#include
#include
然后是对串口的设置,串口的设置主要是设置 struct termios
结构体的各成员值,建议先保存下原有配置,然后全部清零,根据自己的需要再配置,这么做对初学者比较靠谱,不然折腾来折腾去很浪费时间和感情。配置函数如下
//serial port set function
void setTermios(struct termios *pNewtio, unsigned
int uBaudRate)
{
bzero(pNewtio,sizeof(struct
termios)); //清零所有
pNewtio->c_cflag =
uBaudRate|CS8|CREAD|CLOCAL; //设置波特率、数据位数8位
pNewtio->c_iflag = IGNPAR;
//无奇偶校验
pNewtio->c_oflag =
0;
pNewtio->c_lflag =
0;
pNewtio->c_cc[VINTR] =
0;
pNewtio->c_cc[VQUIT] =
0;
pNewtio->c_cc[VERASE] =
0;
pNewtio->c_cc[VKILL] =
0;
pNewtio->c_cc[VEOF] =
0;
pNewtio->c_cc[VTIME] =
1;
pNewtio->c_cc[VMIN] =
0;
pNewtio->c_cc[VSWTC] =
0;
pNewtio->c_cc[VSTART] =
0;
pNewtio->c_cc[VSTOP] =
0;
pNewtio->c_cc[VSUSP] =
0;
pNewtio->c_cc[VEOL] =
0;
pNewtio->c_cc[VREPRINT] =
0;
pNewtio->c_cc[VDISCARD] =
0;
pNewtio->c_cc[VWERASE] =
0;
pNewtio->c_cc[VLNEXT] =
0;
pNewtio->c_cc[VEOL2] =
0;
}
具体每一项的解释百度百科里有中文的
这里有英文的
打开串口是通过使用标准的文件打开函数操作的
int fd;
char *dev = "/dev/ttyUSB0";
if((fd=open(dev,O_RDWR|O_NOCTTY|O_NDELAY))<0)
{
printf("Can't open serial
port!\n");
return -1;
}
打开后就可以调用上面的函数设置串口了
struct termios oldtio,newtio; //一个用来保存原有的配置,一个用来设置新的
tcgetattr(fd,&oldtio); //保存原有的
setTermios(&newtio,B115200); //调用配置函数
tcflush(fd,TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio); //设置新的
读串口和读文件是一样的
read_byte = read(fd,buffer,512);
if(read_byte>0) //读到了数据
{
printf("read
length=%d\n",read_byte);
buffer[read_byte]='\0';
printf("%s\n",buffer);
}
发送也和接收一样简单
for(i=0;i
{
nCount =
write(fd,send_data,strlen(send_data));
printf("send data OK!count=%d
times=%d\n",nCount, i+1);
sleep(1);
}
这里有个sleep(1),是用来延时1秒的,同样后面的usleep(100000)是延时100000us,即100毫秒。如果是循环接收的话就需要在两次接收之间延时一小会了。
操作完了别忘了把设置改回去,关掉串口
tcsetattr(fd,TCSANOW,&oldtio);
close(fd);
下面是完整的代码,将发送和接收写在一块了,先发后接。
#include
#include
#include
#include
#include
#include
#include
#include
#include
//serial port set function
void setTermios(struct termios *pNewtio, unsigned
int uBaudRate)
{
bzero(pNewtio,sizeof(struct
termios));
pNewtio->c_cflag =
uBaudRate|CS8|CREAD|CLOCAL;
pNewtio->c_iflag = IGNPAR;
//无奇偶校验
pNewtio->c_oflag =
0;
pNewtio->c_lflag =
0;
pNewtio->c_cc[VINTR] =
0;
pNewtio->c_cc[VQUIT] =
0;
pNewtio->c_cc[VERASE] =
0;
pNewtio->c_cc[VKILL] =
0;
pNewtio->c_cc[VEOF] =
0;
pNewtio->c_cc[VTIME] =
1;
pNewtio->c_cc[VMIN] =
0;
pNewtio->c_cc[VSWTC] =
0;
pNewtio->c_cc[VSTART] =
0;
pNewtio->c_cc[VSTOP] =
0;
pNewtio->c_cc[VSUSP] =
0;
pNewtio->c_cc[VEOL] =
0;
pNewtio->c_cc[VREPRINT] =
0;
pNewtio->c_cc[VDISCARD] =
0;
pNewtio->c_cc[VWERASE] =
0;
pNewtio->c_cc[VLNEXT] =
0;
pNewtio->c_cc[VEOL2] =
0;
}
int main(int argc,char **argv)
{
int fd;
int nCount,nTotal;
int send_times = 5;
int i,j,m;
int read_byte = 0;
char buffer[512];
char *send_data="test123";
struct termios oldtio,newtio;
char *dev = "/dev/ttyUSB0";
if((fd=open(dev,O_RDWR|O_NOCTTY|O_NDELAY))<0)
{
printf("Can't open serial port!\n");
return -1;
}
tcgetattr(fd,&oldtio);
setTermios(&newtio,B115200);
tcflush(fd,TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
//Send data
for(i=0;i
{
nCount =
write(fd,send_data,strlen(send_data));
printf("send data OK!count=%d
times=%d\n",nCount, i+1);
sleep(1);
}
//receive data
for(j=0;j<100;j++)
{
read_byte = read(fd,buffer,512);
if(read_byte>0)
{
printf("read length=%d\n",read_byte);
buffer[read_byte]='\0';
printf("%s\n",buffer);
}
usleep(100000);
}
printf("Receive data finished!\n");
tcsetattr(fd,TCSANOW,&oldtio);
close(fd);
return 0;
}
编译完后可正常通信。
Makefile的编写
CC=gcc
uart:uart.c
$(CC) uart.c -o uart
clean:
rm uart
如果程序是在arm中运行,就把
CC=gcc改为交叉编译器,我的是
CC=arm-none-linux-gnueabi-gcc
好了,make一下就可以正常收发数据了。
感谢以下朋友的帮助
2013-8-21 23:12:45
~遥望~
http://blog.sina.com.cn/yaowanglab
linux c 串口 调用命令,Linux系统C语言串口收发相关推荐
- Linux中的uptime命令查看系统运行时间
Linux中的uptime命令查看系统运行时间 uptime:查看系统运行(up)了多长时间 语法如下: uptime会在一行中显示如下信息: 当前时间.系统运行了多长时间.当前登录的用户有多少.前1 ...
- linux如何看udpsocket状态,Linux如何使用ss命令查看系统的socket状态
Linux如何使用ss命令查看系统的socket状态 发布时间:2021-05-08 10:34:54 来源:亿速云 阅读:99 作者:小新 小编给大家分享一下Linux如何使用ss命令查看系统的so ...
- Linux下的tree命令 --Linux下目录树查看
Linux下的tree命令 --Linux下目录树查看 有时我们需要生成目录树结构,可以使用的有ls -R,但是实际效果并不好 这时需要用到tree命令,但是大部分Linux系统是默认不安装该命令的, ...
- linux里面查找替换命令,LINUX 查找替换命令 总结
find /var/ -name "*.php" > /home/tmp 在/var/目录下查找 所有以.php后缀结尾的文件 结果很多,就 > 输出结果到/home ...
- Linux下python的命令,linux下python相关命令
若本机已安装python2,尽量不要动现有的python2,额外安装python3即可. 1.安装python3.6(centos下安装python3自带pip和setuptools) # 安装依赖环 ...
- linux关闭后台运行命令,linux后台运行、关闭、查看后台任务常用命令
一.& 加在一个命令的最后,可以把这个命令放到后台执行,如: [root@bqh-01 ~]# watch -n 3 "sh 1.sh" #每3s在后台执行一次1.sh脚 ...
- linux安装DNS服务命令,linux配置dns服务器配置命令
linux配置dns服务器配置命令 Linux系统的DNS服务器怎么配置,配置命令有哪些?下面跟yjbys小编一起来了解一下吧! 一.实验目的 熟悉Linux系统中DNS服务器的配置方法.理解配置过程 ...
- linux查看双机状态命令,Linux 系统下双机HA的功能实现
在Linux系统上双机功能的实现,对双机软件High-Availability Linux Project的安装.配置.运行以及测试进行说明.1.软件及安装说明本文档描述的Linux-HA软件以及参考 ...
- linux怎么退出tail命令,Linux系统tail命令怎么使用
Linux系统要查看文件末尾内容,显示字节等功能,可以利用tail命令实现,具体怎么操作呢,下面由学习啦小编为大家整理了linux系统中tail命令的使用详解,希望对大家有帮助! linux系统中ta ...
最新文章
- HEAD元素使用集锦
- mysql5.6热升级_mysql 5.6 后热数据的加载
- 【廖雪峰python入门笔记】列表生成式
- destroy 方法_线程方法destroy()和stop(Throwable)在JDK 11中删除
- java物业管理系统设计,JAVA物业管理系统设计与实现(论文+源代码)
- mongodb在aggregate lookup 进行分页查询,获得记录总数
- 002 html总结
- 梯度下降python编程实现_【机器学习】线性回归——单变量梯度下降的实现(Python版)...
- 当程序员写不出代码了,该怎么办?
- Qt Creator 第一个插件
- POST 与GET的不同
- nekohtml+xpath实例,及注意事项
- JSP企业人事管理系统
- 2019年2月10日训练日记
- 两阶段最小二乘法原理_什么是两阶段最小二乘法(2sls)?
- 来了解质量管理工具——质量屋(HOQ)
- 训练集和测试集的分布差距太大有好的处理方法吗?
- 汉语拼音工具包相关实用方法
- 【Verilog】消息码转AMI码的具体Verilog代码实践以及经验分享
- 湖南省邵阳市谷歌高清卫星地图下载