UART (Universal Asynchronous Receiver Transmitter)

MPLAB C30コンパイラのUARTモジュール用のライブラリについて解説します。

ライブラリファイルはuart.hですので、先にこれをインクルードします。

#include <uart.h>

なお、このファイルは既定ではC:\Program Files\Microchip\MPLAB C30\src\peripheral_30F_24H_33F\includeにあります。

I/Oの設定

送信のUxTXピンを出力に、受信のUxRXピンを入力に、それぞれ入出力方向を設定します。

ポートのオープン、クローズ (Open,Close)

ポートのオープン

使用する関数はOpenUART()となっていますが、PICにはポートを開くという概念はないため、実際にはUARTの動作設定をすることになります。

void OpenUART1(
  unsigned int config1,  // UxMODEレジスタ(Mode register)の値
  unsigned int config2,  // UxSTAレジスタ(Status register)の値
  unsigned int ubrg      // UxBRGレジスタ(Baud rate generator register)の値
  )
第1引数config1のパラメータ
区分 定数 説明
UARTモジュール 有効/無効 UART_EN Module enable
UART_DIS Module disable
パリティ・データビット長 UART_NO_PAR_9BIT No parity 9 bit
UART_ODD_PAR_8BIT odd parity 8 bit
UART_EVEN_PAR_8BIT even parity 8 bit
UART_NO_PAR_8BIT no parity 8 bi
ストップビット UART_2STOPBITS 2 stop bits
UART_1STOPBIT 1 stop bits
アイドルモード時の動作 UART_IDLE_CON Work in IDLE mode
UART_IDLE_STOP Stop all functions in IDLE mode
スリープ時のスタートビット検出によるウェイクアップ 有効/無効 UART_EN_WAKE Enable Wake-up on START bit Detect during SLEEP Mode bit
UART_DIS_WAKE Disable Wake-up on START bit Detect during SLEEP Mode bit
ループバック 有効/無効 UART_EN_LOOPBACK Loop back enabled
UART_DIS_LOOPBACK Loop back disabled
自動ボーレート UART_EN_ABAUD Enable baud rate measurement on the next character
UART_DIS_ABAUD Baud rate measurement disabled or completed
IrDAエンコーダ 有効/無効 UART_IrDA_ENABLE IrDA encoder and decoder enabled
UART_IrDA_DISABLE IrDA encoder and decoder disabled
Alternate I/O※1 UART_ALTRX_ALTTX Communication through ALT pins
UART_RX_TX Communication through the normal pins
UxRTSピンモード UART_MODE_SIMPLEX UxRTS pin in Simplex mode
UART_MODE_FLOW UxRTS pin in Flow Control mode
Port latch control UART_UEN_11 UxTX,UxRX and BCLK pins are enabled and used; UxCTS pin controlled by port latches
UART_UEN_10 UxTX,UxRX, UxCTS and UxRTS pins are enabled and used
UART_UEN_01 UxTX,UxRX and UxRTS pins are enabled and used; UxCTS pin controlled by port latches
UART_UEN_00 UxTX and UxRX pins are enabled and used; UxCTS and UxRTS/BCLK pins controlled by port latches
Idle state UART_UXRX_IDLE_ZERO UxRX Idle state is zero
UART_UXRX_IDLE_ONE UxRX Idle state is one
BRG UART_BRGH_FOUR BRG generates 4 clocks per bit period
UART_BRGH_SIXTEEN BRG generates 16 clocks per bit period
※1 これが有効なのは、dsPIC30F1010、dsPIC30F2020、dsPIC30F2023、dsPIC30F4011のみ
第2引数config2のパラメータ
区分 定数 説明
送信 有効/無効 UART_TX_ENABLE Transmit enable
UART_TX_DISABLE Transmit disable
送信の割り込み条件 UART_INT_TX_BUF_EMPTY Interrupt on TXBUF becoming empty
UART_INT_TX_LAST_CH Interrupt when last character shifted out
UART_INT_TX Interrupt on transfer of every character to TSR
受信の割り込み条件 UART_INT_RX_BUF_FUL Interrupt on RXBUF full
UART_INT_RX_3_4_FUL Interrupt on RXBUF 3/4 full
UART_INT_RX_CHAR Interrupt on every char received
送信ブレーク UART_TX_PIN_NORMAL UART TX pin operates normally
UART_TX_PIN_LOW UART TX pin driven low
IrDAエンコード UART_IrDA_POL_INV_ONE IrDA encoded, UxTX Idle state is '1'
UART_IrDA_POL_INV_ZERO IrDA encoded, UxTX Idle state is '0'
Sync break UART_SYNC_BREAK_ENABLED Send sync break on next transmission
UART_SYNC_BREAK_DISABLED Sync break transmission disabled or completed
アドレス検出 有効/無効 UART_ADR_DETECT_EN address detect enable
UART_ADR_DETECT_DIS address detect disable
バッファオーバーラン UART_RX_OVERRUN_CLEAR Rx buffer Over run status bit clear
ループバック (Loopback)
通信テストを行うための機能。有効にすると、送信データが受信ポートに返されるようになる。
送信ブレーク (Transmit Break)
送信ラインをLowにして、強制的に送信を停止させる。
アドレス検出 (Address Detect)
送受信バッファの9ビット目をアドレス指定のフラグとして、それがセトされているときにはデータをアドレスとみなす。そしてそのアドレスに合したデバイだけが続くータを処理することで、複数のデバイスとの通信を可能とする。

サンプルコード

#define CPU_CLOCK        10000000                         // クロック[ Hz ]
#define CPU_PLL          8                                // PLL
#define CLOCK_FREQUENCY  ( ( CPU_CLOCK * CPU_PLL ) / 4 )  // 動作周波数[ Hz ]

#define BAUDRATE         115200L                          // ボーレート[ bps ]
const unsigned int Mode
     = UART_EN              // UARTモジュール - 有効
     & UART_IDLE_STOP       // アイドルモード - 動作停止
     & UART_DIS_WAKE        // ウェイクアップ - 無効
     & UART_DIS_LOOPBACK    // ループバック - 無効
     & UART_DIS_ABAUD       // 自動ボーレート - 無効
     & UART_NO_PAR_8BIT     // パリティなし/データ 8ビット
     & UART_1STOPBIT;       // ストップビット - 1ビット

const unsigned int Status
     = UART_TX_ENABLE           // 送信 - 有効    
     & UART_INT_TX_BUF_EMPTY    // 送信の割り込み条件 - 送信バッファが空
     & UART_INT_RX_CHAR         // 受信の割り込み条件 - 受信する都度
     & UART_TX_PIN_NORMAL       // 送信ブレーク - 通常
     & UART_ADR_DETECT_DIS      // アドレス検出 - 無効
     & UART_RX_OVERRUN_CLEAR;   // 受信バッファオーバーランエラー - クリア

const double Baudrate = ( double )CLOCK_FREQUENCY / ( 16 * BAUDRATE ) - 1;

// ボーレートの小数点以下を四捨五入する
unsigned int baudrate = ( unsigned int )( Baudrate + 0.5 );

OpenUART1( Mode, Status, baudrate );

通信の波形

ボーレート (Baud rate)

記号 説明 関係式
FOSC システムクロック
(System clock output)
FOSC = オシレータ周波数 * PLLの乗数
FCY 令実行クロック
(Instruction cycle clock)
[ MIPS(Million Instructions Per Second)と等しい ]
FCY = FOSC/4
TCY 命令サイクル
(Instruction cycle)
TCY = 1/FCY = 4/FOSC
BRG UxBRGレジスタ値
(Baud rate generator)
BRG = ( FCY / ( 16 * Baud rate ) ) - 1
※ dsPICには高ボーレートの設定は存在しない

ボーレートを算出する式は次のように表せます。

Baud rate = FCY / ( 16 * ( BRG + 1 ) )

よってこれを変形すると、OpenUART()の第3引数ubrgに与える値は次のように求められます。

BRG = FCY / ( 16 * Baud rate ) - 1

ボーレートエラー (Baud rate Error)

ボーレートの設定値は整数で与える必要があるため、小数点以下を丸めることで理論値との誤差が生じます。

例えばボーレートなどの条件を次のように仮定すると、

オシレータ周波数 10MHz
PLL 8
ボーレート 115.2kbps

BRGに設定する値は、

( 10 * 106 * 8 / 4 ) / ( 16 * 115.2 * 103 ) - 1 ≒ 10

と求まり、これから逆にボーレートを求めると、

( 10 * 106 * 8 / 4 ) / ( 16 * ( 10 + 1 ) ) ≒ 113636 [bps]

よってボーレートの誤差は

( 113636 - 115200 ) / 115200 ≒ -1.36%

となります。

ポートのクローズ

CloseUARTx()を使用します。この関数は、内部的には割り込みを無効とする処理をします。

void CloseUART1( void )

送受信 (Read、Write)

区分 データサイズ 関数
送信 1byte WriteUARTx()
putcUARTx()
複数byte putsUARTx()
受信 1byte ReadUARTx()
getcUARTx()
複数byte getsUARTx()

送信

送信バッファへデータを書き込みます。

void WriteUART1( unsigned int data ) 

送信にはputcUARTx()という関数もありますが、これは次のように定義されていて、実際にはWriteUARTx()のエイリアスです。

#define putcUART1 WriteUART1

連続してデータを送信するにはputsUARTx()を使用します。

void putsUART1( unsigned int *buffer )

受信

受信バッファからデータを読み込みます。

unsigned int ReadUART1( void )

getcUARTx()という関数もありますが、これはReadUARTx()のエイリアスです。

#define getcUART1 ReadUART1

連続してデータを受信するにはgetsUARTx()を使用します。

unsigned int getsUART1(
    unsigned int length,
    unsigned int *buffer,
    unsigned int uart_data_wait
    )

データのサイズ

WriteUARTx()とReadUARTx()のそれぞれの引数と戻り値はunsigned intであり、MPLAB C30のデータ型ではそれは16ビットです。またそれぞれのバッファUxTXREG、UxRXREGレジスタも16ビットです。しかし上位8ビットはアドレス検出に使用されるため、実際のデータサイズは8ビットになります。

通信状態の取得

対象 変数名、関数
送信バッファ UxSTAbits.UTXBF
受信バッファ DataRdyUARTx()
送信ステータス BusyUARTx()

送信バッファ

UxSTAレジスタのUTXBFビットで、送信バッファがフル (Full) か否かを確認できます。なお送信バッファがフルの状態で送信を試みもて、バッファには書き込まれず送信が無視されます。

if( U1STAbits.UTXBF )
{
    // 送信バッファはフル
}
else
{
    // 送信バッファはフルではない
}

送信バッファは4word (8byte) ありますが、アドレス検出のビットを含むため実際には4byteです。

受信バッファ

DataRdyUARTx()で、受信バッファにデータがあるか否かを確認できます。

char DataRdyUART1( void )

受信バッファも4wordありますが、送信バッファと同様の理由により実際には4byteです。

送信ステータス

BusyUARTx()で、送信の実行中か否かを確認できます。 (処理内容としては、UxSTAレジスタのTRMTビットの値を取得します)

char BusyUART1( void )

通信エラー

エラー 変数名
受信バッファオーバーランエラー
(receive buffer Overrun ERRor)
UxSTAbits.OERR
フレーミングエラー
(Framing ERRor)
UxSTAbits.FERR
パリティエラー
(Parity ERRor)
UxSTAbits.PERR

受信バッファオーバーランエラー発生時の注意

受信バッファオーバーランエラーが発生した際には、そのOERRビットをクリアするまでは、受信シフトレジスタ UxRSR (Receive Shift Register) が固定されます。これにより受信バッファも書き換えられなくなるため、受信できるようにするためにはOERRビットをクリアする必要があります。

フレーミングエラー (framing error)

データの転送において、データを構成するフレームに異常があること。 非同期通信では、データのストップビットが"0"となっている場合に、フレーミングエラーとなる。

http://japan.renesas.com/fmwk.jsp?cnt=w-mcu_k.framing_error.htm&fp=/support/glossary_child/w-mcu_k.ha/&title=フレーミングエラーとは

パリティチェック (parity check)

通信処理で用いられる単純な誤り検出方法。データ中の"1"の個数を常に奇数(奇数パリティ)または偶数(偶数パリティ)になるように、検査用のビット(パリティビット)を付加して送信する。受信側において"1"の個数を数えることにより、受信したデータが正しいか検証できる。

http://japan.renesas.com/fmwk.jsp?cnt=w-mcu_k.parity_check.htm&fp=/support/glossary_child/w-mcu_k.ha/&title=パリティチェックとは

割り込み (Interrupt)

ConfigIntUARTx()関数ならば、割り込みの許可、禁止および割り込み優先順位の設定を行えますので、下記のマクロと関数の機能を一括して実行できます。

void ConfigIntUART1( unsigned int config )

許可、禁止

機能 区分 マクロ
割り込みを許可 送信 EnableIntUxTX
受信 EnableIntUxRX
割り込みを禁止 送信 DisableIntUxTX
受信 DisableIntUxRX

これらのマクロは、次のように定義されています。

/* Macros to Enable/Disable interrupts of UART1 */
#define EnableIntU1RX      _U1RXIE = 1
#define EnableIntU1TX      _U1TXIE = 1

#define DisableIntU1RX     _U1RXIE = 0
#define DisableIntU1TX     _U1TXIE = 0

割り込み優先順位

機能 区分 マクロ
割り込み優先順位を設定 送信 SetPriorityIntUxTX()
受信 SetPriorityIntUxRX()

これもまたマクロであり、次のように定義されています。

/* Macros to set Interrupt priority of UART1 */
#define SetPriorityIntU1RX(priority)     _U1RXIP = priority
#define SetPriorityIntU1TX(priority)     _U1TXIP = priority

優先順位を指定する引数には、次の定数を使用します。レベルは0から7まであり、既定では4となっています。

送信 UART_TX_INT_PRn (nは0~7の数値)
受信 UART_RX_INT_PRn (nは0~7の数値)

割り込みフラグ

変数名 説明
IFS0bits.UxTXIF 送信 割り込みフラグ
  • 0:割り込みなし
  • 1:割り込み発生
IFS0bits.UxRXIF 受信

割り込みサービスルーチン (ISR)

割り込みにより呼び出される関数は、次のように定義します。

記述方法 区分
__attribute__(( interrupt, auto_psv )) _UxRXInterrupt() 受信
__attribute__(( interrupt, auto_psv )) _UxTXInterrupt() 送信

>> 割り込み全般について

レジスタ (Register)

  • UxMODE (Mode)
  • UxSTA (Status)
  • UxTXREG (Transmit Register)
  • UxRXREG (Receive Register)
  • UxBRG (Baud Rate Generator Prescaler)