跳转到内容

应用机器人/微控制器/串行通信

来自维基教科书,开放世界中的开放书籍

串行通信基础

[编辑 | 编辑源代码]

串行通信是一种一次发送一位数据的方式,用于在设备之间进行数据传输。这种方法只需要每个设备少数几根线和 I/O 引脚来进行通信。通常,大多数串行设备发送和接收字节取向的数据(每次传输 8 位),并有专门的发送和接收线路(全双工)。串行通信通常由专门的硬件外设处理,称为 **USART**(**U**niversal **S**ynchronous-**A**synchronous **R**eceiver-**T**ransmitters),这些外设处理低级格式、移位和数据恢复。

大多数 ATmega 系列 AVR 微控制器都有 1-2 个可用的 USART。一些现代微控制器有 5-7 个独立的 USART。

串行帧结构

[编辑 | 编辑源代码]

串行传输被分成所谓的帧。每个帧都包含要发送的有效载荷数据字节以及一些用于“帧”或格式化数据的位。大多数 USART,包括 AVR USART,都兼容这样的帧结构。

一个通用的 UART 串行通信帧示例。

串行线路在传输开始之前保持逻辑高电平。每次传输都以一个称为起始位的单个逻辑低位开始。在起始位之后,有效载荷数据被移出,通常以最低有效位在前。在最后一个数据位移出之后,会发送一个可选的奇偶校验位。奇偶校验位的取值为 0 或 1,具体取决于数据中逻辑 1 位的数量,接收方可以使用它来检测其中一位被翻转的错误传输。最后,串行线路在可配置的 1 或 2 个位时间内恢复到逻辑高电平;这些被称为停止位。AVR USART 能够发送具有 5-9 个数据位、偶数、奇数或无奇偶校验以及 1 或 2 个停止位的帧。在上面的帧中,逻辑高信号对应于 '0',而逻辑低信号对应于 '1'。

同步与异步串行

[编辑 | 编辑源代码]

使用 USART 的串行通信可以同步完成(数据带有专用的时钟信号)或异步完成(数据没有专用的时钟信号)。使用同步串行线路需要为时钟信号添加额外的线路,而且在典型的串行数据速率下往往是不必要的。通常,大多数标准串行通信,特别是 PC 和微控制器之间的通信,都是异步完成的。

波特率

[编辑 | 编辑源代码]

波特率指定了发送位的频率。波特率可以通过将 1 除以位时间(以秒为单位)来计算。正确设置异步串行的波特率非常重要,因为接收方必须根据预定的时钟频率从传入数据中恢复时钟信号。PC 上常见的波特率有 1.2k、2.4k、4.8k、9.6k、19.2k、38.4k、57.6k、115.2k、230.4k、460.8k 和 921.6k。

逻辑电平

[编辑 | 编辑源代码]

有许多不同的标准串行逻辑电平被使用。大多数 PC 接口使用 RS-232 串行,它指定了 -15V 到 -3V 和 +3 到 +15V 之间的逻辑电平,并且空闲时为低电平的线路。AVR USART 使用 0-5V 之间的 CMOS 逻辑电平,并且具有空闲时为高电平的串行线路,通常与标准的 3.3V 或 5V 逻辑输出兼容。设备之间必须使用适当的串行逻辑电平,为此可能需要特殊的电平转换器。

德州仪器生产用于 RS-232 的 RS-232 到 CMOS/TTL 电平转换器。这些器件内置了一个电荷泵,用于提供 RS-232 电平,并且只需要几个外部元件。这些芯片的一个例子是 MAX232 http://www.ti.com/product/max232

在 ATmega 微控制器上设置 USART

[编辑 | 编辑源代码]

以下示例展示了如何在 ATmega128 上设置串行端口,使用 USART0 作为以 115200 波特率运行的异步串行设备。在这个示例中,ATmega128 使用一个 16 MHz 的时钟。程序应该初始化 USART0,并在其发射器上发送字节 0xAA。它将继续检查接收器是否有新数据,如果收到 0xAA 字节,则将 PB0 设置为高电平。这允许进行快速环回测试,并演示了基本的 USART 概念。

/**************************************************
 *
 * AVR Microcontroller USART0 Example 
 * Cody Hyman <[email protected]>
 *
 **************************************************/
#include <avr/io.h>

/* Initialize USART0 */
void init_usart()
{
    UBRR0H = 0; // Initialize the baud rate registers for 115.2kbps
    UBRR0L = 8; 
    UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);// Set the USART data size to 8b
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);  // Enable the receiver and transmitter
    DDRE |= (1<<1);                  // Set the Tx line (PE0) to be an output.
}
/* Blocking single byte transmit on USART0 */
void transmit_usart0(uint8_t byte)
{
    // Check for previous transmission to complete and 
    while(!(UCSR0A & (1<<TXC0))); // Wait until last transmit is complete
    UDR0 = byte;                  // Start next transmission by writing to UDR0
}
/* Checks the USART0 Rx complete status flag */
uint8_t usart_has_rx_data(void)
{
    return (UCSR0A & (1<<RXC0)) != 0; // Return the RX complete status flag
}
/* Reads data from the USART receive buffer */
uint8_t receive_usart0(void)
{
    uint8_t ret_val = UDR0; // Read data register
    return ret_val;   // Return read value
}
int main(void)
{
    init_usart();              // Run USART initialization routine
    DDRB |= (1<<0);            // Initialize ATmega128 board LED 0
    uint8_t received_data = 0; // Receive data buffer
    transmit_usart0(0xAA);     // Transmit 0xAA
    while(1)    // Main loop
    {    
        if(usart_has_rx_data())               // Check for received data
        {
            received_data = receive_usart0(); // If yes, get the data
            if(received_data = 0xAA)          // Check the data
                PORTB |= (1<<0);              // If it matches, turn on LED
            else
                PORTB &= ~(1<<0);             // Else turn off LED
        }
    }
    return 0;
}

USB - 串行桥

[编辑 | 编辑源代码]

通常,大多数现代 PC 都没有可用的专用 RS-232 串行端口,因此必须使用另一种方法。许多供应商以低廉的价格销售 RS-232 和 TTL 或 LVTTL 电平适配器。这些器件通常需要驱动程序,因此请遵循所有制造商的安装说明。

可插拔 USB 到 RS-232 适配器

FTDI UMFT230XB USB 到 3.3V 串行适配器

FTDI TTL-232R-5V-PCB USB 到 5V(或 3.3V)串行适配器

在 Windows 机器上

[编辑 | 编辑源代码]

串行适配器通常枚举为 COMx 端口。检查设备管理器以确定 COM 端口号。

在 Linux 机器上

[编辑 | 编辑源代码]

串行适配器通常枚举为 ttyUSBx 设备。检查你的 /dev/ 目录以确定 tty 设备号。

RS-232 引脚定义

[编辑 | 编辑源代码]

以下引脚分配图通常用于标准 RS-232 DE-9 连接器。DTE 公头引脚分配对应于 PC 或串行适配器侧的引脚。DCE 母头引脚分配对应于终端设备,例如带有 RS-232 端口的微控制器板。RS-232 还指定了一些其他流控制线,这些线路在旧串行调制解调器中经常使用,但对于大多数情况来说,只需要 TxD/RxD 和地线。 RS-232 DE-9 Connector Pinouts

常见错误

[edit | edit source]

常见错误包括 DCE 侧连接器 Tx/Rx 引脚接线错误,或意外使用 RS-232 交叉线而不是直通线。强烈建议在 RS-232 通信无法正常工作时检查这些因素。

串行终端软件

[edit | edit source]

存在多种串行终端程序,允许快速发送和接收串行数据。这些程序对于调试和测试串行设备很有用。

Windows 串行程序

[edit | edit source]

Realterm - 一个功能强大的基于 GUI 的串行终端。 - http://realterm.sourceforge.net/ Linux 串行程序:Minicom: 一个非常流行的基于终端的串行接口程序 - Debian 包名称 "minicom" Cutecom: 一个基于 GUI 的串行终端程序 - Debian 包名称 "cutecom"

Python 串行模块 (PySerial)

[edit | edit source]

PySerial 是一个易于跨平台使用的库,用于 PC 串行通信。建议使用 Python 2.7 而不是 Python 3.x。Pyserial 允许轻松管理串行端口,并在 Windows 或 Linux 上分别管理通过 COM 或 tty 端口发送和接收数据。可以在以下网站找到 Pyserial 和相关文档 - http://pyserial.sourceforge.net/

华夏公益教科书