linux下uart应用编程
目的:在用户空间通过读写uart设备文件,控制uart串口发送和接收数据。
在用户空间设置uart波特率、奇偶校验使能等操作是通过termios结构体和termios库函数完毕。须要在应用程序中包括termios.h头文件。
一、termios结构体定义
#define NCCS 17 // 控制字符数组的长度。
struct termios
{
unsigned long c_iflag; // 输入模式标志
unsigned long c_oflag; // 输出模式标志
unsigned long c_cflag; // 控制模式标志
unsigned long c_lflag; // 本地模式标志
unsigned char c_line; // 线路规程(速率)
unsigned char c_cc[NCCS]; // 控制字符数组
};
c_iflag标记參数有:
#define IGNBRK 0000001 // 输入时忽略BREAK 条件
#define BRKINT 0000002 // 假设没有设置IGNBRK,则在BREAK 时产生SIGINT 信号
#define IGNPAR 0000004 // 忽略奇偶校验和帧错误
#define PARMRK 0000010 // 标记奇偶校验错,在INPCK被设置且IGNPAR未被设置时才实用
#define INPCK 0000020 // 使能帧和奇偶校验错误检查
#define ISTRIP 0000040 // 屏蔽字符第8位
#define INLCR 0000100 // 输入时将换行符NL映射成回车符CR
#define IGNCR 0000200 // 忽略回车符CR
#define ICRNL 0000400 // 在输入时将回车符CR 映射成换行符NL
#define IUCLC 0001000 // 在输入时将大写字符转换成小写字符
#define IXON 0002000 // 同意開始/停止(XON/XOFF)输出控制
#define IXANY 0004000 // 同意不论什么字符重新启动输出
#define IXOFF 0010000 // 同意開始/停止(XON/XOFF)输入控制
#define IMAXBEL 0020000 // 输入队列满时响铃
c_oflag标记參数有:
#define OPOST 0000001 // 使能输出处理。 仅仅有这个标记设置了。c_oflag其它的设置才会有效
#define OLCUC 0000002 // 在输出时将小写字符转换成大写字符
#define ONLCR 0000004 // 在输出时将换行符NL 映射成回车-换行符CR-NL
#define OCRNL 0000010 // 在输出时将回车符CR 映射成换行符NL
#define ONOCR 0000020 // 在0列不输出回车符CR
#define ONLRET 0000040 // 换行符NL运行回车符的功能
#define OFILL 0000100 // 延迟时使用填充字符而不使用时间延迟
#define OFDEL 0000200 // 填充字符是ASCII 码DEL。 假设未设置,则使用ASCII NULL
#define NLDLY 0000400 // 选择换行延迟
#define NL0 0000000 // 换行延迟类型0
#define NL1 0000400 // 换行延迟类型1
#define CRDLY 0003000 // 选择回车延迟
#define CR0 0000000 // 回车延迟类型0
#define CR1 0001000 // 回车延迟类型1
#define CR2 0002000 // 回车延迟类型2
#define CR3 0003000 // 回车延迟类型3
#define TABDLY 0014000 // 选择水平制表延迟
#define TAB0 0000000 // 水平制表延迟类型0
#define TAB1 0004000 // 水平制表延迟类型1
#define TAB2 0010000 // 水平制表延迟类型2
#define TAB3 0014000 // 水平制表延迟类型3
#define XTABS 0014000 // 将制表符TAB 换成空格。该值表示空格数
#define BSDLY 0020000 // 选择退格延迟
#define BS0 0000000 // 退格延迟类型0
#define BS1 0020000 // 退格延迟类型1
#define VTDLY 0040000 // 纵向制表延迟
#define VT0 0000000 // 纵向制表延迟类型0
#define VT1 0040000 // 纵向制表延迟类型1
#define FFDLY 0040000 // 选择换页延迟
#define FF0 0000000 // 换页延迟类型0
#define FF1 0040000 // 换页延迟类型1
c_cflag标记參数有:
#define CBAUD 0000017 // 传输速率位屏蔽码
#define B0 0000000 // 挂断线路
#define B50 0000001 // 波特率 50
#define B75 0000002 // 波特率 75
#define B110 0000003 // 波特率 110
#define B134 0000004 // 波特率 134
#define B150 0000005 // 波特率 150
#define B200 0000006 // 波特率 200
#define B300 0000007 // 波特率 300
#define B600 0000010 // 波特率 600
#define B1200 0000011 // 波特率 1200
#define B1800 0000012 // 波特率 1800
#define B2400 0000013 // 波特率 2400
#define B4800 0000014 // 波特率 4800
#define B9600 0000015 // 波特率 9600
#define B19200 0000016 // 波特率 19200
#define B38400 0000017 // 波特率 38400
#define EXTA B19200 // 扩展波特率A
#define EXTB B38400 // 扩展波特率B
#define CSIZE 0000060 // 字符位宽度屏蔽码
#define CS5 0000000 // 每字符5 比特位
#define CS6 0000020 // 每字符6 比特位
#define CS7 0000040 // 每字符7 比特位
#define CS8 0000060 // 每字符8 比特位
#define CSTOPB 0000100 // 设置两个停止位
#define CREAD 0000200 // 字符接收使能。假设没有设置,仍然从port接收字符。可是这些字符都要被丢弃
#define CPARENB 0000400 // 开启输出时产生奇偶位、输入时进行奇偶校验
#define CPARODD 0001000 // 输入/输入校验是奇校验
#define HUPCL 0002000 // 最后进程关闭后挂断
#define CLOCAL 0004000 // 忽略调制解调器(modem)控制线路
#define CIBAUD 03600000 // 输入波特率(未使用)
#define CRTSCTS 020000000000 //流控制
#define PARENB CPARENB // 开启输出时产生奇偶位、输入时进行奇偶校验
#define PARODD CPARODD // 输入/输入校验是奇校验
c_lflag标记參数有:
#define ISIG 0000001 // 当收到字符INTR、QUIT、SUSP 或DSUSP,产生对应的信号
#define ICANON 0000002 // 开启规范模式(熟模式)
#define XCASE 0000004 // 若设置了ICANON,则终端是大写字符的
#define ECHO 0000010 // 回显输入字符
#define ECHOE 0000020 // 若设置了ICANON,则ERASE/WERASE 将擦除前一字符/单词
#define ECHOK 0000040 // 若设置了ICANON。则KILL 字符将擦除当前行
#define ECHONL 0000100 // 如设置了ICANON。则即使ECHO 没有开启也回显NL 字符
#define NOFLSH 0000200 // 当生成SIGINT 和SIGQUIT 信号时不刷新输入输出队列,当生成SIGSUSP 信号时。刷新输入队列
#define TOSTOP 0000400 // 发送SIGTTOU 信号到后台进程的进程组,该后台进程试图写自己的控制终端
#define ECHOCTL 0001000 // 若设置了ECHO,则除TAB、NL、START 和STOP 以外的ASCII控制信号将被回显成象^X 式样。X 值是控制符+0x40
#define ECHOPRT 0002000 // 若设置了ICANON 和IECHO。则字符在擦除时将显示
#define ECHOKE 0004000 // 若设置了ICANON。则KILL 通过擦除行上的全部字符被回显
#define FLUSHO 0010000 // 输出被刷新。通过键入DISCARD 字符,该标志被翻转
#define PENDIN 0040000 // 当下一个字符是读时,输入队列中的全部字符将被重显
#define IEXTEN 0100000 // 开启实现时定义的输入处理
c_line參数有:
#define TIOCM_LE 0x001 // 线路同意(Line Enable)
#define TIOCM_DTR 0x002 // 数据终端就绪(Data Terminal Ready)
#define TIOCM_RTS 0x004 // 请求发送(Request to Send)
#define TIOCM_ST 0x008 // 串行数据发送(Serial Transfer)
#define TIOCM_SR 0x010 // 串行数据接收(Serial Receive)
#define TIOCM_CTS 0x020 // 清除发送(Clear To Send)
#define TIOCM_CAR 0x040 // 载波监測(Carrier Detect)
#define TIOCM_RNG 0x080 // 响铃指示(Ring indicate)
#define TIOCM_DSR 0x100 // 数据设备就绪(Data Set Ready)
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
c_cc[NCCS]数组:
TO-DO
二、termios库函数
1、获取当前的操作模式參数
int tcgetattr (int fd, struct termios *termios_p)
2、使用*termios_p来设置操作模式參数
int tcsetattr (int fd, int optional_actions, struct termios *termios_p)
optional_actions的參数:
#define TCSANOW 0 // 改变马上发生
#define TCSADRAIN 1 // 改变在全部已写的输出被传输之后发生
#define TCSAFLUSH 2 // 改变在全部已写的输出被传输之后而且在全部接收到但还没有读取的数据被丢弃之后发生
3、获得*termios_p中的发送波特率
speed_t cfgetospeed (struct termios *termios_p)
4、获得*termios_p中的接收波特率
speed_t cfgetispeed (struct termios *termios_p)
5、设置*termios_p中的发送波特率
int cfsetospeed (struct termios *termios_p, speed_t speed)
6、设置*termios_p中的接收波特率
int cfsetispeed (struct termios *termios_p, speed_t speed)
7、等待全部输出数据都被发送
int tcdrain (int fd)
8、清空输入/输出缓冲区
int tcflush (int fd, int queue_selector)
queue_selector的參数:
#define TCIFLUSH 0 // 清空输入缓冲区(驱动程序已接收到。但用户程序尚未读取)
#define TCOFLUSH 1 // 清空输出缓冲区(用户程序已经写,但驱动尚未发送)
#define TCIOFLUSH 2 // 清空输入和输出缓冲区
9、对输入输出流进行控制
int tcflow (int fd, int action)
action的參数:
#define TCOOFF 0 // 挂起输出。 #define TCOON 1 // 重新启动被挂起的输出。 #define TCIOFF 2 // 系统传输一个STOP 字符,使设备停止向系统数据传输。
#define TCION 3 // 系统传输一个START 字符,使设备開始向系统数据传输。
10、发送break
int tcsendbreak (int fd, int duration)
在一个指定的时间区间内发送连续的二进位数0。若duration參数为0,则此种发送延续0,25~0.5秒。POSIX.1说明若duration非0。则发送时间依赖于实现。
三、编程实例
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h> #define UART_DEVICE "/dev/ttyPS0" //uart设备文件名称 int main(int argc, char *argv[])
{ int fd, res;
struct termios oldtio, newtio;
char ch;
char buf[256] = {0}; //-----------打开uart设备文件------------------
fd = open(UART_DEVICE, O_RDWR|O_NOCTTY);//没有设置O_NONBLOCK。所以这里read和write是堵塞操作
if (fd < 0) {
perror(UART_DEVICE);
exit(1);
}
else
printf("Open %s successfully\n", UART_DEVICE); //-----------设置操作參数-----------------------
tcgetattr(fd, &oldtio);//获取当前操作模式參数
memset(&newtio, 0, sizeof(newtio)); //波特率=115200 数据位=8 使能数据接收
newtio.c_cflag = B115200|CS8|CLOCAL|CREAD;
newtio.c_iflag = IGNPAR;
//newtio.c_oflag = OPOST | OLCUC; //
/* 设定为正规模式 */
//newtio.c_lflag = ICANON; tcflush(fd, TCIFLUSH);//清空输入缓冲区和输出缓冲区
tcsetattr(fd, TCSANOW, &newtio);//设置新的操作參数 //------------向urat发送数据-------------------
res=write(fd, "\r\nBegin Uart tx", 16);
while(1) {
//从控制台终端获取数据,然后通过uart发送出去,直到接收到! 字符
while((ch=getchar()) != '!') {
buf[0]=ch;
res=write(fd, buf, 1);
} buf[0]=ch;
buf[1]='\n';
res = write(fd, buf, 2);
break;
}
//-------------从uart接收数据-------------------
while(1) {
res = read(fd, buf, 255);//程序将在这里挂起,直到从uart接收到数据(堵塞操作)
if (res == 0)
continue; buf[res] = '\0';
printf("res = %d, buf = %s\n", res, buf);//将uart接收到的字符打印出来
if (buf[0] == '!')//uart接收到! 字符后退出while
break;
}
//------------关闭uart设备文件,恢复原先參数--------
close(fd);
printf("Close %s\n", UART_DEVICE);
tcsetattr(fd, TCSANOW, &oldtio); //恢复原先的设置 return 0;
}
linux下uart应用编程的更多相关文章
- Linux下TCP网络编程与基于Windows下C#socket编程间通信
一.linux下TCP网络编程基础,需要了解相关函数 Socket():用于套接字初始化. Bind():将 socket 与本机上的一个端口绑定,就可以在该端口监听服务请求. Listen():使s ...
- Linux下的C编程实战
Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来, Linu ...
- Linux下C语言编程实现spwd函数
Linux下C语言编程实现spwd函数 介绍 spwd函数 功能:显示当前目录路径 实现:通过编译执行该代码,可在终端中输出当前路径 代码实现 代码链接 代码托管链接:spwd.c 所需结构体.函数. ...
- linux下的c编程
linux下的c编程 Linux 系统上可用的 C 编译器是 GNU C 编译器, 它建立在自由软件基金会的编程许可证的基础上,因此可以自由发布.GNU C 对标准 C 进行一系列扩展,以增强标准 ...
- Linux基础与Linux下C语言编程基础
Linux基础 1 Linux命令 如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 登录Linux后,我们就可以在#或$符后面去输入命令,有 ...
- LINUX下C语言编程基础
实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...
- LINUX下C语言编程调用函数、链接头文件以及库文件
LINUX下C语言编程经常需要链接其他函数,而其他函数一般都放在另外.c文件中,或者打包放在一个库文件里面,我需要在main函数中调用这些函数,主要有如下几种方法: 1.当需要调用函数的个数比较少时, ...
- Linux下C语言编程基础学习记录
VIM的基本使用 LINUX下C语言编程 用gcc命令编译运行C语言文件 预处理阶段:将*.c文件转化为*.i预处理过的C程序. 编译阶段:将*.i文件编译为汇编代码*.s文件. 汇编阶段:将*.s ...
- 【转】Linux基础与Linux下C语言编程基础
原文:https://www.cnblogs.com/huyufeng/p/4841232.html ------------------------------------------------- ...
随机推荐
- LN : leetcode 5 Longest Palindromic Substring
lc 5 Longest Palindromic Substring 5 Longest Palindromic Substring Given a string s, find the longes ...
- python中os模块中文帮助
python中os模块中文帮助 python中os模块中文帮助文档文章分类:Python编程 python中os模块中文帮助文档 翻译者:butalnd 翻译于2010.1.7——2010.1.8 ...
- java.lang.RuntimeException: java.lang.NullPointerException...的错误
先FQ,让电脑能登上谷歌,然后重新安装,应该就好了,我的是这样解决的.如果下次安装又报:java.lang.RuntimeException: java.lang.NullPointerExcepti ...
- java web 学习笔记 - Java Bean
1. Java Bean 是一个简单的 java 类,一般放在WEB-INF下的 classes目录下(如果没有则需要手工新建) 一个简单的Bean包括属性,getter ,setter方法,如果没有 ...
- CPU 的寻址方式
来源https://baike.baidu.com/item/%E5%AF%BB%E5%9D%80%E6%96%B9%E5%BC%8F/3210621?fr=aladdin 寻址方式就是处理器根据指令 ...
- Robot Framework(九) 执行测试用例——基本用法
3.1基本用法 Robot Framework测试用例从命令行执行,默认情况下,最终结果是XML格式的输出文件和HTML 报告和日志.执行后,可以组合输出文件,然后使用rebot工具进行后处理. 3. ...
- HDU6189 Law of Commutation (数论)
题意:输入n和a 定义m等于2的n次方 求1-m有多少数使得 a^b = b^a (mod m) 题解:先打表找规律 发现a为奇数的答案只有b = a这一种 (不知道为什么也不想知道为什么 当a为偶数 ...
- libevent reference Mannual II--library
FYI: http://www.wangafu.net/~nickm/libevent-book/TOC.html The Libevent Reference Manual: Preliminari ...
- HDU - 6264 - Super-palindrome(思维)
题意: 给出一个字符串,使得所有的奇数连续子串为回文串,输出最小变化次数 思路: 分析过后,只存在两种情况,1全部为一种字母,2形如abab交替类型 对于奇数位和偶数位单独计数,只需计算出奇数位或者偶 ...
- C++异常:exception
基本知识 下图表示了标准异常的继承关系 exception是所有标准异常的基类,自定义异常也需要继承exception,如下例: #include "pch.h" #include ...