嵌入式Linux串口编程简介
简介
嵌入式Linux下串口编程与Linux系统下的编程没有什么区别,系统API都是一样的。嵌入式设备中串口编程是很常用的,比如会对接一些传感器模块,这些模块大多是RS232或者RS485接口,对于软件层面上来说,RS232与RS48区别不大。RS232与RS485在使用上的区别,RS232是全双工的,只能对接一个设备串口设备。RS485是半双工的总线协议,一般可以挂多个传感器设备,半双工的意思是同时只能有一个设备向串口发数据。
用到的API函数
| 函数 | 说明 |
|---|---|
| open | 打开设备,用于打开串口设备 |
| fcntl | 修改设备描述符属性参数 |
| isatty | 检测打开的描述符是否指向一个终端 |
| tcgetattr | 用来获取串口终端参数 |
| cfmakeraw | 将终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理 |
| tcflush | 用于清空输入、输出缓冲区 |
| tcsetattr | 设置串口终端参数 |
| read | 读取数据 |
| write | 写数据 |
| close | 关闭串口设备 |
代码
#include<termios.h>
#include "uart.h"
/***************************************
*name : open_port
*功能描述: 打开串口
*入口参数: 串口号
*返 回 值: 成功返回文件描述符,失败返回负值
*作 者:
*修改时间:
***************************************/
int open_port(const char * com_port)
{
int fd;
if( com_port == NULL ){
printf("the port name is null\n");
return -1;
}
/*open port*/
fd = open(com_port, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd < 0){
fd = open(com_port, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd < 0){
perror("open serial port");
return -1;
}
}
printf("open %s OK!\n", com_port);
if(fcntl(fd, F_SETFL,0) < 0){
perror("fcntl F_SETFL");
}
if(isatty(fd) == 0){
perror("isatty is not a terminal device");
}
return fd;
}
/******************************
*name : set_port
*功能描述: 设置串口参数
*入口参数: fd 文件描述符, baud_rate 波特率, data_bits 数据位,
* parity 奇偶校验, stop_bits 停止位
* 调用示例: set_port(fd, 115200, 8, 'N',1);
*返 回 值: 成功返回0,失败返回-1
*作 者:
*修改:
******************************/
int set_port(int fd, int baud_rate,
int data_bits, char parity, int stop_bits)
{
struct termios new_cfg, old_cfg;
int speed_arry[]= {B2400, B4800, B9600, B19200, B38400,B57600, B115200};
int speed[]={2400,4800,9600,19200,38400,57600,115200};
int i = 0;
/*save and test the serial port*/
if(tcgetattr(fd, &old_cfg) < 0){
perror("tcgetattr");
return -1;
}
if(fcntl(fd,F_SETFL,0) < 0)//恢复为阻塞模式
{
perror("fcntl(CzjFd,F_SETFL,0)!");
}
new_cfg = old_cfg;
cfmakeraw(&new_cfg); //配置为原来配置
new_cfg.c_cflag &= ~ CSIZE; //用数据位掩码清空数据位的设置
/*set baud_rate*/
for(i = sizeof(speed_arry) / sizeof(speed_arry[0]); i > 0; i--)
{
if(baud_rate == speed[i]){
cfsetispeed(&new_cfg,speed_arry[i]);
cfsetospeed(&new_cfg,speed_arry[i]);
}
}
switch(data_bits) /*设置数据位*/
{
case 7:
new_cfg.c_cflag |= CS7;
break;
default:
case 8:
new_cfg.c_cflag |= CS8;
break;
}
switch(parity)
{
default:
case 'N':
case 'n':
{
new_cfg.c_cflag &= ~PARENB; //清除校验位
new_cfg.c_iflag &= ~(ICRNL|INPCK|IXON|IXOFF); //关闭奇偶校验 关闭软件流控
break;
}
case 'o':
case 'O':
{
new_cfg.c_cflag |= (PARODD | PARENB); //使用奇校验不是用偶校验
new_cfg.c_iflag |= INPCK;
break;
}
case 'e':
case 'E':
{
new_cfg.c_cflag |= PARENB;
new_cfg.c_cflag &= ~PARODD; //使用偶校验
new_cfg.c_iflag |= INPCK;
break;
}
case 's':
case 'S':
{
new_cfg.c_cflag &= ~PARENB;
new_cfg.c_cflag &= ~CSTOPB;
break;
}
}
new_cfg.c_iflag &= ~(ICRNL| IXON | IXOFF ); //关闭奇偶校验 关闭软件流控
new_cfg.c_oflag &= ~OPOST;
switch(stop_bits)
{
default:
case 1:
{
new_cfg.c_cflag &= ~CSTOPB;
new_cfg.c_cflag &= ~CRTSCTS; //禁用硬件流控
//new_cfg.c_cflag |= CRTSCTS; //启用硬件流控
break;
}
case 2:
{
new_cfg.c_cflag |= CSTOPB;
break;
}
}
/*set wait time*/
new_cfg.c_cc[VTIME] = 0;
new_cfg.c_cc[VMIN] = 1;
tcflush(fd, TCIFLUSH); //处理未接收字符
if((tcsetattr(fd, TCSANOW, &new_cfg)) < 0)
{
perror("tcsetattr");
return -1;
}
return 0;
}
调用测试代码:
#include "uart.h"
#include <stdio.h>
#include <unistd.h>
int main()
{
int fd = open_port("/dev/ttyS1");
if ( fd < 0 )
{
perror("open port");
return -1;
}
set_port(fd, 115200, 8, 'N',1);
char readBuf[32] ={0};
const char *pstr="hello world";
write(fd, pstr, strlen(pstr)+1);
read(fd, readBuf, sizeof(readBuf));
close(fd);
}
嵌入式Linux串口编程简介的更多相关文章
- 嵌入式linux串口编程(二)
/*com_writer.c*/#include "uart_api.h" int main(void){ int fd; char buff[BUFFER_SIZE]; if(( ...
- storysnail的Linux串口编程笔记
storysnail的Linux串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据Ge ...
- linux串口编程
按照对linux系统的理解,串口编程的顺序无非就是open,read,write,close,而串口有波特率.数据位等重要参数需要设置,因此还应该用到设置函数,那么接下来就带着这几个问题去学习linu ...
- Linux串口编程详解(转)
串口本身,标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接 ...
- 嵌入式linux多进程编程
嵌入式linux多进程编程 在主程序显示文本菜单.提供例如以下服务.要求每一个服务都通过生成子进程来提供. 服务包含:日历信息显示,日期信息显示,推断闰年服务,文件复制功能,数字排序功能.退出功能. ...
- linux串口编程总结
串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...
- linux串口编程参数配置详解(转)
1.linux串口编程需要的头文件 #include <stdio.h> //标准输入输出定义#include <stdlib.h> //标准函数 ...
- linux串口编程参数配置详解
1.linux串口编程需要的头文件 #include <stdio.h> //标准输入输出定义 #include <stdlib.h> //标准函 ...
- Linux串口编程进阶
在<Linux串口编程>编程一文中介绍了串口应用中常用的基本操作,如:串口打开关闭.串口设置.数据收发等.本篇文章主要基于常规串口操作进行了扩充,主要介绍如下操作: Linux系统使用非标 ...
随机推荐
- nginx反向代理导致session失效的问题处理
一同事求援:后台系统的登录成功了,但不能成功登进系统,仍然跳转到登录页,但同一套代码另一个环境却没有问题. 背景 经了解,他对同一个项目使用tomcat部署了两个环境,一个在开发服务器上,一个在他本机 ...
- bzoj2292【POJ Challenge 】永远挑战*
bzoj2292[POJ Challenge ]永远挑战 题意: 有向图,每条边长度为1或2,求1到n最短路.点数≤100000,边数≤1000000. 题解: 有人说spfa会T,所以我用了dijk ...
- Linux-常见的命令
1.杀掉tomcat进程 ps -ef |grep tomcat kill -9 pid 2.启动http服务 service httpd start 3.停止mysql服务 servi ...
- java的干儿子锁Lock
目录 Lock的由来 线程之间的交互 Lock方法简介 lock() lockInterruptibly() trylock() trylock(long,TimeUnit) unlock() new ...
- scss : div水平垂直居中
scss 是一个很好用的css预处理语言,有很多很好的特性. 比如 mixin. 我们可以像使用函数那样使用mixin. 比如写一个div水平垂直居中. 上代码. @mixin absolute_ce ...
- css:实现文本两行或多行文本溢出显示省略号
div{ display: -webkit-box; -webkit-box-orient: vertical; word-break: break-all; word-wrap: break-wor ...
- 解决nginx在Linux中已经正常启动,Windows端的浏览器却无法访问的问题
一:查看Linux中nginx已经正常启动 二:查看80端口,未被占用 三:检查防火墙的问题 关闭防火墙:chkconfig iptables off //失败 暂时关闭防火墙:service ipt ...
- vue学习(十六) 自定义私有过滤器 ES6字符串新方法 填充字符串
<div id="app"> <p>{{data | formatStr('yyyy-MM-dd')}}</p></div> //s ...
- layui常用插件(二) 时间插件
日期和时间 html <div class="layui-inline"> <!-- 注意:这一层元素并不是必须的 --> <input type=& ...
- 关于android的监听器
import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bu ...