示意圖
微控制器經常發現自己處于具有特定功能的專用電路中,例如測量,監控和控制。但是,有些情況下將微控制器連接到計算機可能非常有益甚至是必要的(例如,設備配置)。有幾種方法可以實現PC-Microcontroller通信
雖然這些形式的通信可能允許高數據傳輸速率,但它們很難使用,大多數微控制器都有另外一種類型的通信,稱為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
+關注
關注
9文章
2090瀏覽量
154346 -
uart
+關注
關注
22文章
1240瀏覽量
101495 -
ATmega168
+關注
關注
0文章
9瀏覽量
9310
發布評論請先 登錄
相關推薦
評論