简介

嵌入式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. JavaWeb基础(day11)

    HTML HTML是超文本标记语言.HTML就 是普通的文本文件,只不过在文本中的内容如果被一些 特殊的标签进行包裹就有了特殊的含义,这些被那些标签标记文本,就成了超文本. 网页的组成 网页的组成 H ...

  2. 使用wsl2時碰到的問題

    1.啓動wsl系统时出现“参考的对象类型不支持尝试的操作”. 解决方法: netsh winsock reset

  3. 数据可视化实例(七): 计数图(matplotlib,pandas)

    https://datawhalechina.github.io/pms50/#/chapter5/chapter5 计数图 (Counts Plot) 避免点重叠问题的另一个选择是增加点的大小,这取 ...

  4. ArcGIS 10.2安装及卸载教程

    卸载 在控制面板中找到程序->卸载程序 找到ArcGIS的相关软件 这里以ArcGIS 10.2 Destop为例,选中,然后点击卸载,会出现如下界面 选择Remove,然后根据提示进行操作,即 ...

  5. Kafka 是如何管理消费位点的?

    Kafka 是一个高度可扩展的分布式消息系统,在实时事件流和流式处理为中心的架构越来越风靡的今天,它扮演了这个架构中核心存储的角色.从某种角度说,Kafka 可以看成实时版的 Hadoop 系统.Ha ...

  6. Ethical Hacking - GAINING ACCESS(16)

    CLIENT SIDE ATTACKS - Social Engineering Social Engineering Information gathering Tool: Maltego Gath ...

  7. OSCP Learning Notes - WebApp Exploitation(4)

    Local File Inclusion[LFI] Target Pentester Lab: Download from the following website: https://www.vul ...

  8. Ethical Hacking - NETWORK PENETRATION TESTING(3)

    Change MAC Address using macchanger.  Packet Sniffing Basics Airodump-ng airodump-ng is a program pa ...

  9. java基础知识--入门程序说明

    ①main方法:称为主方法,写法格式固定,是程序的入口或起始点,无论我们编写多少程序,JVM在运行的时候,都会从main方法这里开始执行. ②注释:对代码的解释说明.单行注释//.多行注释/* */. ...

  10. JELLY技术周刊 Vol.15 云游戏会是 5G 杀手级应用么?

    蒲公英 · JELLY技术周刊 Vol.15 听到"云游戏",或许我们的第一反应会是"云玩家"而不是那些上云的"游戏",在这个 5G 已来的 ...