简介

嵌入式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串口编程简介的更多相关文章

  1. 嵌入式linux串口编程(二)

    /*com_writer.c*/#include "uart_api.h" int main(void){ int fd; char buff[BUFFER_SIZE]; if(( ...

  2. storysnail的Linux串口编程笔记

    storysnail的Linux串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据Ge ...

  3. linux串口编程

    按照对linux系统的理解,串口编程的顺序无非就是open,read,write,close,而串口有波特率.数据位等重要参数需要设置,因此还应该用到设置函数,那么接下来就带着这几个问题去学习linu ...

  4. Linux串口编程详解(转)

    串口本身,标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接 ...

  5. 嵌入式linux多进程编程

    嵌入式linux多进程编程 在主程序显示文本菜单.提供例如以下服务.要求每一个服务都通过生成子进程来提供. 服务包含:日历信息显示,日期信息显示,推断闰年服务,文件复制功能,数字排序功能.退出功能. ...

  6. linux串口编程总结

    串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...

  7. linux串口编程参数配置详解(转)

    1.linux串口编程需要的头文件 #include <stdio.h>         //标准输入输出定义#include <stdlib.h>        //标准函数 ...

  8. linux串口编程参数配置详解

    1.linux串口编程需要的头文件 #include <stdio.h>         //标准输入输出定义 #include <stdlib.h>        //标准函 ...

  9. Linux串口编程进阶

    在<Linux串口编程>编程一文中介绍了串口应用中常用的基本操作,如:串口打开关闭.串口设置.数据收发等.本篇文章主要基于常规串口操作进行了扩充,主要介绍如下操作: Linux系统使用非标 ...

随机推荐

  1. es6新增特性总结

    定义 ES6是ECMA为JavaScript制定的第6个标准版本,标准委员会决定,标准在每年6月正式发布并作为当年的正式版本,接下来的时间里就在此版本的基础上进行改动,直到下一年6月草案就自然变成新一 ...

  2. CSRF攻击原理以及防御方法(写的很好)

    转载地址:http://www.phpddt.com/reprint/csrf.html        CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟 ...

  3. python 爬虫,网页转PDF:OSError: No wkhtmltopdf executable found

    解决办法: 代码中设置参数: path_wk = r‘D:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe‘ #wkhtmltopdf安装位置 config ...

  4. 数据可视化之DAX篇(十)在PowerBI中累计求和的两种方式

    https://zhuanlan.zhihu.com/p/64418286 假设有一组数据, 已知每一个产品贡献的利润,如果要计算前几名产品的贡献利润总和,或者每一个产品和利润更高产品的累计贡献占总体 ...

  5. Quartz.Net系列(十四):详解Job中两大特性(DisallowConcurrentExecution、PersistJobDataAfterExecution)

    1.DisallowConcurrentExceution 从字面意思来看也就是不允许并发执行 简单的演示一下 [DisallowConcurrentExecution] public class T ...

  6. Go Pentester - HTTP CLIENTS(2)

    Building an HTTP Client That Interacts with Shodan Shadon(URL:https://www.shodan.io/)  is the world' ...

  7. P2058 海港 (洛谷)

    这个题复制过来真的有点恶心,懒得手打,以后再搬题面吧. 今天我双更了,AC这个题我就完成某谷春令营第一课的作业了(假的) 这个题是个双指针.非常友善.一直往里读入就可以了,遇见不是一条船的乘客输出这一 ...

  8. 一张图就可以完美解决Java面试频次最高、GG最高的题目!快点收藏

    如果要问Java面试频次最高的题目,那么我想应该是HashMap相关了. 提到HahMap,必然会问到是否线程安全?然后牵扯出ConcurrentHashMap等,接着提及1.7和1.8实现上的区分, ...

  9. go : 连接数据库并插入数据

      package main import ( "database/sql" "fmt" "log" "net/http" ...

  10. 《闲扯Redis六》Redis五种数据类型之Hash型

    一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...