linux下串口相关控制

    因为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的接口。

     计算机串口的引脚说明
序号 信号名称 符号 流向 功能
2 发送数据 TXD DTE→DCE DTE发送串行数据
3 接收数据 RXD DTE←DCE DTE 接收串行数据
4 请求发送 RTS DTE→DCE DTE 请求 DCE 将线路切换到发送方式
5 允许发送 CTS DTE←DCE DCE 告诉 DTE 线路已接通可以发送数据
6 数据设备准备好 DSR DTE←DCE DCE 准备好
7 信号地     信号公共地
8 载波检测 DCD DTE←DCE 表示 DCE 接收到远程载波
20 数据终端准备好 DTR DTE→DCE DTE 准备好
22 振铃指示 RI DTE←DCE 表示 DCE 与线路接通,出现振铃
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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值