因为linux下“一切设备皆文件”的思想,所以串口在linux下也不例外,也可以当做文件来进行处理。
因此对他的一切操作都和文件的操作一样(涉及到了open,read,write,close等文件的基本操作)。
串口简历:
串行口是计算机一种常用的接口,是异步全双工串行通信,具有连接线少,通讯简单,得到广泛的使用.常用的串口是 RS-232-C 接口(又称 EIA RS-232-C)它是在 1970 年由美国电子工业协会(EIA)联合贝尔系统、 调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准.它的全名是"数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准"该标准规定采用一个 25 个脚的 DB25 连接器,对连接器的每个引脚的信号内容加以规定,还对各种信号的电平加以规定.传输距离在码元畸变小于 4% 的情况下,传输电缆长度应为 50 英尺,
rs
232
是负逻辑电平,它定义+5~+12V为低电平,
而-12~-5V为高电平。
还有TTL电平的串口,它由四根线组成的通信,还有的USB-TO-SERIAL(usb转串口),就是将串口封装成usb的接口。
计算机串口的引脚说明
TTL只需要2,3外加VCC和GND即可。
串口编程的步骤:开始,打开串口、串口初始化、读/写串口、关闭串口、结束。
下面是一个简单的串口程序:
/*
* =====================================================================================
*
* Filename: uart.c
*
* Description:
*
在linux系统上进行串口相关的控制
*
* Version: 1.0
* Created: 06/28/2017 06:48:54 PM
* Revision: none
* Compiler: arm-linux-gcc
*
Language: C
* Author: huangcheng,
* Company:
*
* =====================================================================================
*/
#include <stdio.h> //errno
#include <errno.h>
#include <string.h> //memset
#include <termios.h>
#include <sys/types.h> //open
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> //read
/**
*
@Description 初始化uart
*
@param file 打开的串口设备文件
*
@param baudrate 指定串口工作的波特率
*
@return int :成功返回初始化好的设备文件描述符fd 失败返回-1
**/
int init_serial(const char *file, int baudrate)
{
u32_t fd;
fd = open(file, O_RDWR);
if (fd == -1)
{
perror("open device error:");
return -1;
}
struct termios myserial;
//清空结构体
memset(&myserial, 0, sizeof (myserial));
//O_RDWR
myserial.c_cflag |= (CLOCAL | CREAD);
//设置控制模式状态,本地连接,接受使能
//设置 数据位
myserial.c_cflag &= ~CSIZE; //清空数据位
myserial.c_cflag &= ~CRTSCTS; //无硬件流控制
myserial.c_cflag |= CS8; //数据位:8
myserial.c_cflag &= ~CSTOPB;// //1位停止位
myserial.c_cflag &= ~PARENB; //不要校验
//myserial.c_iflag |= IGNPAR; //不要校验
//myserial.c_oflag = 0; //输入模式
//myserial.c_lflag = 0; //不激活终端模式
switch (baudrate)
{
case 9600:
cfsetospeed(&myserial, B9600); //设置波特率
cfsetispeed(&myserial, B9600);
break;
case 115200:
cfsetospeed(&myserial, B115200); //设置波特率
cfsetispeed(&myserial, B115200);
break;
case 19200:
cfsetospeed(&myserial, B19200); //设置波特率
cfsetispeed(&myserial, B19200);
break;
}
/* 刷新输出队列,清除正接受的数据 */
tcflush(fd, TCIFLUSH);
/* 改变配置 */
tcsetattr(fd, TCSANOW, &myserial);
return fd;
}
/**
*
@Description 向串口读取指定字节的数据
*
@param fd 打开的串口设备文件描述符
*
@param buf 指定串口中读取的缓冲区
*
@param size 指定从串口中读取的字节数
*
@return int 成功返回0 失败返回已经读取的字节数
**/
int read_serial(u32_t fd, void *buf, u32_t size)
{
int sum =0;
int ret = 0;
while(sum < size)
{
ret = read(fd, buf + sum, size-sum); //bug如果数据没有发送,一直会产生阻塞,可以使用io多路监听。
sum += ret;
}
return 0;
}
/*
@Description 向串口写入指定字节的数据
@param fd 打开的串口设备文件描述符
@param buf 指定串口中写入的缓冲区
@param size 指定从串口中读取的字节数
@return int 成功返回0 失败返回已经读取的字节数
*/
int write_serial(u32_t fd, void *buf, u32_t size)
{
int sum = 0;
int ret = 0;
if(size <= 0)
return -1;
while(sum < size)
{
ret = write(fd, buf + sum, size-sum); //bug如果数据没有发送,一直会产生阻塞,可以使用io多路监听。
sum += ret;
}
return 0;
}