Linux串口编程详解

转自:http://www.adamjiang.com/pukiwiki/index.php?Linux%E4%B8%B2%E5%8F%A3%E7%BC%96%E7%A8%8B%E8%AF%A6%E8%A7%A3

串口本身,标准和硬件 

串口是计算机上的串行通讯的物理接口。计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备。虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接通常特指那些与RS-232标准兼容的硬件或者调制解调器的接口。虽然现在在很多个人计算机上,原来用以连接外部设备的串口已经广泛的被USB和Firewire替代;而原来用以连接网络的串口则被以太网替代,还有用以连接终端的串口设备则已经被MDA或者VGA取而代之。但是,一方面因为串口本身造价便宜技术成熟,另一方面因为串口的控制台功能RS-232标准高度标准化并且非常普及,所以直到现在它仍然被广泛应用到各种设备上。 某些计算机使用一个叫做UART的集成电路来作为串口设备。这个集成电路可以进行字符和异步串行通讯序列之间的转换,并且可以自动地处理数据的时序。而某些低端设备则会让CPU直接通过输出针来传送数据,这种技术叫做bit-banging。 因为“串口”,RS-232和UARTs基本上总是在同一个语境中出现,所以这些名词通常会被搞混。下面逐一解释以下一些重要的名词和术语。

什么是串行通信 

计算机可以每次传送一个或者多个位(bit)的数据。“串行”指的式每次只传输一位(1bit)数据。 当需要通过串行通讯传输一个字(word)的数据时,只能以每次一位的方式接收或者发送。每个位可能是on(1)或者off(0)。很多技术术语中经常用mark表示on,而space表示off。

串行数据的速度通常用每秒传输的字节数bits-per-second(bps)或者波特率(baud)表示。这个值表示的是每秒钟被送出的0和1的个数。很久很久以前,300bps就是很快的速度了,而现在的电脑可以处理高达430,800的RS-232速率。表示波特率的单位还有kpbs和Mbps,1kps=1000bps而1Mbps=1000kbps。 一般有人提到串行设备的时候,它通常说可能是某种数据通讯设备-DCE(Data Communications Equipment)或者数据终端设备-DTE(Data Terminal Equipment)。它们之间的区别非常简单,每个信号对,比如传送和接收,它们俩正好是相反的。如果需要将两个DTE或者DCE设备连接起来的话,需要适配器或者交叉线缆将信号对交换。

什么是RS-232 

RS-232是EIA(Electronic Industries Association)定义的串行通信的电器接口。RS-232事实上有三种(A,B和C),它们分别采用不同的电压来表示on和off。最被广泛使用的是RS-232C,它将mark(on)比特的电压定义为-3V到-12V之间,而将space(off)的电压定义到+3V到+12V之间。虽然RS-232C标准说信号最远被传输8m,但事实上你可以使用它传输更长的距离,直到信号波特率已经小到不行了为止。 RS-232的连结线中除去用来传入传出数据的电线,还有一些用来提供时序,状态和握手的电线:

RS-232 针脚定义

DB-25

针脚 描述 针脚 描述 针脚 描述 针脚 描述 针脚 描述
1 Earth Ground 6 DSR - Data Set Ready 11 Unassigned 16 Secondary RXD 21 Signal Quality Detect
2 TXD - Transmitted Data 7 GND - Logic Ground 12 Secondary DCD 17 Receiver Clock 22 Ring Detect
3 RXD - Received Data 8 DCD - Data Carrier Detecter 13 Secondary CTS 18 Unassigned 23 Data Rate Select
4 RTS - Request To Send 9 Reserved 14 Secondary TXD 19 Secondary RTS 24 Transmit Clock
5 CTS - Clear To Send 10 Reserved 15 Transmit Clock 20 DTR - Data Terminal Ready 25 Unassigned

DB-9

针脚 名称 全名 方向(主机 外设)
3 TD Transmit Data ->
2 RD Receive Data <-
7 RTS Request To Send ->
8 CTS Clear To Send <-
6 DSR Data Set Ready <-
4 DTR Data Terminal Ready ->
1 CD Data Carrier Detect <-
9 RI Ring Indicator <-
5 - Signal Ground  

另外两个比较常见的串行接口的标准式RS-422和RS-574。RS-422使用更低的电压和差分信号,这样可以将传输距离扩张到300m。而RS-574定义了通常可以见到的用在电脑上的9针连接器和电压。

信号定义 

RS-232标准定义了18个不同的串行通信的信号。而这些之中,仅仅有如下6个可以在UNIX环境中使用。

  • GND - Logic Ground

    从技术角度讲,GND不能算是信号。但是没有它其他信号都不能用了。基本上,logic ground有点像一个参考电压,通过它来判断哪个电压表示正哪个电压表示负。

  • TXD - Transmitted Data

    TXD信号负载着从你的电脑或者设备到另一端(比如调制解调器)的数据。Mark范围的电压被解析成1,而space范围电压被解析成0。

  • RXD - Received Data

    RXD于TXD正好相反。它负载着从另一端的电脑或者设备上传到你的工作站的数据。Mark和space的解析方法于TXD一致。

  • DCD - Data Carrier Detect

    DCD信号通常来自串口连结线的另一端。这条信号线上的space电压表示另一端的电脑或者设备现在已经连接。但是,DCD信号线却不是总可以得到的,有些设备上有这条信号线,而有的则没有。

  • DTR - Data Terminal Ready

    DTR信号是你的工作站产生的,用以告诉另一端的电脑或者设备你已经是否已经准备好了。Space电压表示准备好了,而mark电压表示没有准备好。当你在工作站上打开串行接口时,DTR通常自动被设置位有效。

  • CTS - Clear To Send

    CTS则通常来自连结线的另一端。Space电压表示你可以从工作站送出更多的数据。CTS通常用来协调你的工作站和另一端之间的串行数据流。

  • RTS - Request To Send

    如果RTS信号被设置成space电压,这表示你准备好了一些数据需要传送。和CTS一样,RTS也被用来协调工作站和另一端的电脑或者设备之间的数据流。有些工作站上会一直将这个信号设置位space。

异步通讯 

计算机为了弄懂传给它的串行数据,它需要确定每个字符开始和结束的位置。这通常是用异步串行数据来完成的。

在异步模式中,除非有字符被传输,否则串行数据线总是处于mark(1)状态。有一个start位会被加入传输字符的各个位之前,在字符本身的位之后会有一个可选的parity位和一个或者多个stop位。Start位总是space(0)并且它会告诉计算机新的串行数据过来了。数据可以随时被送出或者接收,这就是所谓的异步。

#ref(): File not found: "async.gif" at page "Linux串口编程详解"

那个可选的parity位仅仅是所有传输位的和,这个和用以表示传输字符中有奇数个1还是偶数个1。在偶数parity中,如果有传输字符中有偶数个1,那么parity位被设置成0,而传输字符中有奇数个1,那么parity位被设置成1。在奇数parity中,位设置与此相反。还有一些术语,比如space parity, mark parity和no parity。Space parity是指parity位会一直被设置位0,而mark parity正好与此相反,parity会一直是1。No parity的意思就是根本不会传输parity位。 剩余的位叫做stop位。传输字符之间可以有1个,1.5个或者2个stop位,而且,它们的值总是1。传统上,Stop位式用给计算机一些时间处理前面的字符的,但是它只是被用来同步接收数据的计算机和接受的字符。 异步数据通常被表示成"8N1","7E1",或者与此类似的形式。这表示“8数据位,no parity和1个stop bit”,还有相应得,“7数据位,even parity和1个stop bit”。

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Qt中实现Linux串口通讯可以使用Qt的QSerialPort模块。以下是一个示例代码来在Linux上使用Qt进行串口通讯: ```cpp #include <QCoreApplication> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 获取可用的串口列表 QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts(); if (portList.isEmpty()) { qDebug() << "No serial ports found."; return 0; } foreach (const QSerialPortInfo &portInfo, portList) { qDebug() << "Port:" << portInfo.portName(); qDebug() << "Description:" << portInfo.description(); qDebug() << "Manufacturer:" << portInfo.manufacturer(); // 连接到串口 QSerialPort serial; serial.setPort(portInfo); if (serial.open(QIODevice::ReadWrite)) { qDebug() << "Connected to" << portInfo.portName(); // 配置串口参数 serial.setBaudRate(QSerialPort::Baud9600); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneStop); serial.setFlowControl(QSerialPort::NoFlowControl); // 读取串口数据 QObject::connect(&serial, &QSerialPort::readyRead, [&]() { QByteArray data = serial.readAll(); qDebug() << "Received data:" << data; }); // 写入串口数据 QByteArray sendData("Hello, Serial"); qint64 bytesWritten = serial.write(sendData); qDebug() << "Sent data:" << sendData; qDebug() << "Bytes written:" << bytesWritten; } else { qDebug() << "Failed to connect to" << portInfo.portName(); } } return a.exec(); } ``` 以上代码会列出可用的串口列表并尝试连接到每个串口,然后设置串口参数、读取和写入数据。你可以根据需要修改串口参数、读取和写入数据的方式。 在.pro文件中添加如下配置: ```pro QT += serialport ``` 这样就可以使用Qt的串口模块了。 希望这能帮助到你!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值