Atmel Tiny 88 Single-wire Software UART

  1. Introduction

Single-wire Software UART 的特性:
  • 使用軟體開發的 UART
  • 半雙工單線傳輸
  • 使用中斷驅動事件
  • 支援傳輸速度為 9600@1MHz 的系統時脈
  • 所有的 AVR 晶片所需要的外部中斷及一個 8-bit 的計數比較器
UART 的資料傳送和資料接收是使用分開的線路(兩條線路)來完成。Single-wire UART 是使用同一條線路來做資料的傳送和接收,價位上相對便宜但是傳輸速度就不能太快只能做半雙工的傳輸,同一時間,只能做資料的傳送或接收,這份資料將會描述 single-wire UART 如何開發,兩個裝置之間半雙工傳輸的協議。需要選擇一個據有外部中斷旳 GPIO 和據有中斷的計數器。

UART 的簡介:

  • Frame -

UART protocol 是一個非同步的串列傳輸標準,資料是採用循序傳送的,一次一個位元。一般的傳送資料組包含 8 個位元的資料,一個啟動位元和兩個結束位元所組成。使用者可以自己定義不同的資料組,資料位元可以由 5 到 9 個位元,一個同位位元或一個結束位元。


  • Transmission -

資料傳輸的開始由傳輸端送出 start 位元(把資料線拉 Low,並保持一個位元的傳輸時間)。接收者偵測到 start 位元(資料線由 High 轉成 Low 時的觸發,開啟接收者的同步程序,資料由最低的位元開始傳送。

傳送者必須要先採樣資料,確定資料的結束位元已經傳送結果,如果有裝置正在接收中,資料傳送將不會被啟動。 Error Flag 是指傳輸者送出 High 的資料,但是有輸送者的中斷,造成接收者卻收到 Low 的資料。

  • Reception -

資料接收由偵測到 start 位元開始,接收資料準位採樣設定在位元傳輸時間的中心點,所以第一筆資料的採樣時間是在 start 位元偵測 (High 轉成 Low) 後的 1.5 位元時間(一個完整 start 位元時間加上第一筆資料的半個位元時間)。經過多數的硬體驗証,在中心點採樣比較能接收到正確的資料。

Baud rate 是指 UART 的傳輸速度,也就是每秒可以傳送的位元數,這些位元數不只算資料位元,還包含了啟動及結束位元,所以要計算有效資料傳送量時,需要再扣除啟動和結束位元。傳送者和接收者必須協議出相同的 Baud rate 否則資料無法同步。一般使用的 Baud rate 為 4800,9600,19200,28800 和 38400。

  • Error Condition -

<情況一>
兩個裝置的 Baud rate 相差太多,資料無法同步。Baud rate 的基礎是系統時脈,若使用內部的 RC 振盪器建議要先經過校正。

<情況二>
接收資料緩衝器只有一個 Byte 的空間,如果前一筆資料還沒有被讀取前,又接收到一筆新的資料,舊的資料會被新的資料覆蓋,產生 data overflow,並設定 overflow flag。針對這個情況可以降低 UART baud rate,增加資料緩衝空間,或縮短接收函式的處理時間。

<情況三>
如果資料線受到雜訊產生一個 Low 的脈衝,AVR 就會偵測到 start 位元,同時啟動接收,如果在 start 位元的採準資料為 High 的話,AVR 就會結束資料傳輸,並且不儲存這筆雜訊。但是若雜訊持持 Low 超過一個位元時間,雜訊就會被認定為資料處理。

<情況四>
在資料傳送時間,雜訊產生一個 Low 的脈衝。根據這種情況,建議使用同位位元(奇同位或偶同位) 增加資料的正確性。

<情況五>
當主程式和中斷服務程式都要執行 UART 的傳輸,而且中斷服務程式使用不同的傳輸頻率,會造成主程式 UART 的傳輸失敗。根據這種情況,建議使用Master / Slave 的設定,Slave 只有 Master 要求讀取資料時,才傳送資料。
就可以預防兩個裝置都要傳送資料的情況。若 Slave 裝置發生錯誤要通知 Master 的話,可以把資料線拉 Low 一段時間,Master 偵察到後也會設定 error flag。直到 Slave 錯誤解除把資料線放到,傳輸才能恢復正常。

程式碼說明:

  • Baud rate 設定 -

Baud rate 設定會使用到一個 8-bit 計時/計數器,需要工作在 Clear Timer on Compare mode (CTC) 並且在計數值和預設比較值相同時,產生一個中斷。預設比較值會根據系統時脈及系統時脈除頻器來決定。計數值由零開始。

/**

 * Baud rate settings (WAIT_ONE - PRESCALER):

 * Baud Rate     1MHz      2Mhz      4MHz      8MHz

 * 4800     207 - 1    51 - 8   103 - 8   (207 - 8)

 * 9600     103 - 1   207 - 1    51 - 8   103 - 8

 * 19200       NA      103 - 1   207 - 1    51 - 8

 * 28800       NA         NA     138 - 1    34 - 8

 * 38400       NA         NA     103 - 1   207 - 1

 * Please note that the UART consumes about all CPU resources

 * when WAIT_ONE*PRESCALER<100.

 */

 

#if (F_CPU == 1000000)

/**

 * Half bit period compare setting.

 * See the application note for calculation of this value.

 * Make sure timer prescaler is set to the intended value.

 */

#define WAIT_ONE          103

/* Prescaler setting. Must be set according to the baud rate setting. */

#define PRESCALER         1

#elif (F_CPU == 2000000)

/* Half bit period compare setting. See the application note for calculation

 * of this value. Make sure timer prescaler is set to the intended value.

 */

#define WAIT_ONE          207

/* Prescaler setting. Must be set according to the baud rate setting. */

#define PRESCALER         1

#elif (F_CPU == 4000000)

#define WAIT_ONE          103

#define PRESCALER         1

#endif


Baud rate 的設定值

比較值的設定值

Error Calibration 值

Baudrate
4800
9600
19200
28800
38400
1MHz
Prescaler
1
1
N/A
N/A
N/A
Compare
207
103
N/A
N/A
N/A
Error
-0.16%
-0.16%
N/A
N/A
N/A
2MHz
Prescaler
8
1
1
N/A
N/A
Compare
51
207
103
N/A
N/A
Error
-0.16%
-0.16%
-0.16%
N/A
N/A
4MHz
Prescaler
8
8
1
1
1
Compare
103
51
207
138
103
Error
-0.16%
-0.16%
-0.16%
-0.08%
-0.16%
8MHz
Prescaler
8
8
8
8
1
Compare
207
103
51
34
207
Error
-0.16%
-0.16%
-0.16%
-0.82%
-0.16%

其中,8 位元計數器的中斷服務程式沒有完成前,中斷旗標不會被清除,中斷就不會產生,所以在選用 baud rate  時,需要確認中斷服務程式所需的時間。

  • Hardware 設計 -

    • single-wire 接腳需要使用外部 pull-up。因為 AVR 的內部阻抗約 15-40KΩ,無法做高速傳輸,而且 UART 需要 -15V 到 15V 的工作電壓,所以建議使用外部 pull-up 到外部的工作電壓。
    • single-wire 要能設為 Open-collector 的輸出。
    • single-wire 在接收到資料時,需要可以產生中斷。
/* UART interrupt vectors definitions. */
/* UART external interrupt vector. Make sure this is in accordance
to the defined UART pin. */
#define SW_UART_EXTERNAL_INTERRUPT_VECTOR       INT1_vect
/* UART compare interrupt vector. */
#define SW_UART_TIMER_COMPARE_INTERRUPT_VECTOR  TIMER0_COMPA_vect

  • Register 說明 -

    • SW_UART_TX_BUFFER_FULL - 資料已準備好要傳送,設定為1。使用 SW_UART_transmit 函式來傳送資料。
    • SW_UART_RX_BUFFER_FULL - 接收到有效的資料,設定為1。使用 SW_UART_Receive 函式來接收資料。
    • SW_UART_RX_BUFFER_OVERFLOW - 接收緩衝器發生資料 Overflow,設定為1。
    • SW_UART_FRAME_ERROR - 接收到 start bit 的準位是 High 或者 stop bit 準位為 Low 的資料。
    • UART counter - 提供給 UART driver 軟體來控制狀態並且得知位元是要傳送或接收。


  • UART Function 說明 -

    • SW_UART_Enable - 啟動 SW UART 功能

    • SW_UART_Transmit - SW UART 傳送功能

    • SW_UART_Receive - SW UART 接收功能

    • External_SW_UART_ISR - INT0 的中斷服務程式

    • Timer_Compare_SW_UART - CTC 的中斷服務程式,其中 UART Tansmit Handler 和 UART Receive Handler 在下方會有詳細的流程圖。




  • UART Transmit Handler 的流程 -


  • UART Receive Handler 的流程

  1. SampleCode

程式碼是 download AVR274 sample code,因為設計上不同做了一些修改。
  • 我的板子使用的外部中斷是 INT1,sample code 是 INT0。
  • 我使用的晶片的 Tiny88,有些暫存器名字不同,更改成 Tiny88 暫存器。
  • 編譯器使用 Atmel Studio v7,修改部分宣告語法。

下載 SampleCode
  1. Reference Document

  • doc8008.pdf - ATtiny 88 datasheet
  • AVR274.pdf - AVR274 : Single-wire Software UART on tinyAVR and megaAVR devices


留言

這個網誌中的熱門文章

EC 所需知識 - SMBUS

EC 所需知識 - LPC

EC 所需知識 - KBC