0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

怎样用UART与PC通信

454398 来源:工程师吴畏 2019-07-31 17:12 次阅读

示意图

怎样用UART与PC通信

微控制器通信 - 什么是UART

微控制器经常发现自己处于具有特定功能的专用电路中,例如测量,监控和控制。但是,有些情况下将微控制器连接到计算机可能非常有益甚至是必要的(例如,设备配置)。有几种方法可以实现PC-Microcontroller通信

通过Wi-Fi(如ESP8266模块)

以太网

USB

虽然这些形式的通信可能允许高数据传输速率,但它们很难使用,大多数微控制器都有另外一种类型的通信,称为UART,它代表通用异步接收器/发送器。

这是一个简单的串行连接,可以是用于以低速发送少量数据,并且使用和实现极其简单。使UART更加便捷的是,有USB转串口转换器可用于允许微控制器通过USB使用虚拟COM端口与PC通信。

串行概述

使用微控制器和计算机的串行通信可包括许多不同的设置,包括奇偶校验和停止位。但是,在本教程中,我们将介绍最简单的串行通信形式,这也是最常见的形式之一。所以我们首先要看的是如何发送串行数据。首先,我们来看看硬件

微控制器上最简单形式的串行外设是一个美化的移位寄存器,它使用两个独立的I/O引脚来发送数据(TxDn)和接收数据(RxDn)

当需要从设备发送数据时,它会将数据发送到其发送移位寄存器中,然后逐位计时数据,直到所有数据都已发送完毕。当需要读取数据时,接收器首先需要检测是否正在接收某些数据。

一旦满足此条件,接收器就会将数据移入移位寄存器。完成后,可以从接收移位寄存器中读取器件,并以其认为合适的任何方式处理数据。

UART模块的简单框图

UART模块中使用的协议本身(有时称为RS-232)包含有助于数据传输/接收的选项和附加功能。下图显示了典型的UART传输,包括起始位,数据本身,奇偶校验位和停止位。

从ATmega168数据表中获取的图像

IDLE - 如果没有发生传输,则传输线必须保留逻辑1(5V,3.3V等)

起始位 - UART线上的下降沿表示传输即将开始

数据位 - 这些是我们的实际数据位发送,并且位首先发送到最低位(位0,位1 。..位7)

奇偶校验位 - 此可选位可用作错误检查的基本形式具有等于所有位组合的异或(XOR)的值

停止位 - 这是停止传输所必需的并且是逻辑1.有时,可以使用两个停止位,但通常只使用一个

ATmega上的UART

ATmega168上的UART模块非常复杂,因为它允许不同的操作模式(包括同步传输),但我们将配置UART以使用适用于99%基于UART的项目的最常见设置。

时钟

我们需要配置的第一件事是UART模块的时钟源(这也配置了UART运行的模式) 。由于我们将使用异步传输(时钟不传输,只有数据),我们将使用“正常异步”。为此,我们在UCSRnC寄存器中将UMSEL位设置为0.

奇偶校验位和停止位

由于大多数传输不需要奇偶校验,我们将禁用该位。为此,我们需要将两个UPM位都设置为0,这可以在UCSR寄存器中找到。

对于停止位,我们只会使用一个停止位,通过清除UCSRnB寄存器中的USBS位来完成。

数据大小

UART模块能够以不同的位宽发送数据,但对于大多数项目,我们将使用8位数据大小,因为我们的微控制器是一个8位器件。为此,我们将寄存器UCSRnB和UCSRnC中的UCSZ位的值设置为011。

波特率

在谈到串行通信时,波特率通常是指每秒传输的数据位数,可以认为是连接速度。串行通信的典型波特率包括9600,115200和10417.

对于我们的串行设置,我们将使用9600的波特率(非常常见的波特率)。波特率可以使用下面的公式计算,但是,使用第163-165页上的表格更容易。

由于我们的ATmega168连接到8MHz振荡器,我们可以查看下表,看看我们将UBRR寄存器设置为什么值。

对于9600波特,我们将使用值51.请注意,您的CLKDIV8位可能已设置,如果是这种情况,那么您的波特率可能比您预期的慢8倍。如果是这种情况,请尝试使用UBRR值12而将U2X0设置为开,或使用更高的时钟速度。

启用接收/传输

我们需要设置几个启用位,其他启用位是可选的。我们需要使能的前两位是RXEN和TXEN,它们使能接收器和发送器。

我们可以设置两个中断使能位,这意味着当我们的UART模块完成发送或接收数据时,中断将触发(对实时应用程序有用)。

读/写UART

有趣的是,AVR UART外设对接收和发送寄存器使用相同的I/O地址。当写入UART数据寄存器(UDRn)时,数据被发送到UART发送器移位寄存器,当从UART数据寄存器读取时,返回来自UART接收器的数据。

一些有用的控制信号

一个寄存器UCSR0A可以帮助确定UART的状态模块,因为它有几个状态位。

RXC0,第7位,如果接收缓冲区中有需要读取的数据,则为1

TXC0,第6位,一旦传输将为1已完成

如果发送缓冲区为空,UDRE0,位5将为1

FE0,位4,发出帧错误警告

DOR0,第3位,发出数据溢出警告(当收到的数据太多且接收缓冲区已满时)

当奇偶校验时,UPE0,位2将为1在接收到的字节上检测到错误

一个简单的UART示例

此示例将介绍如何创建一个echo设备,该设备将等待连接的PC向UART线路发送一个字节。一旦检测到,AVR将立即发回相同的字节以回显消息。

/*

* AVR UART.c

*

* Created: 09/01/2018

* Author : RobinLaptop

*/

// These are really useful macros that help to get rid of unreadable bit masking code

#define setBit(reg, bit) (reg = reg | (1 《《 bit))

#define clearBit(reg, bit) (reg = reg & ~(1 《《 bit))

#define toggleBit(reg, bit) (reg = reg ^ (1 《《 bit))

#define clearFlag(reg, bit) (reg = reg | (1 《《 bit))

#include

int main(void)

{

// Initialize Registers

// Configure register UCSRA

setBit(UCSR0A, U2X0); // Double the BRG speed (since I am using a 8MHz crystal which is divided by 8)

clearBit(UCSR0A, MPCM0); // Normal UART communication

// Configure register UCSRB

clearBit(UCSR0B, RXCIE0); // We will not enable the receiver interrupt

clearBit(UCSR0B, TXCIE0); // We will not enable the transmitter interrupt

clearBit(UCSR0B, UDRIE0); // We will not enable the data register empty interrupt

setBit(UCSR0B, RXEN0); // Enable reception

setBit(UCSR0B, TXEN0); // Enable transmission

clearBit(UCSR0B, UCSZ02); // 8 bit character size

// Configure register UCSRC

clearBit(UCSR0C, UMSEL00); // Normal Asynchronous Mode

clearBit(UCSR0C, UMSEL01);

clearBit(UCSR0C, UPM00); // No Parity Bits

clearBit(UCSR0C, UPM01); // No Parity Bits

clearBit(UCSR0C, USBS0); // Use 1 stop bit

setBit(UCSR0C, UCSZ01); // 8 bit character size

setBit(UCSR0C, UCSZ00);

// Configure the baud rate register (this is a combination of both UBRR0L and UBRR0H)

// Despite using an 8MHz crystal my Fosc is 1MHz since the CLK8DIV fuse bit is dividing the clock

// by 8. When I try to change this fuse the AVR locks me out!

UBRR0 = 12;

while (1)

{

// Wait until data has been received

while(!(UCSR0A & (1 《《 RXC0)));

// Now send the same byte back

UDR0 = UDR0;

// Wait until the Data Transmit Register is empty

while(!(UCSR0A & (1 《《 TXC0)));

}

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PC
    PC
    +关注

    关注

    9

    文章

    1950

    浏览量

    152786
  • uart
    +关注

    关注

    22

    文章

    1156

    浏览量

    99942
  • ATmega168
    +关注

    关注

    0

    文章

    9

    浏览量

    9235
收藏 人收藏

    评论

    相关推荐

    STM32F412G-DISCO怎样用MX生成fatfs的代码?

    STM32F412G-DISCO怎样用MX生成fatfs的代码? SD卡例程能跑,但mx生成的代码不能正常运行,我生成代码后是不是还要配置一些东西?(我生成后只写了测试代码) 问题解决了,虽然我不知道我为什么不能直接使用mx生成的代码去操作sd卡,但我通过复制粘贴例程的代码完成了测试。
    发表于 03-12 08:15

    无线通信怎样用电磁波表示1和0

    为什么频率越高,能携带的信息就越多?以数字信号为例,信息就是一串串的1和0,所以先搞清楚怎样用电磁波表示1和0。
    发表于 12-05 14:44 613次阅读
    无线<b class='flag-5'>通信</b>:<b class='flag-5'>怎样用</b>电磁波表示1和0

    怎样用ADAU1761设计DRC的压缩/扩展?

    请问怎样用ADAU1761设计DRC的压缩/扩展。我在SigmaStudio 4.5的模块中只找到RMS。如果ADAU1761设计DRC要怎样
    发表于 11-28 06:41

    怎样用32单片机测电压?

    怎样用32单片机测电压
    发表于 10-31 07:09

    怎样用现成的Eclipse插件来调试AT32系列芯片以及SLIB的配置范例

    本篇应用指南主要描述怎样用现成的Eclipse插件来调试AT32系列芯片以及SLIB的配置范例。本文档仅以AT32F403A为例进行说明,关于AT32F403A SLIB的详细说明,请详阅《AT32F403ASecurity Library Application Note》。
    发表于 10-24 07:41

    怎样用现成的Eclipse插件来调试AT32系列芯片

    拥有很高的灵活性,软件可以以Eclipse为架构开发自己的IDE。这边文档主要描述怎样用现成的Eclipse插件来调试AT32系列芯片。
    发表于 10-24 07:12

    怎样用单片机IO口来控制三极管的开关特性使共阳极的LED点亮?

    怎样用单片机IO口来控制三极管的开关特性使共阳极的LED点亮
    发表于 10-15 06:02

    uart通信的详细讲解

    UART(UniversalAsynchronousReceiver/Transmitter,通用异步收发器)是一种常用的串行通信协议,广泛应用于单片机或各种嵌入式设备之间的通信。本文将详细介绍
    的头像 发表于 09-22 08:22 1676次阅读
    <b class='flag-5'>uart</b><b class='flag-5'>通信</b>的详细讲解

    PLC中怎样用X和Y两个轴走出直线轨迹?

    PLC中怎样用X和Y两个轴走出直线轨迹呢?那么这两个轴需要配合成速度成线性比例,位置和速度应该如何云运算呢?
    发表于 09-12 09:58 364次阅读
    PLC中<b class='flag-5'>怎样用</b>X和Y两个轴走出直线轨迹?

    UART串口通信的应用方法

    数据传输速率较慢,但其占用资源少、成本低、实现简单,因此在嵌入式系统中应用十分广泛,而UART(通用异步收发器)则是众多串行通信协议中最典型的一种。本期内容将通过PC主机与RV-STAR开发板间的三个
    发表于 08-16 08:24

    UART通信原理详解

    通用异步收发传输器,通常称作UART,是一种异步收发传输器。是异步通信协议。特性:两根线,全双工,异步通信,速度较慢。
    发表于 06-28 15:26 1326次阅读
    <b class='flag-5'>UART</b><b class='flag-5'>通信</b>原理详解

    怎样用示波器测试lin总线的波特率呢?

    怎样用示波器测试lin总线的波特率呢?有什么方法吗?
    发表于 05-09 11:22

    怎样用FPGA实现FSK调制解调呢?

    最近想做这方面的,怎样用FPGA实现FSK调制解调?但是我一点头绪都没有,哪位高手帮帮忙,讲解一下什么的
    发表于 05-08 17:34

    请问Proteus仿真软件中怎样用探针测电压呢?

    请问Proteus仿真软件中怎样用探针测电压呢?
    发表于 04-26 15:55

    怎样用74LS00实现两位数据输入的奇偶校验电路?

    怎样用74LS00实现两位数据输入的奇偶校验电路?
    发表于 04-26 11:25