示意圖

微控制器經(jīng)常發(fā)現(xiàn)自己處于具有特定功能的專用電路中,例如測(cè)量,監(jiān)控和控制。但是,有些情況下將微控制器連接到計(jì)算機(jī)可能非常有益甚至是必要的(例如,設(shè)備配置)。有幾種方法可以實(shí)現(xiàn)PC-Microcontroller通信
雖然這些形式的通信可能允許高數(shù)據(jù)傳輸速率,但它們很難使用,大多數(shù)微控制器都有另外一種類型的通信,稱為UART,它代表通用異步接收器/發(fā)送器。
這是一個(gè)簡(jiǎn)單的串行連接,可以是用于以低速發(fā)送少量數(shù)據(jù),并且使用和實(shí)現(xiàn)極其簡(jiǎn)單。使UART更加便捷的是,有USB轉(zhuǎn)串口轉(zhuǎn)換器可用于允許微控制器通過(guò)USB使用虛擬COM端口與PC通信。
串行概述
使用微控制器和計(jì)算機(jī)的串行通信可包括許多不同的設(shè)置,包括奇偶校驗(yàn)和停止位。但是,在本教程中,我們將介紹最簡(jiǎn)單的串行通信形式,這也是最常見(jiàn)的形式之一。所以我們首先要看的是如何發(fā)送串行數(shù)據(jù)。首先,我們來(lái)看看硬件!
微控制器上最簡(jiǎn)單形式的串行外設(shè)是一個(gè)美化的移位寄存器,它使用兩個(gè)獨(dú)立的I/O引腳來(lái)發(fā)送數(shù)據(jù)(TxDn)和接收數(shù)據(jù)(RxDn)
當(dāng)需要從設(shè)備發(fā)送數(shù)據(jù)時(shí),它會(huì)將數(shù)據(jù)發(fā)送到其發(fā)送移位寄存器中,然后逐位計(jì)時(shí)數(shù)據(jù),直到所有數(shù)據(jù)都已發(fā)送完畢。當(dāng)需要讀取數(shù)據(jù)時(shí),接收器首先需要檢測(cè)是否正在接收某些數(shù)據(jù)。
一旦滿足此條件,接收器就會(huì)將數(shù)據(jù)移入移位寄存器。完成后,可以從接收移位寄存器中讀取器件,并以其認(rèn)為合適的任何方式處理數(shù)據(jù)。

UART模塊的簡(jiǎn)單框圖
UART模塊中使用的協(xié)議本身(有時(shí)稱為RS-232)包含有助于數(shù)據(jù)傳輸/接收的選項(xiàng)和附加功能。下圖顯示了典型的UART傳輸,包括起始位,數(shù)據(jù)本身,奇偶校驗(yàn)位和停止位。

從ATmega168數(shù)據(jù)表中獲取的圖像
IDLE - 如果沒(méi)有發(fā)生傳輸,則傳輸線必須保留邏輯1(5V,3.3V等)
起始位 - UART線上的下降沿表示傳輸即將開(kāi)始
數(shù)據(jù)位 - 這些是我們的實(shí)際數(shù)據(jù)位發(fā)送,并且位首先發(fā)送到最低位(位0,位1 。..位7)
奇偶校驗(yàn)位 - 此可選位可用作錯(cuò)誤檢查的基本形式具有等于所有位組合的異或(XOR)的值
停止位 - 這是停止傳輸所必需的并且是邏輯1.有時(shí),可以使用兩個(gè)停止位,但通常只使用一個(gè)
ATmega上的UART
ATmega168上的UART模塊非常復(fù)雜,因?yàn)樗试S不同的操作模式(包括同步傳輸),但我們將配置UART以使用適用于99%基于UART的項(xiàng)目的最常見(jiàn)設(shè)置。
我們需要配置的第一件事是UART模塊的時(shí)鐘源(這也配置了UART運(yùn)行的模式) 。由于我們將使用異步傳輸(時(shí)鐘不傳輸,只有數(shù)據(jù)),我們將使用“正常異步”。為此,我們?cè)赨CSRnC寄存器中將UMSEL位設(shè)置為0.


奇偶校驗(yàn)位和停止位
由于大多數(shù)傳輸不需要奇偶校驗(yàn),我們將禁用該位。為此,我們需要將兩個(gè)UPM位都設(shè)置為0,這可以在UCSR寄存器中找到。

對(duì)于停止位,我們只會(huì)使用一個(gè)停止位,通過(guò)清除UCSRnB寄存器中的USBS位來(lái)完成。

數(shù)據(jù)大小
UART模塊能夠以不同的位寬發(fā)送數(shù)據(jù),但對(duì)于大多數(shù)項(xiàng)目,我們將使用8位數(shù)據(jù)大小,因?yàn)槲覀兊奈⒖刂破魇且粋€(gè)8位器件。為此,我們將寄存器UCSRnB和UCSRnC中的UCSZ位的值設(shè)置為011。

波特率
在談到串行通信時(shí),波特率通常是指每秒傳輸?shù)臄?shù)據(jù)位數(shù),可以認(rèn)為是連接速度。串行通信的典型波特率包括9600,115200和10417.
對(duì)于我們的串行設(shè)置,我們將使用9600的波特率(非常常見(jiàn)的波特率)。波特率可以使用下面的公式計(jì)算,但是,使用第163-165頁(yè)上的表格更容易。

由于我們的ATmega168連接到8MHz振蕩器,我們可以查看下表,看看我們將UBRR寄存器設(shè)置為什么值。
對(duì)于9600波特,我們將使用值51.請(qǐng)注意,您的CLKDIV8位可能已設(shè)置,如果是這種情況,那么您的波特率可能比您預(yù)期的慢8倍。如果是這種情況,請(qǐng)嘗試使用UBRR值12而將U2X0設(shè)置為開(kāi),或使用更高的時(shí)鐘速度。

啟用接收/傳輸
我們需要設(shè)置幾個(gè)啟用位,其他啟用位是可選的。我們需要使能的前兩位是RXEN和TXEN,它們使能接收器和發(fā)送器。
我們可以設(shè)置兩個(gè)中斷使能位,這意味著當(dāng)我們的UART模塊完成發(fā)送或接收數(shù)據(jù)時(shí),中斷將觸發(fā)(對(duì)實(shí)時(shí)應(yīng)用程序有用)。

讀/寫UART
有趣的是,AVR UART外設(shè)對(duì)接收和發(fā)送寄存器使用相同的I/O地址。當(dāng)寫入U(xiǎn)ART數(shù)據(jù)寄存器(UDRn)時(shí),數(shù)據(jù)被發(fā)送到UART發(fā)送器移位寄存器,當(dāng)從UART數(shù)據(jù)寄存器讀取時(shí),返回來(lái)自UART接收器的數(shù)據(jù)。

一些有用的控制信號(hào)
一個(gè)寄存器UCSR0A可以幫助確定UART的狀態(tài)模塊,因?yàn)樗袔讉€(gè)狀態(tài)位。
RXC0,第7位,如果接收緩沖區(qū)中有需要讀取的數(shù)據(jù),則為1
TXC0,第6位,一旦傳輸將為1已完成
如果發(fā)送緩沖區(qū)為空,UDRE0,位5將為1
FE0,位4,發(fā)出幀錯(cuò)誤警告
DOR0,第3位,發(fā)出數(shù)據(jù)溢出警告(當(dāng)收到的數(shù)據(jù)太多且接收緩沖區(qū)已滿時(shí))
當(dāng)奇偶校驗(yàn)時(shí),UPE0,位2將為1在接收到的字節(jié)上檢測(cè)到錯(cuò)誤

一個(gè)簡(jiǎn)單的UART示例
此示例將介紹如何創(chuàng)建一個(gè)echo設(shè)備,該設(shè)備將等待連接的PC向UART線路發(fā)送一個(gè)字節(jié)。一旦檢測(cè)到,AVR將立即發(fā)回相同的字節(jié)以回顯消息。
/*
* 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(?。║CSR0A & (1 《《 RXC0)));
// Now send the same byte back
UDR0 = UDR0;
// Wait until the Data Transmit Register is empty
while(?。║CSR0A & (1 《《 TXC0)));
}
}
-
PC
+關(guān)注
關(guān)注
9文章
2167瀏覽量
159343 -
uart
+關(guān)注
關(guān)注
22文章
1314瀏覽量
106671 -
ATmega168
+關(guān)注
關(guān)注
0文章
9瀏覽量
9511
發(fā)布評(píng)論請(qǐng)先 登錄
CW32 UART單線半雙工模式
請(qǐng)問(wèn)CW32 UART用于數(shù)據(jù)收發(fā)的具體過(guò)程是怎樣的?
使用CW32 MCU來(lái)實(shí)現(xiàn)UART串口通信與GPIO控制
UART 串口通信還能玩出什么花樣?
UART 升級(jí)到 USB-C: 串口通信演變史
多路UART數(shù)據(jù)轉(zhuǎn)發(fā)芯片 支持1主4從UART接口 UART擴(kuò)展芯片
RVMCU課堂「13」: 手把手教你玩轉(zhuǎn)RVSTAR—UART通信篇
基于FPGA開(kāi)發(fā)板TSP的串口通信設(shè)計(jì)
UART 擴(kuò)展芯片 數(shù)據(jù)轉(zhuǎn)發(fā)多串口擴(kuò)展 1主4從,高效通信
求助,6832S做UART通信失敗
CYUSB3014與PC通信幾小時(shí)后斷開(kāi),通過(guò)bus hound抓不到任何通信數(shù)據(jù),為什么?
芯知識(shí)|廣州唯創(chuàng)電子語(yǔ)音芯片UART通信協(xié)議解析:發(fā)碼長(zhǎng)度與校驗(yàn)碼計(jì)算
MAX3100 SPI/MICROWIRE兼容UART技術(shù)手冊(cè)
怎樣用UART與PC通信
評(píng)論