分享到plurk 分享到twitter 分享到facebook

版本 4b31a6ecf3b606a7d04cbf4d6754808d95d1704d

embedded/USART

Changes from 4b31a6ecf3b606a7d04cbf4d6754808d95d1704d to current

USART簡介
...................
USART(universal synchronous asynchronous receiver transmitter) 通用同步/非同步收發傳輸器,提供了一種靈活的方法及使用NRZ非同步串行資料格式與外部設備之間進行全雙工資料交換。
同時,USART也提供同步的方式半雙工的通信,另外支持LIN (local interconnection network),Smartcard協定及IrDA (infrared data association紅外通訊技術) SIR ENDEC,Modem(CTS/RTS)的操作。
藉由DMA多重緩衝器的方式,可達到高速資料的通訊。
---
title: Universal Asynchronous Receiver/Transmitter (USART)
categories: ARM, USART, UART, STM32, STM32F4, STM32F429
...

USART簡介與特性
==========================
串列傳輸為CPU與周邊裝置或CPU與CPU間的資料傳輸方法之一,而USART(universal synchronous asynchronous receiver transmitter),通用同步/非同步收發傳輸器,則常被用於一般的串列傳輸應用中。可依照NRZ工業非同步資料傳輸格式,與其他設備進行資料交換。並且此種裝置使用fractional baud rate產生器,提供大範圍的baud rate供使用者選擇。

此外,亦支援同步傳輸、單線半雙工傳輸、LIN(local connection network)、Smartcard protocol、IrDA(Infrared data association) SIR ENDEC標準。

高速資料傳輸,則使用DMA去設定多重緩衝區來達到此目的。

USART主要特性
...................
NRZ標準資料格式(Mark/Space)
==========================

- 全雙工的非同步通訊
   NRZ(Nonreturn to Zero):不歸零編碼

- NRZ標準資料格式
   這是一種傳送資訊的編碼方式,它通常以正電位代表'1', 負電位代表'0'

   NRZ(Nonreturn to Zero):不歸零編碼
   它的特色是編碼解碼較為簡單,但缺乏同步傳輸的能力,且無法提供較佳的訊號校正能力。

   這是一種傳送資訊的編碼方式,它以正脈波代表1,負脈波代表0
![](/NRZcode.png)

   它的特色是編碼解碼較為簡單,可是同步信號必須另外傳播,否則無法提供訊號校正能力
圖片來源:[wikipedia](http://zh.wikipedia.org/wiki/%E4%B8%8D%E6%AD%B8%E9%9B%B6)

.. image:: /NRZcode.png
半雙工/全雙工
===================
 - 半雙工:允許二台設備之間的雙向資料傳輸,但不能同時進行。因此同一時間只允許一設備傳送資料,若另一設備要傳送資料,需等原來傳送資料的設備傳送完成後再處理。例:無線電

圖片來源:`wikipedia<http://zh.wikipedia.org/wiki/%E4%B8%8D%E6%AD%B8%E9%9B%B6>`_
 - 全雙工:允許二台設備間同時進行雙向資料傳輸。例:手機

- 可程式化的資料長度 (8 or 9 bits)
Synchronous 同步傳輸
=========================

- 可程式化的停止位元 (1 or 2 bits)
   - 同步: 額外提供時脈訊號,使兩端機器在溝通時能夠藉此同步收發資料。比起非同步傳輸,同步傳輸不需要start/stop bit,因此能夠一次傳較多的資料。同步傳輸需要解決時鐘偏移對資料傳輸造成的影響,除此之外,額外的時脈分佈網也需要大量的驅動電路,比起非同步傳輸增加了更多的耗能。一般同步系統會用阻斷時脈的方式(clock gating),來令不需運作的模組進入睡眠狀態(sleeping mode)到省電的目的,這個機制需要額外的電路及再次同步的額外延遲,不僅造成多餘的能源損耗,也增加了電路設計上的困難度。

- 提供同步傳輸的CLK信號

- 藉由DMA的多緩衝器資料傳輸,每個USART都能用DMA發送和接收資料
![](/synchronous_transmission.png)

- 獨立的發送器和接收器的enable bit
![](/usart_syn.png)

- 傳輸檢測標誌

 – 接收緩衝區滿
CLOCK SKEW
------------

 – 傳送緩衝區空
時鐘偏移(clock skew)是指時脈訊號到達數位電路各個部分所用時間的差異,這是由於時脈訊號到各個電子元件的所經路徑長度不同而產生。STM32F429的clock tree設計亦考慮到此問題,故將clock source用多層邏輯閘配置給系統中的各元件,藉此降低clock skew(如果只使用單個、或少數個邏輯閘,因其fan out有上限,最多不超過20個,若超過也會產生clock skew)。

 – 傳輸結束

- 校驗控制

 – 發送校驗位
Asynchronous 非同步傳輸
======================

 – 對接收的資料進行校驗
   - 非同步: 在傳送資料時插入額外資訊,表示資料起始、結束。好處是設定時間短、硬體成本低、機器時脈不同也能傳資料,缺點是單次傳輸的資料量較少。

- 4個錯誤檢測標誌
![](/embedded/ASYNC.gif)

 – 溢出錯誤(Overrun error)
來源: [webopedia](http://www.webopedia.com/FIG/ASYNC.gif)

 – 噪音檢測(Noise detection)

 – Frame錯誤
半/全雙工、同步/非同步 & Serial bus 示意圖
=========================================

 – 校驗錯誤
![](/embedded/USART_connection_type.jpg)

- 10個中斷源

 – CTS改變

 – LIN中斷檢測
RS232 介面標準
=============
在RS-232標準中,資料是以串列(serial)方式傳輸,其最常用的編碼格式是非同步起停(asynchronous start-stop)格式,它使用一個start bit後面緊跟7或8個資料位元(bit),然後是可選的奇偶校驗位元,最後是一或兩個停止位元。所以傳送一個字元至少需要10位元,主要功能為提供DTE以及DCE的實體連接。

 – 傳送緩衝區空
RS-232電器與機械特性
-------------
RS-232電器特性

 – 傳送完成
 - 最大電壓範圍為±25V;
 - -3V至-25V定義為邏輯“1”(負邏輯),稱為marking,功能意義為OFF;
 - +3V至+25V定義為邏輯“0” (負邏輯),稱為spacing,功能意義為ON;
 - 接近零的電位是無效的(±3V之間);
 - 接收信號端的輸入阻抗必須在3KΩ~7KΩ之間,輸入電容小於2500pF;
 - 接收信號端開路時,端點電壓必須小於2V;
 - 發送信號的一端輸出阻抗必須大於300Ω。

 – 接收緩衝區滿
RS-232的機械特性

 – 空閒線路檢測
 - 連接器有25pin及9pin,現多用9pin,因較節省空間及成本。
 - 最大傳輸線長度為50呎(15公尺),且資料傳輸速率在20Kbps以下。
 - Data terminal equipment,數位資料的接收或輸出端,並用傳輸協定對資料傳收流程做控制的機器。常見的機器為電腦。
 - Data circuit-terminating equipment,對類比訊號做編解碼,藉此傳收數位資料的機器。常見的機器為數據機。

 – 溢出錯誤
![](/RS232_DB9pin2.png)

 – Frame錯誤
![](/embedded/RS232_DB9Name3.png)

 – 噪音錯誤
RS-232訊號傳輸
-------------

 – 校驗錯誤
![](/RS232_Signal.png)

- 2種喚醒接收器的方式
 - 傳送單一封包時,一個package有1個startbit、8個data bits,1個stop bit。傳送完成後再傳送一個idle。

 - Address bit (MSB, 9th bit)
![](/signal_noidle.jpg)

 - Idle line
 - 而傳送多個連續封包時,在資料傳輸完以前並不會傳送idle,代表還沒有結束傳輸,原因是因為UART傳輸速度太慢,放入idle則會浪費頻寬。

例:由示波器的高低電位可以得出邏輯0010 0100 由於是從LSB開始傳,所以必須翻轉變成0010 0100換成16進位為0x24,就是符號 "$"
 
null modem 
 - modem: modulator-demodulator,將數位訊號編碼為類比訊號、或將類比訊號解碼為數位訊號。類比訊號可為無線電、紅外線、電流等,常見的應用有wifi、手機、藍芽、有線電話、光纖網路等。

USART功能介紹
.................................
 - 一般的modem接法為DTE-DCE-circuit-DCE-DTE,若要使DTE-DTE或DCE-DCE相連,則要透過NULL Modem的方式,其實就是為了欺騙電腦,讓電腦以為它所連接的是一部數據機,而能夠順利地進行數據傳輸,在這裡用了跳線的接法。

 - 跳線就是一個傳送的訊號必須到達對方的接收腳位,如此才能形成一個完整的通路,所以通路的形成就是將一方的傳送與接收的腳位作對調;如此一來,甲方的傳送資料必定到達乙方的接收通道;而乙方的傳送資料則會到達甲方的接收通道,雙方的送收形成一個完整的迴路,最精簡的情形就是只使用2、3、5即可以完成資料傳輸。 

USART block diagram
======================================
.. image:: /usart_block_diagram.png
![](/embedded/USART_NullModemBriefview.jpg)

   - 任何USART雙向通信至少需要兩個腳位:接收資料輸入(RX)和發送資料輸出(TX)
   - RX: 接收資料輸入,並藉由採樣的技術判斷資料及噪音
   - TX: 發送資料,當發送器被啟動時,如果沒有傳送數據,則TX處於高電位。在single-wire或Smartcard mode時,此I/O同時被用於資料的傳送和接收
   - 根據USART_CR1暫存器中的M位選擇8或9位元決定資料長度(見圖)
   - 使用fractional baud rate generator —— 12位整數和4位小數的表示方法,放在baud rate暫存器(USART_BRR)中
   - 一個狀態暫存器(USART_SR)
   - 資料暫存器(USART_DR)
   
   另外在同步模式中,還需要其他腳位
   - SCLK: 發送器的時鐘輸出,用於同步傳輸的時鐘
也有市售的接頭

![](/embedded/USART_NullModem.jpg)

RS-232阻礙

  - 過大的電壓擺幅,造成耗電量的增加
  - 單端訊號對於雜訊抑制的能力並不佳
  - DB25的接頭過大

單端信號傳輸與差分信號傳輸

以前,個人電腦所連接電纜的信號傳輸的主流方式是單端信號方式,其代表性特點是列表機連接使用並行接口(parallel port),調制解調器(modem)使用RS-232C。

單端信號傳輸

![](/embedded/single-ended.png)

 - 採用的是多個信號線共同使用信號返回的地線的方式。進行電壓檢測時,通過地線信號的電位,判斷邏輯。

在這種方式下,列舉如下兩個提高傳輸速率的方法:

 - 提高各信號線的傳輸速度
 - 增加信號線個數

如果增加信號線個數,連接器會更加大型化,電纜也變得更粗。如果單純地提高信號的速度,那麼不僅需要昂貴的IC,而且輻射的電磁干擾噪音也會變強。
如果降低電壓振幅,由於信號的上升/下降時間會縮短,高速傳輸也變得相對容易。但是如果電壓降低,那麼由於外部噪音的影響,很容易發生錯誤,為了解決這些問題,差分傳輸技術開始被廣泛使用。

差分信號傳輸

![](/embedded/Differential Signal.png)

 - 使用兩根信號線,這兩個信號的振幅相同,相位相反,電流在彼此間逆向流動,信號接收端比較這兩個電壓的差值來判斷發送端發送的是邏輯0還是邏輯1。在電路板上,差分走線必須是等長、等寬、緊密靠近、且在同一層面的兩根線,USB3.0就是高速差分傳輸的一種。

至於來自於外部的噪音,即使在正負兩端的信號線外施加同樣的噪音,因差分傳輸而容易發現信號線間的電位差,所以噪音會被消除,不易引發錯誤。

![](/embedded/differential_noise.png)

 - 通過相互間逆向流過電流,抵消磁通,由此降低信號高次諧波所引發的電磁干擾噪音。

但若電路板的面積非常吃緊,單端信號可以只有一根信號線,地線走地平面,而差分信號一定要走兩根等長、等寬、緊密靠近、且在同一層面的線。這常常發生在晶片的pin腳間距很小,以至於只能穿過一根走線的情況下。

STM32 USART介紹與特性
==========================

 - 可調整oversampling長度(8 or 16),藉此在速度以及時脈之間做取捨。

 - Factional baud rate generator systems。常見的tx/rx baud rate設定法,

 - 可程式化的資料長度 (8 or 8+1 bits)

 - 可程式化的停止位元 (1 or 2 bits),在Smartcard模式支援0.5及1.5(建議)bits。

 - LIN 主從同步資料傳輸,使用break傳輸/偵測達到此目的。

 - 同步傳輸模式下,提供tx的CLK信號

 - IrDA SIR 編解碼器

 - 可做為Smartcard模擬器
   
   在Hardware flow control中:
   - nCTS: 清除發送,若在高電位,則當目前資料傳送結束後,中斷下一次的資料傳送
   - nRTS: 發送請求,若在低電位,則表是USART已經準備好接收資料
 - 支援單線半雙工通訊

 - 可用DMA(Direct Memory Access)設定多重緩衝區並進行資料交換。
  
 - TX/RX都有各自獨立的Enable Bit(TE、RE)

 - 3個傳輸檢測標誌

 - 檢測控制

USART 特性描述
 - 4個錯誤檢測標誌

 - 支援10種中斷

 - 多處理器通訊,最多可將16個節點串成同一個網路(因USART_CR2_ADD只有四位元)。

 - 2種喚醒接收器的方式

USART Block Diagram
======================================
資料長度根據USART_CR1暫存器中的M位選擇8或9位元
![](/embedded/USART_pic296.jpg)

在起始位期間,TX處於低電位,在停止位期間,TX處於高電位。
另外空閒符號則全由'1'組成,後面接著下一個資料的開始位('1'的位數也包含資料的停止位元位數);
中斷符號則全由'0'所組成(包含資料的停止位也是'0'),在中斷時,發送器會再插入1或2個停止位('0')
Ref: [RM0090 Reference Manual P.949](http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf)

.. image:: /idleandbreak.png
* 此通訊界面以三個腳位與其他設備連接。任何USART雙向通信至少需要兩個腳位:接收資料輸入(RX)和發送資料輸出(TX)
    - RX: 接收資料輸入。藉由Oversampling技術判斷有效資料及噪音
    - TX: 發送資料。若發送器沒有被啟用,則此腳位會回到I/O port設定狀態。當發送器被啟動時,如果沒有傳送數據,則TX保持高電位。在單線半雙工模式或Smartcard 模式時,此I/O同時被用於資料的傳送和接收(以USART角度來看此情況,TX負責傳輸資料,但接收資料由SW_RX負責)。

* 以USART傳輸資料時,串列資料由下列frames組成:  
    - 傳輸或接收資料之前,由Idle Line表示。
    - 一個start bit
    - 一個資料word,可為8/9 bits,用least significant bit做資料排序。根據USART_CR1暫存器中的M位選擇8或9位元決定資料長度。
    - 一組0.5, 1, 1.5, 2 stop bits,用以表示該次frame傳輸完畢。

傳送器
============================
傳送器依據USART_CR1 M位的狀態來決定發送8或9位元的資料。
當transmit enable bit(TE)被設定時,資料transmit shift register經由TX腳位送出,
同時,相對應的時鐘脈衝會由SCLK腳位輸出。
* 另外包含以下數種register: 
    - 狀態暫存器(USART_SR)
    - 資料暫存器(USART_DR)
    - baud rate暫存器(USART_BRR)。儲存由fractional baud rate generator產生的傳輸速率,以12位整數和4位小數表示
    - Guardtime暫存器(USART_GTPR),供Smartcard模式使用

* 另外在同步模式中,需要此一腳位:
    - SCLK: 在同步模式下,送出傳送器目前的時脈數值。可對應至SPI master mode(在start bit和stop bit不送出clock訊號,另外可用軟體選擇是否在最後一個data bit送出clock訊號)。送出時脈數值的同時,資料可以在RX端被接收。這種特性可用於控制擁有shift暫存器的周邊設備(例: LCD驅動)。時脈的相位以及訊號極性可用軟體設定。在Smartcard模式下,SCLK可對Smartcard提供本身的時脈。
   
* 在Hardware flow control中,則另外需要下列兩個腳位:
    - nCTS: 阻擋發送資料。若在高電位,則當目前資料傳送結束後,中斷下一次的資料傳送  
    - nRTS: 請求發送資料。若在低電位,則表示USART已經準備好接收資料

USART data frame & M bit
-------------------------

每次傳輸資料時,USART會以一個frame作為一次傳輸的單元。

![](/embedded/USART_DataFrame.jpg)


```
在起始位(start bit)期間,資料發送端(TX)處於低電位;在停止位(stop bit)期間,資料發送端(TX)處於高電位。
```

![](/embedded/USART_8bit_length.jpg)


```
若將USART_CR1_M 設定為0,則發送的data frame會變成這樣。

Idle & break frame的長度也會與data frame的長度一樣。Idle 會發送一個frame的高電位、break則是發送一個frame的低電位。

發送break frame之後,會另外插入1~2 stop bit,藉此區分下一次的data frame(因為data frame的開頭也是低電位)。
```

![](/embedded/USART_9bit_length.jpg)


```
若將USART_CR1_M 設定為1,則發送的data frame會比上一張圖多一個bit。

Idle & break frame的長度也會變長1 bit。
```



10種中斷
-------
 - CTS改變(CTSIE, CTS interrupt enable)
 - LIN中斷檢測(LBDIE, LIN break detection interrupt enable)
 - 傳送緩衝區空(TXEIE, Data buffer empty interrupt enable)
 - 傳送完成(TCIE, Transmission complete interrupt enable)
 - 接收緩衝區滿(RXNEIE, Data buffer not empty interrupt enable)
 - 空閒線路檢測(IDLEIE, Idle interrupt enable)
 - 溢出錯誤(Overrun error)
 - Frame錯誤(Framing error)
 - 噪音錯誤(Noise error)
 - 檢驗錯誤(Parity error, PEIE)

3個傳輸檢測標誌
------------
 - 接收緩衝區滿(RXNE,Data buffer not empty)
 - 傳送緩衝區空(TXE,  Data buffer empty)
 - 傳輸結束(TC,  Transmission complete)




Tx傳送器
=======

 - 傳送器依據USART_CR1的M位狀態來決定發送8或9位元的資料。
 - 當transmit enable bit(TE)被設定時,在transmit shift register的資料會經由TX腳位送出,同時,相對應的時鐘脈衝會由SCLK腳位輸出。

資料的傳送
------------------------------------
在USART發送期間,TX首先傳送資料的最低有效位元(least significant bit),因此在此模式中,USART_DR和transmit shift register之間包含一個緩衝器(TDR)。每個資料再傳送前都會有一個低電位的起始位;之後跟著的停止位元數目,則可由使用者決定0.5, 1, 1.5或2
   - 1 bit的停止位: 預設的默認停止位位元數
   - 2 bits的停止位: normal USART, single-wire 和 modem modes
   - 0.5 bits的停止位: Smartcard mode接收數據用
   - 1.5 bits的停止位: Smartcard mode發送數據用
----------

在USART發送期間,TX首先傳送資料的最低有效位元(least significant bit)。在此模式中,USART_DR與內部匯流排和transmit shift register會之間包含一個緩衝器(TDR)。

每個資料在傳送前都會有一個低電位的起始位(start bit);資料傳完之後會接著一組停止位元(stop bit)。

在傳送資料的過程中,不可以去更改TE的設定,否則會導致baud rate counter停止,目前正在傳的資料也會毀損(因只傳了一部份)。
TE被開啟時,會立即送出一個idle frame。

停止位元的數目可由使用者決定為0.5, 1, 1.5或2 bits:

   - 1 bit的stop bit: 預設的停止位位元數
   - 2 bits的stop bit: 一般USART模式、單線傳輸模式和modem modes
   - 0.5 bits的stop bit: Smartcard mode接收數據用
   - 1.5 bits的stop bit: Smartcard mode接收或發送數據用

傳送idle frame時,會連stop bits一起送出,因idle frame本身就包含stop bits。
傳送break時,會連續傳輸10個低電位bits(包含1個stop bit,此時M=0),或是11個低電位bits(包含2個stop bits,此時M=1)。但是不可能傳輸過長的break(大於10/11低電位bits)

**stop bits其實不算是個bit,他是傳輸結束後的一段時間(period),用以區隔每個傳輸的資料,其功用是在非同步傳輸的時候可以告訴接收器,資料傳輸已經結束。透過增加stop bits的長度,可讓接收器能有足夠的時間可以處理該資料**

**另外,由於資料搬移到transmit shift register中最少需要1/2 baud clock,因此在Smartcard mode的接收中,最少必須設定0.5 bit的stop bits**

Ref: [RM0090 Reference Manual P.952](http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf)


傳送器的設定
------------------------------------
   1. 設定USART_CR1暫存器的UE位來啟動傳輸
   2. 設定USART_CR1暫存器的M位決定資料長度
   3. 設定USART_CR2暫存器中的STOP位來決定停止位的長度
   4. 採用多緩衝器的話,則須設定USART)CR3的DMAT啟動DMA,並設置DMA的暫存器
   5. 設置USART_CR1的TE位,在第一筆資料傳送前,傳送一個空閒的frame
   6. 利用USART_BRR暫存器設定baud rate
   7. 將欲發送的資料放入USART_DR中,重複步驟7
----------

當資料放入USART_DR會由硬體清除TXE位,則表示:
   1. 資料已從TDR中進入transmit shift register,資料的發送已開始
   2. TDR暫存器已被清空
   3. 下一筆資料可放入USART_DR中
![](/usart_fig298.jpg)

若TXEIE位的設置,則會產生一個中斷:
   如果USART正在發送資料,對USART_DR的寫入會把資料移到TDR暫存器中,並在目前的資料傳送結束後把該筆資料移進transmit shift register中
   如果USART沒有在發送資料,則對USART_DR的寫入會把資料直接放入transmit shift register中,並啟動傳送,當傳送開始時,硬體會立即設定TXE位
![](/embedded/USART_DataTransmission.gif)

一個frame的資料發送完畢後,TC位會被設定,如果USART_CR1中的TCIE有被設定,則會產生一個中斷,先讀取USART_SR暫存器,再寫入USART_DR暫存器,則可清除TC位
![](/usart_transmiter.png)

設定流程如下:

   1. 設定USART_CR1的UE為1來啟動傳輸,如圖中的(a)
   2. 設定USART_CR1的M決定資料長度,如圖中的(b)
   3. 設定USART_CR2中的STOP位來決定停止位元的長度,如圖中的(c)
   4. 採用多重緩衝器的話,則須設定USART_CR3的DMAT啟動DMA,並按照多重緩衝器的章節內容去設定DMA,如圖中的(d)
   5. 利用USART_BRR暫存器設定baud rate,如圖中的(e)
   6. 設定USART_CR1的TE為1,在第一筆資料傳送前,傳送一個空閒的frame,如圖中的(f)
   7. 將欲發送的資料寫入USART_DR中,此動作會一併清除TXE,如圖中的(g)。
   8. 若有多筆資料要傳送,則重複步驟7.,如圖中的(l)。
   9. 當最後一筆資料寫入USART_DR時,要等到TC=1才可以做其他動作。TC=1代表所有資料傳輸已經結束。此動作為的是避免最後一筆資料在傳輸時毀損(因USART此時可能已經被關閉,或是進入halt mode)。


當資料放入USART_DR會由硬體清除TXE位,如圖中的(h),則表示:

   1. 資料已從TDR中放入transmit shift register,而且資料已開始傳送
   2. TDR暫存器無資料
   3. 下一筆資料可放入USART_DR中,並且不會覆蓋前一筆資料


若設定TXEIE為1,則會產生一個中斷,如圖中的(i):

   - 如果USART正在發送資料,對USART_DR的寫入會把資料移到TDR暫存器中,並在目前的資料傳送結束後,把TDR的資料移進transmit shift register中
   - 如果USART沒有在發送資料,則對USART_DR寫入資料時,會直接把該筆資料放入transmit shift register中,並啟動傳送,當傳送開始時,硬體會立即設定TXE位。

當一個frame的資料發送完畢(送出stop bits後),TC位會被設定為高電位,如圖中的(j),如果USART_CR1中的TCIE有被設定,則會產生一個中斷,如圖中的(k)。

當最後一筆資料寫入USART_DR後,一定要等到TC=1才可以把USART關掉,或是讓整個控制器進入低功耗模式。

在一般模式下,若要清除TC,可以直接對TC寫入0。如果是使用多重緩衝區模式,則要先讀取USART_SR暫存器,再對USART_DR暫存器做寫入動作。

![](/embedded/USART_pic299.jpg)


傳送斷開符號
------------------------------------
(代補)
 - 透過設定USART_CR1的SBK位,可以發送一個斷開符號,斷開符號的長度取決於M位。

 - 如果SBK=1,則在目前的資料發送後,在TX線上再發送一個斷開符號。當斷開符號傳送完成後,會由硬體重設SBK至0。

傳送空閒符號
------------------------------------
(代補)
 - USART會由硬體在最後一個斷開符號的結束處插入一個'1',確保能辨識下一個資料的起始位。


傳送空閒符號
------------------------------------
 - 設置USART_CR1的TE,會使得USART在發送第一筆資料前,發送一個空閒符號,喚醒接收端。


接收器
====================================
接收器依據USART_CR1 M位的狀態來決定接收8或9位元的資料。
 - 接收器依據USART_CR1 M位的狀態來決定接收8或9位元的資料。

Oversampling
------------

定義:在訊號處理中,oversampling 是以取樣頻率大於Nyquist rate的取樣訊號處理。因此取樣頻率高於Nyquist rate,即可讓有限的頻寬完美重現。

接收斷開符號
目的: 可用於改善 影響解析度、減少雜訊和避免aliasing

![](/embedded/oversampling_tmmg.jpg)

起始位元偵測(oversampling)
------------------------------------
設置SBK可發送一個斷開符號。

When a break character is received, the USART handles it as a framing error.
![](/usart_fig300.jpg)


在USART中,如果辨認出一個特殊的採樣序列( 1 1 1 0 X 0 X 0 X 0 0 0 0 ),則認定偵測到一個起始位。不論是用哪種oversampling(16 or 8)方法,這個序列都一樣。

如果在第一次採樣(第3、5、7採樣點)都收集到0,而且第二次採樣(第8、9、10採樣點)也是都收集到0,則認定已經偵測到start bit(此時RXNE會設定為1,若RXNEIE=1會額外發出interrupt)。

如果在第一次採樣(第3、5、7採樣點)收集到2個以上的0,而且第二次採樣(第8、9、10採樣點)也是收集到2個以上的0,也會認定已經偵測到start bit(此時RXNE會設定為1,若RXNEIE=1會額外發出interrupt)。但是會另外去把NE設定為1,因為可能在接收過程中有噪音訊號。

**如果這兩次採樣結果不相符(例: 一次採到2個0,另一次採到2個1),則接收端停止start bit偵測、回到idle state並等待下一次的電壓下降。**

如果在這兩次採樣過程中,有任何一次只收集到2個0(但另一次收集到3個0),還是會認定已經偵測到start bit,但也會把NE設定為1,理由同上。


**採樣的時間間隔**

![](/usart_sampling.png)

假設baud rate = 9600 bps,則一個bit的傳輸時間為104us,usart會在接收器啟動後的52us,開始採樣

若偵測到開始位元,則開始接收資料,反之則等待104us,再採樣一次

停止位元偵測(oversampling)
-----------------------------------------------------

Stop bits的接收數目可以由USART_CR2去設定,在一般模式可選擇1 or 2,在smartcard模式則可選擇0.5 or 1.5。

   1. 0.5 stop bit(用於smartcard模式的接收器): 不進行採樣,所以沒辦法偵測到framing錯誤,或是偵測出break frame。
   2. 1 stop bit: 在第8, 9, 10個採樣點進行採樣
   3. 1.5 stop bit(用於smartcard模式,包含接收器和傳送器): 1.5 stop bit的採樣是在第16, 17, 18個採樣點進行(在stop bit開始後1個baud clock之後才開始採樣)。而1.5 stop bit可以分成前0.5和後1 stop bit。在前0.5 stop bit甚麼事都不做,在後1 stop bit的中間(16, 17, 18)才開始採樣。在smartcard模式傳輸資料時,必須要確保每筆資料都有正確地送出去。所以接收器一定要把USART_CR1的RE設定為1,然後stop bit會被拿來偵測是否有parity error產生。如果發生了parity error,smartcard會在採樣時強制把資料訊號拉至低電位(此為NACK訊號,這種訊號會被另一端標記成framing error)。在1.5 stop bit結束時,FE和RXNE會同時被設定為1。其餘請參考smartcard章節。
   4. 2 stop bits: 在第一個stop bit會對第8, 9, 10個採樣點進行採樣,如果在第一個stop bit就偵測出framing error,會直接去設立framing error旗標,然後第二個stop bit就不會拿來偵測framing error了。RXNE會在第一個stop bit結束採樣時被設立。


資料的接收
------------------------------------
 - 在USART接收期間,RX從資料最低有效位元(least significant bit)開始接收,因此在此模式中,USART_DR和received shift register之間包含一個緩衝器(RDR)。


接收器的設定
------------------------------------

![](/usart_recevier.png)


   1. 設定USART_CR1的UE為1來啟動USART接收,如圖中的(a)
   2. 設定USART_CR1的M決定資料長度,如圖中的(b)
   3. 設定USART_CR2的STOP來決定停止位元的長度,如圖中的(c)
   4. 若需要採用多重緩衝器接收資料,則須設定USART_CR3的DMAR啟動DMA,並按照多重緩衝器的章節內容去設定DMA,如圖中的(d)
   5. 利用USART_BRR設定baud rate,如圖中的(e)
   6. 設定USART_CR1暫存器中的RE,此動作會啟動接收器並開始偵測起始位,如圖中的(f)

* 當資料被接收到後:
    1. 硬體會設定RXNE位,表示received shift register中的資料已移入RDR中,亦即資料已被接收並可被讀出(也包含了已經偵測到的錯誤),如圖中的(g)
    2. 若USART_CR1中的RXNEIE被設定時,會產生一個中斷,如圖中的(h)
    3. 資料接收期間如檢測到frame錯誤或是噪音、溢出錯誤等問題,相關的標誌將被設定(FE、NF、ORE)
    4. 若使用多重緩衝區模式,RXNE在每個字元接收後會被設置,並在DMA讀取RDR之後被清除
    5. 在一般模式(單緩衝區)下,藉由軟體讀取USART_DR可清除RXNE,也可以直接對RXNE寫入0。RXNE一定要在"接收下一筆資料"這個動作結束前被清除,以免產生溢出錯誤


接收斷開符號
------------------------------------
 - USART在接收斷開符號後,該符號處理流程等同framing error。


接收空閒符號
------------------------------------
When an idle frame is detected, there is the same procedure as a data received character
plus an interrupt if the IDLEIE bit is set.
 - 當空閒符號被偵測到時,該符號處理流程等同一般資料,但如果USART_CR1的IDLEIE被設置時,還會產生一個中斷

接收器對時鐘誤差容忍度
-------------------

* 必須要使整個時脈系統的時鐘誤差處於USART接收器的容許範圍內,USART接收器才能夠正常運作。時脈系統的誤差來源有以下幾種: 
    - DTRA: 傳送器的誤差(Deviation due to TRAnsmitter error)。這誤差也包含了傳送器本身的時脈誤差。
    - DQUANT: 接收器的baud rate量化出錯(Devation due to baud rate QUANtization of the receiver)
    - DREC: 接收器的時脈誤差(Deviation due to RECeiver's local oscillator)
    - DTCL: 資料傳輸線的錯誤(Deviation due to Transmission Line)。通常起因於傳輸器,在傳輸資料時,從高電位轉至低電位、或從低電位轉至高電位,在電位轉換期間出現時間誤差。

溢出錯誤
* 總體而言: DTRA + DQUANT + DREC + DTCL < USART接收器的容許上限

* USART接收器的對於時脈誤差的容許上限,取決於下列選項: 
    - USART_CR1的M,可決定使用10/11資料位元。
    - USART_CR1的OVER8,可決定使用8/16 oversampling方法。
    - 是否有使用fractional baud rate
    - USART_CR3的ONEBIT,可決定使用單一採樣點或是三個採樣點。

4種錯誤檢測
==========

溢出錯誤(Overrun error)
------------------------------------
An overrun error occurs when a character is received when RXNE has not been reset. Data
can not be transferred from the shift register to the RDR register until the RXNE bit is
cleared.
 - 在RXNE沒有重設為0的情況下,此時又接收到一筆新資料,則會發生溢出錯誤,如圖中的(i)。在RXNE沒有被清除時,資料將無法從Received shift register轉入RDR。
 - 在一般情況下,本身不產生中斷,在DMA情況下,則由EIE產生中斷,經檢驗USART_SR的ORE可得知溢出錯誤

The RXNE flag is set after every byte received. An overrun error occurs if RXNE flag is set
when the next data is received or the previous DMA request has not been serviced. When
an overrun error occurs:
當溢出錯誤產生時:

● The ORE bit is set.
   1. USART_SR中的ORE將被設定為1,如圖中的(j)
   2. RDR中的內容不會被清除,因此讀取USART_DR仍可以得到之前的資料
   3. Received shift register中的資料將被覆蓋。覆蓋完之後,在接下來overrun錯誤發生的過程中,所有接收到的資料都會遺失。
   4. 如果RXNEIE被設為1,或是EIE(Error interrupt enable)和DMAR被為1,則會產生一個中斷,如圖中的(k)
   5. 依序讀取USART_SR和USART_DT暫存器,可清除ORE

● The RDR content will not be lost. The previous data is available when a read to
USART_DR is performed.
**當ORE位被設置時,表示至少有一個資料已遺失,有以下兩種可能性: **

● The shift register will be overwritten. After that point, any data received during overrun
is lost.
   1. 如果RXNE=1,表示之前的資料還在RDR中,且可被讀出
   2. 如果RXNE=0,表示之前的資料已被讀走,RDR已無資料可被讀取。若正在讀取RDR中的上一筆資料,而讀取時又接收到新的資料(這筆新的資料會遺失),就會發生這種情況。另一種情況是正在讀取USART_SR以及USART_DR的過程中,有新的資料被讀進來(但這筆資料會遺失),這也會導致相同結果。

● An interrupt is generated if either the RXNEIE bit is set or both the EIE and DMAR bits
are set.

● The ORE bit is reset by a read to the USART_SR register followed by a USART_DR
register read operation.
噪音錯誤(Noise error)(select the proper oversampling method)
-----------------------------------------------------------

Note: The ORE bit, when set, indicates that at least 1 data has been lost. There are two
possibilities:
 - 接收器具備不同oversampling方法供使用者選擇(但在同步模式不可選擇),此方法可以區分有效資料以及噪音,並修復已接收到的資料。
 - 在一般情況下,本身不產生中斷,而由RXNE產生中斷,經檢驗USART_SR的NF得知錯誤
 - 在DMA情況下,則由EIE產生中斷,經檢驗USART_SR的NF得知錯誤

● if RXNE=1, then the last valid data is stored in the receive register RDR and can be
read,
 - 設定USART_CR1中的OVER8,即可選擇16個或8個baud clock的採樣,見Fig. 250和Fig. 251:
    - OVER8 = 1: 使用8次採樣可以達到更高速的資料傳輸(最高速為fPCLK/8),相對地接收器會沒辦法容許太多的時脈誤差。
    - OVER8 = 0: 使用16次採樣,則接收器可容許較多的時脈誤差,但傳輸速率會被限制於fPCLK/16

● if RXNE=0, then it means that the last valid data has already been read and thus there
is nothing to be read in the RDR. This case can occur when the last valid data is read in
the RDR at the same time as the new (and lost) data is received. It may also occur
when the new data is received during the reading sequence (between the USART_SR
register read access and the USART_DR read access).
 - 設定USART_CR3中的ONEBIT,可選擇不同的噪音評估法:
    - ONEBIT = 0: 採樣資料中心的3個bits,若此3 bits不完全相等,則NF會被設定為1。適合用於容易產生噪音訊號的環境,如果偵測到有噪音(NF=1),會把該次收到的資料拋棄,因為NF=1代表採樣過程中可能有產生突波、干擾訊號等。
    - ONEBIT = 1: 只採樣資料中心的單一bit,此時NF就絕對不會被設定。適合用於沒有噪音訊號的環境,並且讓接收器容許更多的時脈誤差。

 - 若在資料接收過程中檢測到噪音時:
    - NF會在RXNE升緣時被設定
    - 該次無效資料會從received shift register移入USART_DR
    - 在單一byte通訊模式不會直接產生中斷,而是在NF被設定為1時(此時RXNE會一併設定為1),由RXNE來產生中斷;使用多重緩衝器模式時,如果USART_CR3暫存器中的EIE被設定為1,則會產生一個中斷

Selecting the proper oversampling method
![](/oversampling16.png)

![](/oversampling8.png)

![](/noisedetection.png)

![](/noisedetectionsampledata.png)


Frame錯誤(Frame error)
------------------------------------
The receiver implements different user-configurable oversampling techniques (except in
synchronous mode) for data recovery by discriminating between valid incoming data and
noise.

The oversampling method can be selected by programming the OVER8 bit in the
USART_CR1 register and can be either 16 or 8 times the baud rate clock (Figure 250 and
Figure 251).
 - 起因於傳輸端/接收端沒有同步、或者傳輸線路上有大量的噪音,使得stop bit沒有在預期的時間內被識別出來。
 - 在一般情況下,本身不產生中斷,而由RXNE產生中斷,經檢驗USART_SR的FE可得知Frame錯誤
 - 在DMA情況下,則由EIE產生中斷,經檢驗USART_SR的FE得知錯誤

Depending on the application:

● select oversampling by 8 (OVER8=1) to achieve higher speed (up to fPCLK/8). In this
case the maximum receiver tolerance to clock deviation is reduced (refer to
Section 26.3.5: USART receiver tolerance to clock deviation on page 760)
當Frame錯誤被檢測出時:

● select oversampling by 16 (OVER8=0) to increase the tolerance of the receiver to clock
deviations. In this case, the maximum speed is limited to maximum fPCLK/16
Programming the ONEBIT bit in the USART_CR3 register selects the method used to
evaluate the logic level. There are two options:
   1. FE位被硬體設定為1,如圖中的(l)
   2. 無效的資料從received shift register移入USART_DR中
   3. 在單一byte通訊模式不會直接產生中斷,而是在NF被設定為1時(此時RXNE會一併設定為1),由RXNE來產生中斷;使用多重緩衝器模式時,如果USART_CR3暫存器中的EIE被設定為1,則會產生一個中斷,如圖中的(k)

● the majority vote of the three samples in the center of the received bit. In this case,
when the 3 samples used for the majority vote are not equal, the NF bit is set
依序讀取USART_SR和USART_DR暫存器可恢復FE至0

● a single sample in the center of the received bit
奇偶檢測CONTROL(Parity error)
----------------------------
 - Parity control是用來確保傳輸資料的正確性。其原理是在傳輸端產生一個parity bit,然後在接收端可以重新計算parity bit以確保在傳輸過程沒有發生錯誤。
 - 在STM32,它可以透過設定USART_CR1 register的PCE bit來打開。STM32的frame長度是由M bit所決定,所以USART的frame有以下這些可能格式:

  Depending on the application:
![](/frame_formats.png)

  – select the three samples’ majority vote method (ONEBIT=0) when operating in a
  noisy environment and reject the data when a noise is detected (refer to
  Figure 105) because this indicates that a glitch occurred during the sampling.
parity依算方式的不同分成兩種方式,even parity和odd parity

  – select the single sample method (ONEBIT=1) when the line is noise-free to
  increase the receiver’s tolerance to clock deviations (see Section 26.3.5: USART
  receiver tolerance to clock deviation on page 760). In this case the NF bit will
  never be set.
 - Even parity
    - 如果一個frame內1的數量是偶數,則在 even parity的情況下會把parity bit設為0。

When noise is detected in a frame:
    - E.g.: 假設 data=00110101; 因為有 4 bits被設為1,而且我們選擇的是 even parity(PS bit in USART_CR1 = 0),所以 parity bit被設為0。

● The NF bit is set at the rising edge of the RXNE bit.
 - Odd parity

● The invalid data is transferred from the Shift register to the USART_DR register.
    - 如果一個frame內1的數量是奇數,則在 odd parity的情況下會把parity bit設為0。

● No interrupt is generated in case of single byte communication. However this bit rises
at the same time as the RXNE bit which itself generates an interrupt. In case of
multibuffer communication an interrupt will be issued if the EIE bit is set in the
USART_CR3 register.
    - E.g.: 假設 data=00110101; 因為有 4 bits被設為1,而且我們選擇的是 odd parity(PS bit in USART_CR1 = 1),所以 parity bit被設為1。

The NF bit is reset by a USART_SR register read operation followed by a USART_DR
register read operation.
 - 接收後會做 parity checking
    – 對接收的資料進行檢測(Checks parity of received data byte)

Note: Oversampling by 8 is not available in the Smartcard, IrDA and LIN modes. In those modes,
the OVER8 bit is forced to ‘0 by hardware.
    - 如果 parity check 失敗了,USART_SR register的PE flag會被設立,然後如果USART_CR1 register的PEIE bit也有被設立的話,還會產生中斷。

.. image:: /oversampling16.png
    - PE flag最後在軟體執行(a read from the status register followed by a read or write access to the USART_DR data register)時被清除。


.. image:: /oversampling8.png
 - 傳送前會做 parity generation
    – 發送檢測位(Transmits parity bit)

    - 如果USART_CR1的PCE bit被設立,那麼MSB會被改成parity bit(PS=0 是even parity, PS=1 是odd parity)

.. image:: /noisedetection.png
        - MSB: Most Significant Bit,代表位數最大的那個bit

.. image:: /noisedetectionsampledata.png
        - LSB: Least Significant Bit,代表位數最小的那個bit

鮑率的設定
=========

 - 接收器和傳送器的Baud rate分別由USART_BRR設置USARTDIV的整數部分(Mantissa)及小數部分(Fraction),計算方式如下所示:

Fractional baud rate generation的設定
====================================
The baud rate for the receiver and transmitter (Rx and Tx) are both set to the same value as
programmed in the Mantissa and Fraction values of USARTDIV.
![](/baud.png)
Ref: [RM0090 Reference Manual P.959](http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf)

.. image:: /baud.png
其中USARTDIV為一個無號的定點數(unsigned fixed point number),fCK為給周邊設備的時鐘。

USARTDIV is an unsigned fixed point number that is coded on the USART_BRR register.
   - 當OVER8 = 0 時,小數部分佔USART_BRR的DIV_Fraction[3:0],共 4 bits
   
   - 當OVER8 = 1 時,小數部分佔USART_BRR的DIV_Fraction[2:0],共 3 bits,其中DIV_Fraction[3]應該保持'0'

● When OVER8=0, the fractional part is coded on 4 bits and programmed by the
DIV_fraction[3:0] bits in the USART_BRR register
**USART_BRR被更新後,baud rate的計數器中的值也會同時被更新,因此在傳輸途中不應該更新USART_BRR中的值。
  另外,如果TE或RE被分別禁止,則baud rate的計數器也會停止計數**

● When OVER8=1, the fractional part is coded on 3 bits and programmed by the
DIV_fraction[2:0] bits in the USART_BRR register, and bit DIV_fraction[3] must be kept
cleared.
使用stm32f407vgt6官方lib時,會透過檔案中設定的時脈和baud rate去換算出USART_BRR的值,包含整數與小數部分。.

Note: The baud counters are updated to the new value in the baud registers after a write operation
to USART_BRR. Hence the baud rate register value should not be changed during
communication.
   - BRR(USARTDIV) 的值 Mantissa = 0x088B ; Fraction = 0x08 =>計算方式 0x88B->0d2187 + 8/16 = 2187.5

if over8=0 計算baud rate的方式: baud rate = usart時脈/(8 * (2-over8) * DIV).
 
   - usart時脈42Mhz, baud rate = 42000000/(8 * 2 * 2187.5) = 1200

usart是接在APB BUS上方,stm32f407vgt6有兩組APB各對應不同usart。usart時脈要看APB供應的時脈,
APB時脈要透過RCC和PLL設定去看clock tree。.

   - 預設stm32f4-discovery這塊板子外部震盪器(HSE_VALUE)是8Mhz(官方lib好像設定成25Mhz)。.
   - 8Mhz透過pll_M(8)除頻輸入PLL =>8Mhz/8=1Mhz.
   - 1Mhz輸入PLL,透過pll_N(0x5400)倍頻再透過pll_P(2)除頻,作為sysclk => (1Mhz * 0x5400>>6)/2 = 168Mhz.
   - sysclk轉接HCLK都是168Mhz.
   - HCLK>>2轉給PCLK1 => 168Mhz>>2 = 42Mhz.

多處理機通訊
===========

 - 除了一對一通訊之外,也可以將許多USART串成一個小型網路(multiprocessor communications)。
 - 在這些USART中,可以選出一個USART作為master,其餘的就做為slave。而master的TX會連到所有slave的RX,所有slave的TX則會連接到邏輯AND後,再連接至master的RX。
 - USART的地址放在USART_CR2_ADD,因為只有4位元,所以最多支援到16個節點。

IrDA SIR ENDEC
............................

IrDA:
=======
 - 在多處理機通訊模式下,我們會希望只把訊息傳給該知道的機器就好,如此一來能夠減少不必要的傳輸動作(把資料也傳給其他機器)。

IrDA 是一種標準化紅外線數據傳送方式;STM32f4支援利用USART輸出訊號配合轉換電路,轉換成符合IrDA 標準的訊號,實現紅外線傳輸.
 - 沒接收到資料的機器,可以用mute功能使該機器進入mute模式,在mute模式下的機器行為: 
    - 無法變更接收器的任一個status bit
    - 與接收器相關的interrupt會停用
    - USART_CR1的RWU會被設定為1。RWU可被硬體自動控制,或是在某些限制條件下用軟體變更。

 - 若要使機器離開mute模式,可以用下列兩種方式的其中一種,端看使用者如何設定USART_CR1的WAKE
    - 若WAKE被設定為0,機器進入idle line偵測
    - 若WAKE被設定為1,機器進入address mark偵測

Idle line detection(WAKE=0)
---------------------------

 - 在接收端處於靜默(mute mode)時,可透過發送空閒符號(即所有位均為'1'的資料),喚醒接收端。

 - 若RWU被設定為1,則USART進入mute模式。

 - 如果在mute模式時偵測到Idle frame,則機器會醒過來並進入一般USART模式。此時RWU會被硬體清除(=0),但是USART_SR的IDLE不會被設定為1。

 - RWU也可以用軟體設定成0。

![](/embedded/USART_pic303.jpg)

Address mark detection(WAKE=1)
------------------------------
 
 - 在此模式下,如果接收到的資料位元,其MSB是1,就會被當成位址,若MSB為0,則當成一般資料。在位址資料(1 byte)中,最後4個LSB是放接收者的位址,而接收到這筆資料的機器會拿自己的USART_CR2的ADD(放該機器的位址)與這4個LSB做比較,若相同則清除RWU位,後面的資料將能正常接收。

register 設定:
===============
USART_CR3 : IREN = 1; SCEN, HDSEL = 0.
 - 如果接收到的位址資料,比較之後與自己的位址不相符,該機器就會進入mute模式。此時RWU會被硬體設定為1,而RXNE不會被設定成1(即使有收到位址資料)、沒有interrupt產生、也沒有對DMA送出請求,因為機器已經進入mute模式。

USART_CR2 : LINEN , STOP, CLKEN = 0.
 - 如果接收到的位址資料與自己的位址相符,該機器會回到一般USART模式。此時RWU會被清除,其餘的資料也會按順序被接收進來,而RXNE也會因為RWU被清除的關係,被設定為1(因為收到位址資料,而且是與自己的位址相符)。

IrDA SIR 實體層:
 - 在接收器的緩衝區沒有資料時(USART_SR的RXNE為0),可以對RWU寫入0或1。有資料時,對RWU的寫入動作一律不承認。

![](/embedded/USART_pic304.jpg)

USART 與 SPI之關係
=================

 - SPI:它是主從式的架構,通常一個主設備和多個從設備,由四條信號線組成:SCLK、MISO、MOSI、CS

.. image:: /irda.PNG
    - MOSI:master output, slave input,主設備輸出

SIR Transmit encoder 會把 USART 的Non Return to Zero 轉換成 IrDA 輸出訊號.
    - MISO:master input, slave output,主設備輸入

IrDA 輸出是一種 Return-To-Zero,Inverted 形式的訊號, 用一個紅外線 pulse 表示一個 logic 0.
    - SCLK:serial clock,clock信號,由主設備產生

每一個紅外線 pulse 相當於 3/16 的 bit period, 而 IrDA mode 下的 USART 的 bit rate 最高為 115.2 Kbps. 
    - CS:chip select (optional)

(下圖 IrDA_OUT).
 - USART在全雙工的模式(特別是同步模式)下,也有類似的訊號

.. image:: /normal_mode.PNG
    - TX:傳送訊號給周邊

    - RX:週邊設備傳送給主設備的訊號

    - SCLK:由主設備產生的clock訊號

USART SYNCHRONOUS MODE
......................
register 設定:
以上是兩者有類似的地方

USART_CR2 : CLKEN = 1;LINEN = 0;

USART_CR3 : SCEN, HDSEL, IREN = 0;

特性:

Synchronous 指的是TX 跟 RX 用同一個 Clock, 這個clock(SCLK)由 TX 端送出, 同時需要TE = 1,clock 才會產生;
(UART 4,5 不支援 Synchronous mode)
STM32 USART的MODE
==========================

.. image:: /synchronous_transmission.png

在傳送 start bit, stop bit 時不會有 clock pulse 從 SCLK 送出,clock 處於 logic 0;
Synchronous mode
===================

Last bit clock pulse(LBCL),確定第8(9,如果 M=1)bit的clock pulse會不會輸出;(FOR WHAT???????)
若要使用此模式,要把USART_CR2的CLKEN設定為1。下列設定必須要設為0: 
 
 - USART_CR2的LINEN
 - USART_CR3的SCEN、HDSEL、IREN

CPOL = 0: high 為 logic 1 ; CPOL =1 :high 為 logic 0;
USART允許使用者以master mode控制雙向同步串列傳輸。SCLK腳位會輸出傳送器的時脈,而在送出start bit以及stop bit時,SCLK不會輸出時脈。根據USART_CR2的LBCL設定,可以決定是否在最後一個資料bit(該bit代表位址)於SCLK輸出時脈。USART_CR2的CPOL允許使用者選擇時脈極性,而USART_CR2的CPHA允許使用者選擇外部時脈的相位。

CPHA = 0: clock pulse 發生在bit period 的後半段中;CPHA = 1: clock pulse 發生在bit period 的前半段;差別在於bit period中間的edge是正/負緣觸發;
在idle state、前同步碼(preamble)以及傳送break時,外部SCLK腳位不會被啟用。

master mode: can't recieve or send data using the input clock;
在同步模式下,USART傳送器的行為與非同步模式一樣。但是因SCLK與TX同步(因CPOL與CPHA的設定),TX送出的資料會是同步的。

half-duplex: can't recieve and send at the same time;
此模式下的USART接收器會與非同步模式的行為不同。如果RE=1(CR1的設定),則資料會在SCLK的rising或falling edge被採樣(看CPOL與CPHA的設定),並且不使用任何oversampling。Setup以及hold time必須要明確地保留(依據baud rate變化而有所不同: 1/16 bit time)。

因為同步, 所以不需要oversampling(Ws >> 2Wm)
SCLK與TX須一同使用,所以只有在傳送器啟用(TE=1,CR1的設定)而且正在傳送資料(USART_DR)的情況下,SCLK才會輸出時脈。意即不太可能只接收同步資料,卻不傳送資料。

setup time, hold time
當傳送器和接收器皆關閉時(TE=RE=0),LBCL、CPOL、CPHA必須要被設定,以確保SCLK正常運作。在傳送器或接收器打開時,這三個設定不可以去動。

建議同時設定TE和RE,以減少接收器的setup和hold time。

HARDWARE FLOW CONTROL
......................
利用 nCTS 跟 nRTS 控制 TX , RX 要不要再傳送或接收 data
另外,USART只支援master mode,不論是接收或傳送資料,皆無法使用外部時脈(因SCLK是單向輸出)。

.. image:: /hardware_control_2usarts.png


RTS Flow Control
========================
RTSE(RTS flow control enable) , CTSE 為1才開啟hw flow control;
LIN(local interconnection network) mode
=========================================

Figure 318
在recieve端register 滿了以後, nRTS轉為 1,表示接收完這個data以後就暫時不接收Data;
 - LIN(local interconnect network),車載網路的一種,用於連接車內電子設備(電動車窗、座椅控制等簡單的設備)。原先已有為了車載網路而開發的CAN協定(Controller area network),但將其拿來控制低階設備,不符經濟效益(太貴),所以在1990年代五家車商(BMW、Benz、Volvo、VW & Audi)聯合開發了此協定。LIN可用單一master連接16個slave,傳輸速率最高為19200 baud。好處是能夠降低成本、不用授權費、易於使用、也易於開發衍生設備。

.. image:: /rst_flow_control.png
 - 在USART被硬體設定為LIN模式時,提供13bit break產生器以及10/11bit break偵測器。
  
 - 若要啟用此模式,須設定USART_CR2的LINEN為1,而下列設定必須要設定為0: 
    - USART_CR2的STOP[1:0] (有兩個位元)以及CLKEN
    - USART_CR3的SCEN、HDSEL、IREN

LIN傳送器
----------

CTS Flow Control
========================
跟上面是對應的, 當nRTS為1, transimitter 端的nCTS就會是1, 表示他知道reciever 目前無法接收data, TX就會在傳送完當前的data以後 idle.
 - 以master來說,與一般USART傳送器具有相同的流程(請參閱傳輸器章節)。只是要按照下列方法做設定:
    - USART_CR1的M要設定為8 bit資料長度
    - USART_CR3的LINEN要設為1。而USART_CR3的SBK要設定為13 bit。送出break之後要再送出一個1,才能讓接收器開始偵測start bit。

nCTS為1 的時候,  會由硬體去設定CTSIE bit (USART_CR3).
LIN接收器
----------

.. image:: /cst_flow_control.png
 - 在USART接收器介面有特別設計一個break偵測電路,與一般資料的接收電路區隔開來。不管USART處於甚麼狀態(Idle或是正在接收資料frame),都能夠偵測到break。

 - 當USART_CR1的RE設定為1時(接收器開啟),接收器電路就會從RX查看是否有start bit進來,偵測break或是資料也是用這個方法。如果偵測到start bit,也用相同的採樣方式(針對第8, 9, 10採樣點做偵測)去偵測訊號是否有雜訊。如果第10個(USART_CR2的LBDL=0)或第11個(USART_CR2的LBDL=1)收到的bit為0,且隨後跟著一個分隔符號,USART_SR的LBD會被設立,此時如果LBDIE的設定為1,就會發出interrupt。在驗證一個break之前,會先確保有收到分隔符號(代表RX已經回到高電位狀態)。

PARITY CONTROL
..............
Parity control是用來確保傳輸資料的正確性。其原理是在傳輸端產生一個parity bit,然後在接收端可以重新計算parity bit以確保在傳輸過程沒有發生錯誤。在STM32,它可以透過設定USART_CR1 register的PCE bit來打開。STM32的frame長度是由M bit所決定,所以USART的frame有以下這些可能格式:
 - 偵測break時,若在收到足量的0之前卻收到1,則偵測電路就會取消break偵測,並去偵測start bit。

.. image:: /frame_formats.png
 - 如果LINEN設定為0,接收器會變成一般的USART接收器,也就是不去偵測break符號。

Even/Odd parity
=================================
 - 若開啟了LIN模式,當framing錯誤發生時(收stop bit時卻收到0,有可能是收到break了),接收器會停止,直到break偵測迴路收到1(確認不是收到break),或是收到break後也收到分隔符號(確認收到break)。

parity依算方式的不同分成兩種方式,even parity和odd parity
![](/embedded/USART_pic305.png)

Even parity
--------------------
如果一個frame內1的數量是偶數,則在 even parity的情況下會把parity bit設為0。

E.g.: 假設 data=00110101; 因為有 4 bits被設為1,而且我們選擇的是 even parity(PS bit in USART_CR1 = 0),所以 parity bit被設為0。
單線半雙工模式
==============

Odd parity
-------------------
如果一個frame內1的數量是奇數,則在 odd parity的情況下會把parity bit設為0。
若要啟用單線半雙工模式(Single-wire half-duplex communication),可以設定USART_CR3的HDSEL為1。而下列設定必須要設定為0:

E.g.: 假設 data=00110101; 因為有 4 bits被設為1,而且我們選擇的是 odd parity(PS bit in USART_CR1 = 1),所以 parity bit被設為1。
 - USART_CR2的LINEN、CLKEN
 - USART_CR3的SCEN、IREN

USART可以設定成遵循單線半雙工協定,而TX和RX在內部結構來看是相連在一起的。USART_CR3的HDSEL可以選擇是要全雙工還是半雙工。

接收後會做 parity checking
=========================================
如果 parity check 失敗了,USART_SR register的PE flag會被設立,然後如果USART_CR1 register的PEIE bit也有被設立的話,還會產生中斷。PE flag最後在軟體執行(a read from the status register followed by a read or write access to the USART_DR data register)時被清除。
當HDSEL被設定為1的那刻起:

 - TX和RX在內部結構會變成相連的
 - RX腳位不會被使用
 - 只要沒有資料傳送,TX腳位都是處於釋放狀態,所以會變成一般的標準I/O腳位,處於Idle狀態或是等待接收。當TX腳位沒有被USART使用時,此腳位應該要設定為I/O使得TX成為floating input,或是成為高電位輸出的open-drain。

傳送前會做 parity generation
======================================
如果USART_CR1的PCE bit被設立,那麼MSB會被改成parity bit(PS=0 是even parity, PS=1 是odd parity)
除了以上的敘述之外,此模式的通訊過程都與一般的USART沒甚麼不同,只是這條線的使用權必須要由軟體決定(mutex之類的)。
另外,傳輸的觸發絕對不會被硬體擋住,而且只要有資料被寫入data register(USART_DR)且TE=1時,就會立刻觸發傳輸,並將資料送出。

小知識:

MSB: Most Significant Bit,代表位數最大的那個bit

LSB: Least Significant Bit,代表位數最小的那個bit
智慧卡模式
=========

USART Register 總表
................................
Status register(USART_SR)
 - Smartcard mode在ISO7816-3標準中,Smartcard介面可支援非同步傳輸。

Data register(USART_DR)
![](/smart_card.jpg)

Baud rate register(USART_BRR)
![](/embedded/USART_SmartCardPin.jpg)

Control Register 1(USART_CR1)
 - 若要啟用,須設定USART_CR3的SCEN。另外,下列暫存器一定要清空: 
    - USART_CR2的LINEN
    - USART_CR3的HDSEL以及IREN

Control Register 2(USART_CR2)
 - 使用此模式時,也可考慮設定CLKEN以提供時脈給smartcard。

Control Register 3(USART_CR3)
 - 若要使用Smartcard模式,USART應設定為: 
    - 8 bit以上檢測位元: 在USART_CR1中,M以及PCE應設定為1。
    - 1.5 stop bits: 傳輸/接收時會需要。在USART_CR2中,STOP應設為11。

Guard time and prescaler register(USART_GTPR)
 - 不過,也可以設定為0.5 stop bit,但建議是1.5,避免在使用smartcard模式時,額外對此設定做轉換。

.. image:: /USART_register.png
![](/parity_smartcard.png)

CODE SECTION
.........................
 - 當連接到Smartcard時,USART的TX被使用為雙向溝通,並與Smartcard共用。TX腳位一定要設定為open-drain。

Download sample code : 
    - Smartcard是單線半雙工的通訊協定: 

.. code-block:: c
        - 從transmit shift暫存器傳輸資料時,會被延遲至少1/2 baud clock。在一般模式(USART),一個裝滿資料的transmit shift暫存器,會在遇到下一個baud clock邊緣時開始動作(shift)。但是在Smartcard模式,遇到baud clock邊緣時,還會再延遲一些時間(1/2 baud clock)才開始傳送。

    git clone https://github.com/wujiheng/stm32f407.git
    cd stm32f407/USART
        - 使用0.5或1.5 stop bits時,若在接收資料frame時遇到檢測錯誤(parity error),接收端RX完成接收時,TX那條線會拉低電位長達一個baud clock,然後才開始下一次的資料傳送。這個動作是為了告知Smartcard資料在傳送給USART的過程中,資料沒有正確地被接收。這種訊號稱作NACK,並且產生此訊號時會讓TX端產生framing error(使用1.5 stop bits時)。此種應用可以依據通訊協定的規則進行資料重送。另外,當NACK control bit被設定為1時,RX端偵測出檢測錯誤時會送出NACK訊號,否則就不傳送。

        - TC旗標的設立,可藉由設定Guard Time暫存器來延遲設立的時間。在一般模式(USART)下,若transmit shift暫存器是空的,而且沒有額外的傳送要求時,TC旗標會立即被設立。但在Smartcard模式,在transmit shift暫存器是空的時候,此暫存器會先觸發Guard time counter,並且在Guard time暫存器中計數到一定數值後(由使用者設定),TC旗標才會被設立。在計數的過程中,TC旗標維持低電位,而TC旗標的取消動作與一般模式相同。

To compile code
        - 若在TX端偵測到framing error(因RX傳送NACK),此NACK訊號不會被TX端的接收區偵測為start bit。依據ISO協定,此NACK訊號長度可為1 or 2個baud clock。

.. code-block:: c
        - 如果在RX端偵測到檢測錯誤(parity error)並且NACK訊號已經送出,則NACK的接收者(TX)不會把此訊號當成start bit。

   make 
   make flash    <-- 記得把USB連上去
        - break符號在Smartcard模式中其實不重要。一個0x00相連一個framing error,會被當作一個資料而不是一個break。在觸發TE bit時,不會傳輸Idle frame。雖然Idle frame在其他種設定中有被定義、使用,但在ISO協定中沒有被定義。


這裡採用minicom 超級終端機來接收USART字串
紅外線編碼模式
=============

.. code-block:: c
Ref: [RM0090 Reference Manual P.979](http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf)

若要使用此模式,則必須設定USART_CR3的IREN為1,而下列設定必須要設定為0: 
   
   ls /dev       <-- 找device,見圖,這裡找到/dev/ttyUSB0
 - USART_CR2的LINEN、STOP、CLKEN
 - USART_CR3的SCEN、HDSEL

.. image:: /usart-ls-dev.png
IrDA SIR實體層使用Return to Zero, Inverted調變法(RZI modulation),將邏輯0表示成紅外線脈衝訊號。

.. code-block:: c
SIR(slow Infrared)編碼器(傳輸端)會從USART將資料調變成non return to zero(NRZ)資料流,並將此資料流送至紅外線LED以及LED驅動器。雖然IrDA可以支援多種傳輸速率,但是USART-IrDA最快速率只有支援至115.2Kbps(因STM32f429使用SIR ENDEC,而SIR支援速率為9.6-115.2Kbps,亦可稱為9600-115200 baud rate)。在一般USART模式下,傳輸的脈衝訊號寬度為3/16 bit period。

   sudo apt-get install minicom
   sudo minicom -s                   <-- 不一定要用root,不過使用者必須要device node 讀寫的權限,-s表進入setup
SIR解碼器(接收端)會從紅外線接收器收取return to zero訊號,並將之解調變成non return to zero(NRZ)資料流,接著送到USART做處理。解碼器在Idle state時通常為高電位,而編碼器與解碼器的極性通常是相反的。在解碼器收到低電位訊號時,代表已經收到了start bit了。

.. image:: /usart-minicom-setup.png
.. image:: /usart-minicom-device.png
.. code-block:: c
![](/irda.PNG)

   選擇第三個"Serial port setup",設定接收的模式及port   
   先按'A'選擇device,並輸入/dev/ttyUSB0(由剛剛的ls /dev)決定
   - IrDA是個半雙工通訊協定。若傳送器TX正在忙碌(USART傳送資料給IrDA編碼器),在IrDA接收端上的所有資料會被解碼器忽略。反之,若接收器正在忙碌(IrDA解碼器傳送已解碼的資料給USART),在USART_TX上要傳給IrDA編碼器的資料,不會被IrDA編碼器處理。所以接收資料時,盡量避免有任何傳輸的動作,因資料可能會毀損。
   - 邏輯0會被傳輸成高電位訊號,而邏輯1會被當成0來傳輸(見下圖)。在一般模式下,脈衝訊號寬度由3/16 bit period決定。

.. image:: /usart-minicom-parameter.png
![](/normal_mode.PNG)

   - SIR解碼器會將IrDA相容訊號轉換成USART資料流。編碼器則是相反行為。
   - SIR接收器會將高電位轉換成邏輯1,低電位轉換成邏輯0。傳送器則是相反的。
   - 解碼器的輸出值,會與接收器的輸入值擁有相反極性(理由同上)。SIR輸出端處於Idle state時,輸出低電位。
   - IrDA規定可接收的脈衝週期必須要大於1.41us,不過這週期可以由使用者設定。在接收端會有一個判斷邏輯glitch detection,若該次脈衝週期小於2個PSC,則把該次脈衝過濾掉。(PSC: prescaler value,分頻器的值,定義於IrDA低功率baud暫存器,USART_GTPR)。不過,若脈衝週期小於1個PSC,一定過濾掉。至於脈衝週期介於1-2個PSC之間的,可以選擇是否要過濾。大於2個PSC的脈衝週期就會接收。若PSC設定為0(手冊有說不可以設定這個值),則編碼器和解碼器都不會啟用。
   - 接收器可與低功率傳送器溝通。
   - 在IrDA模式下,USART_CR2的STOP一定要設定為1。

   再來按'E'設定接收的參數,選擇
.. code-block:: c

   'C' --> Baud rate 9600
   
   'L' --> None parity check
IrDA 低功率模式
----------------

   'V' --> 資料長度 8 bits
 - 傳送器:
    - 使用低功率模式時,脈衝的發送並非在3/16 bit period,而是低功率baud rate*3,至少為1.42MHz。通常此值為1.8432MHz(1.42MHz < PSC < 2.12MHz)。為了要達到此值,低功率模式下的除法器會把系統時脈強制降到這個值or區間。

   'W' --> 停止位元數 1 bit
 - 接收器:
    - 低功率模式的接收與一般模式相去不遠。此模式的glitch detection會把小於1個PSC的脈衝過濾掉。有效脈衝的判別,是當脈衝週期大於2個PSC時才會被接收(2 * IrDA低功率baud clock,USART_GTPR的PSC)

   輸入完後按Enter離開
 - 接收器的開機時間應該由軟體決定。另外,在接收與傳輸的動作之間,應該要加入至少10ms的延遲,因為IrDA是半雙工協定。

.. image:: /usart-minicom-save.png
  
.. code-block:: c

   回到原本的畫面,選擇 'Save setup as default' ,然後選擇 'Exit from Minicom' 離開
直接記憶體存取(DMA)模式
===================================

.. image:: /usart-minicom.png
Ref: [Using The DMA controller on STM32](http://www.mind-dump.net/using-the-dma-controller-on-stm32f4)

.. code-block:: c
   回到Terminal,重新輸入sudo minicom進入Minicom的畫面
USART可以使用DMA達到連續通訊的效果,不過DMA會個別對於RX和TX緩衝器送出請求。

.. image:: /usart-minicom.png
Transmission using DMA
------------------------

![](/tx_uart_dma.png)

.. image:: /usart-pin.jpg
若要啟用DMA模式,要在USART_CR3把DMAT啟用。在TXE bit被設立時,資料會先從SRAM(要先由DMA周邊設定,請參考DMA說明手冊)載入到USART_DR暫存器。在系統保留的SRAM,TX/RX的資料緩衝使用集中型DMA。

如果要把DMA通道對應給USART傳送器,請使用下列流程:

.. code-block:: c
   
   按照圖上的接法,白色線接PA2、綠色線接PA3
   ** 白色線為USB的RX所以要接上板子的TX(PA2) ** 
   ** 綠色線為USB的TX所以要接上板子的RX(PA3) ** 
   1. 把USART_DR暫存器的位址寫到DMA控制暫存器中,以設定待傳資料的終端地點。在每次TXE被觸發的時候,資料都會從記憶體中搬到這個位址。
   2. 把記憶體位址寫到DMA控制暫存器裡面,以設定待傳資料的來源。在每次TXE被觸發的時候,資料都會從這個記憶體區段搬到USART_DR。
   3. 在DMA控制暫存器中,設定要傳的資料總量(bytes)。
   4. 在DMA暫存器設定通道的優先順序。
   5. 按照程式需求,設定在傳輸一半/全部資料後,是否產生DMA interrupt。
   6. 清除SR暫存器中的TC(寫入0)。
   7. 啟動DMA暫存器中的通道。

此時畫面中的Minicom會顯示出結果,不斷的印出"Init complete! Hello World!"
如果傳輸的資料總量,已經達到DMA控制暫存器內設定的上限時,DMA控制器會在DMA通道interrupt vector上產生interrupt。

.. image:: /usart_minicom_results.png
在傳輸模式下,只要DMA把所有該傳的資料都傳完時(此時在DMA_ISR的TCIF旗標會設立),TC旗標可以用於監控USART是否已經完成通訊。這步驟是為了避免在最後一次資料尚未傳完時,把USART關掉或是進入Stop模式。程式一定要等到TC=1才可以進行後續的動作。在傳輸資料時,TC旗標會一直維持清除狀態(=0),只有在最後一次資料frame傳輸結束時,TC旗標才會被硬體設立。

按Ctrl+a,再按x可離開Minicom

Reception using DMA
----------------------

![](/rx_usart_dma.png)

DMA模式也可以用於接收資料,須設定USART_CR3的DMAR。只要收到任何一個byte時,該次資料會從USART_DR載入至SRAM(要先由DMA周邊設定,請參考DMA說明手冊)。如果要把DMA通道對應給USART接收器,請使用下列流程:

   1. 把USART_DR暫存器的位址寫到DMA控制暫存器中,以設定待傳資料的來源。在每次RXNE被觸發的時候,資料都會從這個位址搬到記憶體中。
   2. 把記憶體位址寫到DMA控制暫存器裡面,以設定待傳資料的終端地點。在每次RXNE被觸發的時候,資料都會從USART_DR搬到這個記憶體區段。
   3. 在DMA控制暫存器中,設定要傳的資料總量(bytes)。
   4. 在DMA暫存器設定通道的優先順序。
   5. 按照程式需求,設定在傳輸一半/全部資料後,是否產生DMA interrupt。
   6. 啟動DMA暫存器中的通道。

如果接收的資料總量,已經達到DMA控制暫存器內設定的上限時,DMA控制器會在DMA通道interrupt vector上產生interrupt。在interrupt subroutine時,USART_CR3的DMAR應該要由軟體去清除。

另外,如果要把DMA用於接收,就不可以啟用RXNEIE。


多重緩衝區中的Error flagging and interrupt 
---------------------------------------------

若在多重緩衝區的情況下,在傳輸/接收過程中發生了任何錯誤,在該次byte傳完後會立即設立error旗標。另外,如果有任何interrupt enable旗標被設立,error設立完之後還會再產生interrupt。以framing error、overrun error和噪音旗標(另外與RXNE搭配使用,因為可能有單一byte接收的情況)來說,每個都有各自獨立的interrupt enable旗標(USART_CR3的EIE)。如果發生任何一種錯誤,在傳完該次byte之後會立即產生interrupt。在interrupt章節會提到這些interrupt enable之間的關係。

HARDWARE FLOW CONTROL(modem modes)
===================================

USART亦可模擬RS-232通訊。RS-232原本的設計用意,是讓電腦能對數據機、印表機、資料儲存裝置等電腦周邊設備做資料交換。但是RS-232的缺點較多(接孔過大、設備能源消耗太快、資料傳輸速率低),目前的電腦漸漸都淘汰掉這種接孔,並用USB-RS232轉換器做為替代。現今RS232介面則廣泛使用於工業設備、科學儀器及網路設備。

USART使用modem modes時,會變成雙線半雙工通訊(UART)。通訊流控制則由RTS-CTS負責,也因此同時間點只能有一方傳送資料。

利用nCTS跟nRTS控制TX、RX是否再傳送或接收data。
可個別設定USART_CR3的RTSE以及CTSE為1,藉此允許RTS或CTS flow control。

![](/hardware_control_2usarts.png)

RTS Flow Control
-------------------------

 - 如果開啟RTS flow control(要把RTSE設為1),nRTS會被拉至低電位,直到USART接收器準備好要接收下一筆資料才會拉高。如果接收器的暫存器滿了,會先把nRTS拉至高電位,告知另外一端的傳送器在傳完這個資料frame之後,應該要停止傳送資料。

![](/rst_flow_control.png)

CTS Flow Control
-----------------------

如果開啟CTS flow control(要把CTSE設為1),在傳送器要傳送下一筆資料frame之前,會先去檢查nCTS是否有值輸入。如果nCTS被拉至低電位,那麼下一筆資料會立即被送出(假設資料已經先在Transmit Data Register準備好了,也可說成TXE=0),否則不會進行傳送。如果在傳送資料的過程中,nCTS被拉至高電位,那麼會先把剩下該傳的資料先傳完,再停止傳送。

REFERENCE
..................
- `Universal asynchronous receiver/transmitter wikipedia.<http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter#Special_receiver_conditions>`_
如果CTSE被設定為1,那麼在nCTS有值輸入時,CTSIF狀態會自動地被硬體設立,表示該時間點接收器是否已準備好下一次的通訊。若有開啟USART_CR3的CTSIE(=1),則會產生interrupt。

- `STM32F407xx Reference Manual<http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf>`_
另外,在開啟CTS flow的情況下,傳送器在送出break時不會去檢查nCTS的狀態。

![](/cst_flow_control.png)

- `IrDA and RS-232<http://china.maximintegrated.com/app-notes/index.mvp/id/3024>`_

- `Using The DMA controller on STM32<http://www.mind-dump.net/using-the-dma-controller-on-stm32f4>`_
RS-232收發器-MAX232
==========================
 - MAX232晶片是美信(MAXIM)公司專為RS-232標準串口設計的介面電路,屬於+3.0V to +5.5V RS-232 收發器,收發器採用專有的低壓差發送器輸出級,利用雙電荷泵在3.0至5.5V單電源供電時能夠實現真正的RS-232功能,MAX232是一個雙RS-232驅動器/接收器且可以從單一的+5V電源產生RS-232電位(voltage level)(充電泵可轉換+5V為 ±10V),假設我們要用RS232來進行PC(serial port) 與微處理器間的溝通,就要用MAX232來處理訊號電位轉換的功能,方便微處理器處理轉換後的訊號。
 - 其包含兩個驅動器和兩個接收器,功耗僅40mW 且傳輸速率可以達120Kbps。

Q&A
...................
![](/MAX232_pin.png)

***1.UART 原理***
MAX232 內部結構
===============
雙電荷泵轉換器電路 (DUAL CHARGE PUMP CONVERTERS)

DTE(Data Terminal Equipment)簡稱數據終端設備;DCE(Data Communications Equipment)簡稱數據通信設備。
 - 由1、2、3、4、5、6腳和4個電容構成。功能是產生+10V和-10V兩個電源,提供給RS-232串口電位。

事實上,RS-232C標準的正規名稱是"數據終端設備和數據通信設備之間串行二進制數據交換的接口"。
 - 第一階段,電容 C1的電壓提昇兩倍到 +10V並儲存在電容器 C3和V+ output。

通常,將通信線路終端一側的計算機或終端稱為DTE,而把連接通信線路一側的調製解調器稱為DCE。
 - 第二階段,電容 C2將 +10 V的反向變成 -10V並儲存在電容器 C4和V- output。

RS-232C標準中所提到的"發送"和"接收",都是站在DTE立場上,而不是站在DCE的立場來定義的。
 - MAX232運作與的電荷泵電容可低至 0.1μF,若使用更大的電容(最多10μF)可以用來降低電源紋波(voltage ripple)。

由於在計算機系統中往往是CPU和I/O設備之間傳送信息,兩者都是DTE,因此雙方都能發送接收。
電源紋波(voltage ripple)

所謂"串行通信"是指DTE和DCE之間使用一根數據信號線(另外需要地線,可能還需要控制線)
成因是因為一個直流電壓大多時是通過交流電壓整流、濾波而來,濾波若不乾淨則會使交流成分疊加在直流穩定分量上,另外電池的直供電也會因負載的波動而產生波紋。

數據在一根數據信號線上一位一位地進行傳輸,每一位數據都佔據一個固定的時間長度。
![](/MAX232_ripple2.jpg)

這種通信方式使用的數據線少,在遠距離通信中可以節約通信成本,當然,其傳輸速度比並行傳輸慢。
MAX232工作原理
================
 - 由7、8、9、10、11、12、13、14腳構成兩個數據通道。

小知識:
 - 13腳(R1IN)、12腳(R1OUT)、11腳(T1IN)、14腳(T1OUT)為第一數據通道。

DTE英文全稱Data Terminal Equipment,數字終端設備,指一般的終端或是計算機。可能是大、中、小型計算機,也可能是一臺只接收數據的打印機。
 - 8腳(R2IN)、9腳(R2OUT)、10腳(T2IN)、7腳(T2OUT)為第二數據通道。

DCE英文全稱Data Circuit-terminating Equipment,數字通信設備,通常指調制解調器,多路復用器或數字設備。
 - TTL/CMOS訊號從11引腳(T1IN)、10引腳(T2IN)輸入轉換成RS-232數據從14腳(T1OUT)、7腳(T2OUT)送到電腦DB9插頭;

DTE,DCE的區別
 - DB9插頭的RS-232數據從13引腳(R1IN)、8引腳(R2IN)輸入轉換成TTL/CMOS訊號後從12引腳(R1OUT)、9引腳(R2OUT)輸出。

DCE一方提供時鐘,DTE不提供時鐘,但它依靠DCE提供的時鐘工作。
 - 內有的兩組RS232驅動器/接收器和電荷泵可以產生RS232電位,內部各有一個400 KΩ的pull up電阻,可以將未使用的驅動器拉至高電位,因有雙極性的特點,所以輸出邏輯電位會是low,若是在shutdown/power-off模式下驅動器/接收器無法上拉電壓,但是會進入高阻抗狀態,如此可以降低漏電流(最大25μA),避免過載(overload)情形發生。

舉PC機和MODEM之間的連接為例:PC機就是一個DTE,MODEM是一個DCE。
 - 上拉電阻(Pull-up resistors):在驅動電路時,當輸入過低,可以用一個上拉電阻透過接到較高的電位將電壓訊號拉至高電位,對輸入端而言,看起來就是高阻抗,如果成功驅動,則取消上拉電阻的使用。通過這樣,上拉電阻可以使pin腳在未連接外部組件時也能保持正確的邏輯電位。

DTE可以從硬件上區別它的接口為針式,DCE的接口為孔式。
 - 舉例來說:當TTL電路驅動CMOS電路時,如果TTL電路輸出的高電平低於CMOS電路的最低高電平(一般為3.5V),這時就需要在TTL的輸出端接上拉電阻,以提高輸出高電位的值。

參考資料:http://wfeng520.blog.hexun.com.tw/62795095_d.html
 - 下拉電阻(Pull-down resistors):原理相同於上拉電阻,但其是與GND連接,故可以使邏輯訊號保持在接近0V的狀態。

![](/MAX232_waveform2.png)

***2.USART和SPI的不同***
 - 供電
    - 15腳GND、16腳VCC(+5V)。

簡單複習SPI:
 - 等效電路說明

SPI:它是主從式的架構,通常一個主設備和多個從設備
![](/embedded/MAX232_circuit.jpg)

由四條信號線組成:SCLK、MISO、MOSI、CS
 - TXD為TTL輸入端,RXD為TTL輸出端,由於二極體與電容的作用使二極體D1與電容C7交接處的電壓保持在-3V~-15V。

MOSI:master output, slave input,主設備輸出
 - TTL轉RS232:

MISO:master input, slave output,主設備輸入
    - 當TXD為"邏輯1"時(TTL),Q3(PNP電晶體)為截止狀態,PCRXD上電壓與PCTXD電壓相等,也是-3~-15V,為"邏輯1"(RS232)

SCLK:serial clock,clock信號,由主設備產生
    - 當TXD為"邏輯0"時(TTL),Q3(PNP電晶體)為導通狀態,PCRXD上電壓約為+5V,此電壓位於+3~+15V之間,也就是"邏輯0"(RS232)

CS:chip select (optional)
 - RS232轉TTL:

USART在全雙工的模式(特別是同步模式)下,也有類似的訊號
    - 當PCTXD為"邏輯1"時(RS232),Q4(NPN電晶體)為截止狀態,RXD電壓約為+5V,為"邏輯1"(TTL)

TX:傳送訊號給周邊
    - 當PCTXD為"邏輯0"時(TS232),Q4(NPN電晶體)為導通狀態,RXD電壓為0V,為"邏輯0"(TTL)

RX:週邊設備傳送給主設備的訊號
 - 其中D2二極體的功能是為了防止Q4的逆向偏壓過高而導致的崩潰現象發生。 

SCLK:由主設備產生的clock訊號
USB to UART 橋接器-CP2102 
==========================

以上是兩者有類似的地方
CP2102是一個十分完整的USB轉UART橋接器,運用了最小化元件和最少的PCB空間,其中包含了USB2.0的全速電路、USB收發器、振盪器、EEPROM(電子抹除式可複寫唯讀記憶體)、非同步串列資料匯流排。

![](/CP2102.png)

***3.高速UART及低速UART之應用?***
 - EEPROM是用來儲存USB供應商ID、產品ID、產品說明、電源參數、裝置版本號、裝置序號,寫入次數壽命為10萬次。

嵌入在ElanSC520微控制器中的高速UART通信的速度可以高達1.1152Mbps
 - UART接口包括TXD、RXD、RTS、CTS、DSR、DTR、DCD和RI控制信號。

另外利用計算機軟件技術(EDA技術)和FPGA/CPLD的靈活性可以方便快速地設計高速和低速的UART。
 - UART支持RTS/CTS、DSR/DTR和X-On/X-Off作hand-shaking。

高速的UART可以用在光纖通信上,低速的UART可以用在FPGA/CPLD和單片機的通信上。
![](/CP2102_table.png)

handshaking:早期不同的終端設備或電腦以RS232作資訊通訊時,為了確認已建立通訊連結作先作hand shaking,確認後才會開始作資料傳輸。

***4.USART、COM、RS232之關係***
 - X-ON/X-OFF:是一種用於流量控制的非同步通信協議,舉例來說,電腦傳送資料到印表機的速率明顯大於印表機的列印速度,所以印表機內會有一個buffer用來儲存來不及印的資料,若是在列印結束之前,buffer滿了的話,列表機將會發送一個XOFF的控制字元符號來告訴電腦暫停傳輸,等到buffer空的時候再發出一個XON控制字符到電腦繼續傳輸資料,所以方向皆是接收端傳到傳送端

UART包括了RS232、RS449、RS423、RS422和RS485等介面標準規範和匯流排標準規範,即UART是非同步串列通信口的總稱。
供電結構
=======
CP2102內部有一個5 to 3V的電壓調節器,如此才能配置成匯流排供電或是自行供電,以下介紹兩種供電配置。

而RS232、RS449、RS423、RS422和RS485等,是對應各種非同步串列通信口的介面標準和匯流排標準,
匯流排供電

它規定了通信口的電力特性、傳輸速率、連接特性和介面的機械特性等內容。
 - 裝置可以是由「匯流排供電」(Bus-powered),也就是從USB連接的介面取電。

實際上這是是屬於通信網路中的物理層(最底層)的概念,與通信協議沒有直接關係。而通信協議,是屬於通信網路中的數據鏈路層(上一層)的概念。
![](/CP2102_buspowered.png)

COM是PC(個人計算機)上,非同步串列通信口的簡寫。由於歷史原因,IBM的PC外部介面配置為RS232,成為實際上的PC界默認標準。
 - 匯流排供電情況:會將VBUS與REGIN接通,Vin由VBUS輸入。

所以,現在PC機的COM均為RS232。若配有多個非同步串列通信口,則分別稱為COM1、COM2...。
自行供電

參考資料:http://ithelp.ithome.com.tw/question/10028134
 - 裝置由USB電源線提供電源,也就是「自行供電」(Self-powered)、或是由電池或外接電源供電。

![](/CP2102_selfpowered.png)

***5.紅外線高速之應用?***
 - 自行供電情況(功能由軟體的Boolean flag啟動,True代表使用self-powered):Vin由5V Power net輸入,REGIN和VBUS並不接通。

低速紅外線是指其傳輸速率在每秒115.2Kbits者而言,它適用於傳送簡短的訊息、文字或是檔案。
![](/CP2102_selfpowered_bypassed.png)

有低速紅外線也有高速紅外線(Fast IR),它是指傳輸速率在每秒1或是4Mbits者而言,其他更高傳輸速率則仍在發展中。
 - 另外一種self-powered(選擇功能)是若將3V的POWER NET電壓給VDD且將VDD和REGIN接在一起,則可以關掉電壓調節器,不通過其而產生輸出。

對於網路解決方案而言,高速紅外線可以說是其基礎,包括檔案傳輸、區域網路連結甚至是多媒體傳輸。

最理想的USB 供電方式之一是由匯流排供電,如此一來就不需要再外接電源,但其缺點是在暫停狀態(suspend)下電流最多耗費500μA,若支援遠端喚醒功能則會耗費2.5mA的大電流,所以可攜式裝置大多採用Self-powered。

USB功能控制器/發送器
==================
USB功能控制器負責管理所有UART及USB間的資料傳輸,和處理來自主機端控制器(host)和UART的控制命令,暫停(Suspend)和恢復(Resume)狀態是用外部電路的方式實現,若是在匯流排上檢測到Suspend訊號,CP2102會進入暫停狀態並送出SUSPEND和SUSPEND*訊號,若是Reset CP2102也會進入暫停狀態,直到USB設定完成。

另外離開暫停狀態的方法有三種:離開完成後SUSPEND和SUSPEND'訊號會被清除

 - 檢測到恢復訊號
 - 收到USB Reset訊號
 - 裝置Reset

注意當Reset時,SUSPEND和SUSPEND'會有暫時的突波電壓,可放置一個10kΩ的下拉電阻在11腳位以保持重啟時低電位。

![](/CP2102_elec.png)

工作流程

![](/embedded/CP2102_MAX232.jpg)

 - 大多時候CP2102會搭配MAX232作使用,在RS232與CP2102之間還會接一個Max232來達到穩壓的效果及轉換訊號的功能,資料從RS232的pin2傳出去,MAX232的R2IN收到,接著從R2OUT輸出一個TTL/CMOS訊號到CP2102裡面,因為CP2102裡面有兩條數據傳輸通道以及緩衝區,振盪器和USB function controller會去控制資料的緩衝和傳遞​,由USB傳送端從usb port傳出去。

STM32 USART Register 總表
==========================

Status register(USART_SR)

![](/embedded/USART_SR.jpg)

Data register(USART_DR)

Baud rate register(USART_BRR)

Control Register 1(USART_CR1)

![](/embedded/USART_CR1.jpg)

Control Register 2(USART_CR2)

![](/embedded/USART_CR2.jpg)

Control Register 3(USART_CR3)

![](/embedded/USART_CR3.jpg)

Guard time and prescaler register(USART_GTPR)

![](/USART_register.png)


STM32F429-USART程式碼 & 示波器圖解
==========================


Download sample code : 


 - 測試用code: [http://wiki.csie.ncku.edu.tw/embedded/stm32F429-usart.zip](http://wiki.csie.ncku.edu.tw/embedded/stm32F429-usart.zip)
 - 從PC端接收stm32f429-USART的資料,並紀錄到檔案。 [http://codepad.org/0yvz8jk4](http://codepad.org/0yvz8jk4)
 - 環境設定: [https://stm32f429.hackpad.com/NOTE-WbiooOfkaoR](https://stm32f429.hackpad.com/NOTE-WbiooOfkaoR)
 - 本程式碼在ubuntu-12.04測試,並對stm32f429燒錄成功。


```c
void RCC_Configuration(void)
{
    /* --------------------------- System Clocks Configuration -----------------*/
    /* USART1 clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    /* GPIOA clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
}

void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /*-------------------------- GPIO Configuration ----------------------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Connect USART pins to AF */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);   // USART1_TX
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);  // USART1_RX
}

void USART1_Configuration(void)
{
    USART_InitTypeDef USART_InitStructure;

    /* USARTx configuration ------------------------------------------------------*/
    /* USARTx configured as follow:
     *  - BaudRate = 9600 baud
     *  - Word Length = 8 Bits
     *  - One Stop Bit
     *  - No parity
     *  - Hardware flow control disabled (RTS and CTS signals)
     *  - Receive and transmit enabled
     */
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);


    USART_Cmd(USART1, ENABLE);
}

void USART1_puts(char* s)
{
    while(*s) {
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        USART_SendData(USART1, *s);
        s++;
    }
}
```

```c
int main(void)
{   
    RCC_Configuration();
    GPIO_Configuration();
    USART1_Configuration();

    USART1_puts("USART");
    char t = 'a';
    char rs[50] = {'\0'};
    char* prs = rs; 

    while(t != 'b')
    {   
        while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
        t = USART_ReceiveData(USART1);
        *prs++ = t;
    }   
    USART1_puts("\r\nThis is the string typed by user:\r\n");
    USART1_puts(rs);

    while(1)
    {   
        while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
        t = USART_ReceiveData(USART1);
        if ((t == '\r')) {
            while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
            USART_SendData(USART1, t); 
            t = '\n';
        }   
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        USART_SendData(USART1, t); 
    }   

    while(1);   // Don't want to exit
}   
```

![](/embedded/USART_pin.jpg)


```
如果是使用圖中轉接板,要將紅色板子的TX接到stm32f429的PA10(RX)、RX接到PA9(TX)。
若是使用USB-TTL轉接線,要將綠色線(TX)接到PA9、白色線(RX)接到PA10
接地線要記得插上板子
```


![](/embedded/USART_Osc_PC.jpg)


```
使用putty連線,設定如圖中所示。
開始連線後,板子會傳送USART字串。一直按板子的reset,會如圖中下方所示。
```

![](/embedded/USART_Osc_brief.jpg)


```
使用示波器量測stm32f429的RX收到的訊號,從PC對其送出字元b。。
先按autoset,再調整紅色圈圈的兩個設定。建議將時間區間(x軸)調成4ms、電壓區間(y軸)調成1V,不然會抓到不完整的訊號。
注意綠色圈圈,要把量測棒的夾到板子上(接地),否則會出現雜訊。
**時間區間沒調好,波形會變成下圖這樣**
```

![](/embedded/USART_Oscilloscope.jpg)


![](/embedded/USART_Oscilloscope_char_b.jpg)


```
在沒接地時,量測STM32F429從PC接收字元b。    
整體波形變得不平整,但還是看得到USART輸出的波形。
```

![](/embedded/USART_Osc_IDLE_USART.jpg)


```
使用測試程式燒錄到板子上,並透過示波器量測stm32f429的TX送出的訊號。
綠色圈圈代表板子正在開機,USART並未開啟。
IDLE在圖中已標示成紅色字體。
紫色點代表start bit,橘色點代表stop bit,並依序在圖上標示USART字樣。
注意字元的傳送都是從LSB開始。U的二進位表示為:01010101,但是在傳送時會送出此序列:10101010
```



   
REFERENCE
==========================
- [[1]Universal asynchronous receiver/transmitter wikipedia.](http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter#Special_receiver_conditions)

- [[2]STM32F407xx Reference Manual P.946 ~ P.997](http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf)


- [[3]IrDA and RS-232](http://china.maximintegrated.com/app-notes/index.mvp/id/3024)

- [[4]Using The DMA controller on STM32](http://www.mind-dump.net/using-the-dma-controller-on-stm32f4)

- [[5]ISO 7816-3](http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-3.aspx)

Q&A
==========================

***1.baud rate為何不是2的倍數?幾個baud rate數字的關聯?為何設定會有小數點?***

baud rate 是單位時間內傳輸資訊的個數,單位是bits/sec

最早的發明是用來測量電報傳輸速率,現在用來作為網路兩節點的傳輸速率

常用的有300、1200、2400、9600、115200、19200等bits/sec

這些規格是來自歷史因素,最早的baud rate用在電傳,是75baud

後來每次擴充都是兩倍,75->150->300->600->1200....

而我們為了要得到這個值,必須從系統的clock做分頻,因此要設定USARTDIV

這也是USARTDIV會是小數的原因

***2.為什麼USART可以選擇8 bit/9 bit***

由於歷史因素,所以usart可以選擇8,9bit的傳送

最一開始的ASCII code是使用7 bit來做編碼,而第8個位元常會被拿來做各種應用

像是加上parity bit來驗證資料的正確性

但是當以8為單位的電腦系統興起後,開始用8bit來做傳輸

所以一開始7 bit ASCII code也被擴展為8 bit

***3.為何stop bit有0.5 bit、1.5 bit的設計?***

stop bit其實不算是bit,他是傳輸結束後的一段時間(period),區隔每個傳輸的資料

它的功用是在非同步傳輸的時候可以告訴receiver資料傳輸已經結束

stop bit有0.5, 1, 1.5, 2bits,共四種

一些比較老的teletype machine可能需要不只一個stop bit

如果stop bit越長,可以增加多一點點的處理時間

另一個原因是長一點的stop bit可以提供長一點的同步時間

若是在環境比較不好的情況下(例如,長距離傳輸),較長的同步時間會可以有效減少錯誤的發生

不過缺點是會導致throughput的降低

***4.為何取樣是看8,9,10這幾個bit?***

因為8,9,10是在整個start bit的正中間

由於接收端和傳送端的取樣頻率可能會有些微誤差

如果我們在中間取樣,可以容許一定程度的取樣頻率誤差

![](/unmatched clocks.png)

[圖片來源](http://electronics.stackexchange.com/questions/42236/uart-receiver-clock-speed)