MPLAB C30コンパイラの、UARTモジュールのライブラリについて解説します。
ライブラリファイルはuart.hですので、先にこれをインクルードします。
#include <uart.h>
なお、このファイルは既定では/Microchip/MPLAB C30/support/peripheral_30F_24H_33F/にあります。
関数名やマクロ名はOpenUARTx()のような形式で、使用するUARTモジュールに応じてxの部分でUARTの番号を指定します。 UARTモジュールが1つしか搭載されていない場合には、つねに1となります。
用途 | 関数 |
---|---|
オープン/クローズ | OpenUARTx |
CloseUARTx | |
送受信 | ReadUARTx (getcUARTx) |
WriteUARTx (putcUARTx) | |
putsUARTx | |
getsUARTx | |
通信状態 | DataRdyUARTx |
BusyUARTx | |
割り込み | ConfigIntUARTx |
用途 | マクロ |
---|---|
割り込み | EnableIntUxRX |
EnableIntUxTX | |
DisableIntUxRX | |
DisableIntUxTX | |
SetPriorityIntUxRX | |
SetPriorityIntUxTX |
区分 | SFR名 | Bit 15 | Bit 14 | Bit 13 | Bit 12 | Bit 11 | Bit 10 | Bit 9 | Bit 8 | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | リセット後の値 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
(モード) | U1MODE | UARTEN | - | USIDL | - | reserved | ALTIO | reserved | reserved | WAKE | LPBACK | ABAUD | - | - | PDSEL<1:0> | STSEL | 0000 0000 0000 0000 | |
(ステータス) | U1STA | UTXISEL | - | - | - | UTXBRK | UTXEN | UTXBF | TRMT | URXISEL<1:0> | ADDEN | RIDLE | PERR | FERR | OERR | URXDA | 0000 0001 0001 0000 | |
(送信データ) | U1TXREG | - | - | - | - | - | - | - | UTX8 | Transmit Register | 0000 0000 0000 0000 | |||||||
(受信データ) | U1RXREG | - | - | - | - | - | - | - | URX8 | Receive Register | 0000 0000 0000 0000 | |||||||
(ボーレート) | U1BRG | Baud Rate Generator Prescaler | 0000 0000 0000 0000 |
送信
受信
ピン | 説明 |
---|---|
UxTX | |
UxRX |
UARTモジュールを有効にすると、送受信のピンは出力と入力にそれぞれ自動で設定されます。よってI/Oの設定をする必要はありません。≫I/Oと周辺モジュール
使用する関数はOpenUARTx()となっていますが、PICにはポートを開くという概念はないため、実際にはUARTの動作設定をすることになります。
void OpenUARTx( unsigned int config1, // UxMODEレジスタ (Mode register) の値 unsigned int config2, // UxSTAレジスタ (Status register) の値 unsigned int ubrg // UxBRGレジスタ (Baud rate generator register) の値 )
区分 | 定数 | 説明 |
---|---|---|
UARTモジュール 有効/無効 | UART_EN | モジュールを有効にする |
UART_DIS | モジュールを無効にする | |
パリティ・データビット長 | 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 |
区分 | 定数 | 説明 |
---|---|---|
送信 有効/無効 | UART_TX_ENABLE | 送信を有効にする |
UART_TX_DISABLE | 送信を無効にする | |
送信の割り込み条件 | UART_INT_TX_BUF_EMPTY | 送信バッファが空になったとき |
UART_INT_TX_LAST_CH | 最後のデータがシフトレジスタに転送されたとき | |
UART_INT_TX | データがシフトレジスタに転送されるごと | |
受信の割り込み条件 | UART_INT_RX_BUF_FUL | 受信バッファの4/4がフルになったとき |
UART_INT_RX_3_4_FUL | 受信バッファの3/4がフルになったとき | |
UART_INT_RX_CHAR | データを受信するごと | |
送信ブレーク | 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 |
システムクロック (System clock) は、
であり、命令サイクルクロック (Instruction cycle clock) 周波数は
です。またボーレートを算出する式は、
であることから、UxBRGレジスタ値 (Baud Rate Generator) は
となり、OpenUARTx()の第3引数ubrgに与える値が求められます。
※dsPICには高ボーレートの設定は存在しません。ボーレートの設定値は整数で与える必要があるため、小数点以下を丸めることで理論値との誤差が生じます。
たとえばボーレートなどの条件を次のように仮定すると、
オシレータ周波数 | 10MHz |
---|---|
PLL | 8 |
ボーレート | 115.2kbps |
BRGに設定する値は、
と求まり、これから逆にボーレートを求めると、
となります。よって、
のボーレートの誤差が生じることになります。
ポートをオープンするコードを示します。
#define CPU_CLOCK 10000000L // クロック [Hz] #define CPU_PLL 8 // PLL #define FCY ( ( 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 )FCY / ( 16 * BAUDRATE ) - 1; // ボーレートの小数点以下を四捨五入する unsigned int baudrate = ( unsigned int )( Baudrate + 0.5 ); OpenUART1( Mode, Status, baudrate );
CloseUARTx()を使用します。この関数は、内部的には割り込みを無効とする処理をします。
void CloseUARTx( void )
区分 | データサイズ | 関数 | 関与する変数 |
---|---|---|---|
送信 | 1byte | WriteUARTx() | UxTXREG |
putcUARTx() | |||
複数byte | putsUARTx() | ||
受信 | 1byte | ReadUARTx() | UxRXREG |
getcUARTx() | |||
複数byte | getsUARTx() |
送信バッファがフルの状態で送信を試みても、バッファには書き込まれず送信が無視されます。
送信バッファへデータを書き込みます。
void WriteUARTx( unsigned int data )
送信にはputcUARTx()という関数もありますが、これは
#define putcUART1 WriteUART1
のように定義されていて、実体はWriteUARTx()の別名です。または、
UxTXREG = data;
のようにレジスタに直接書き込んでも同じです。
連続してデータを送信するには、putsUARTx()という関数があります。
void putsUARTx( unsigned int *buffer )
たとえば文字列を送信するならば、
char* str = "abc"; putsUART1( (unsigned int*)str );
のようにします。
受信バッファオーバーランエラーが発生した場合、その状態がクリアされるまでは受信が行われません。このときバッファから読み込むと、つねに最後に受信したデータが返されます。
受信バッファからデータを読み込みます。
unsigned int ReadUARTx( void )
getcUARTx()という関数もありますが、これはReadUARTx()のエイリアス別名です。
#define getcUART1 ReadUART1
または送信と同様に、
unsigned int data = UxRXREG;
のようにレジスタから直接読み込む方法もあります。
連続してデータを受信するには、getsUARTx()という関数があります。
unsigned int getsUARTx( 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() | UxSTAbits.URXDA |
送信ステータス | BusyUARTx() | UxSTAbits.TRMT |
受信バッファと送信ステータスの確認には関数が用意されていますが、レジスタの値を調べることと同義です。
UxSTAレジスタのUTXBFビットで、送信バッファがフル (Full) かどうかを確認できます。
if( U1STAbits.UTXBF ) { // 送信バッファはフル } else { // 送信バッファはフルではない }
ところで、
#define _UTXBF U1STAbits.UTXBF
のようにマクロが定義されているため、_UTXBF
のようにも記述できます。
なお送信バッファは4word (8byte) ありますが、アドレス検出のビットを含むため、保持できるデータは4byteです。
DataRdyUARTx()で、受信バッファにデータがあるかどうかを確認できます。
char DataRdyUARTx( void )
受信バッファにデータがあれば1が、さもなくば0が返されます。受信バッファも4word (8byte) ありますが、送信バッファと同様の理由により4byteのデータしか保持できません。
受信バッファの確認には関数が用意されていますが、内部的にはUxSTAレジスタのURXDAビットを調べているだけです。よって送信バッファの場合と同様に、
if( _URXDA )
のようにも記述できます。
受信バッファオーバーランエラーが発生した場合、その状態がクリアされるまでは、つねに受信バッファにデータがある状態 (_URXDA == 1
) となります。
BusyUARTx()で、送信の実行中かどうかを確認できます。送信中ならば1を、さもなくば0を返します。これは内部的にはUxSTA<TRMT>の値の否定であり、_TRMTとは逆の値を返します。
char BusyUARTx( void )
エラー | 関与する変数 |
---|---|
受信バッファオーバーランエラー (receive buffer Overrun ERRor) |
UxSTAbits.OERR |
フレーミングエラー (Framing ERRor) |
UxSTAbits.FERR |
パリティエラー (Parity ERRor) |
UxSTAbits.PERR |
フレーミングエラー (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=パリティチェックとは
受信バッファオーバーランエラーが発生したときには、そのOERRビットをクリアするまでは、受信シフトレジスタ UxRSR (Receive Shift Register) が固定されます。これにより受信バッファも書き換えられなくなるため、受信できるようにするためにはOERRビットをクリアする必要があります。
送信ではデータがシフトレジスタに転送されることによって、受信ではデータがバッファに格納されることによって割り込みが発生します。具体的な割り込みの発生条件は、ステータスレジスタ (UxSTA) で設定します。
変数名 | 説明 | |
---|---|---|
IFS0bits.UxTXIF | 送信 | 割り込みフラグ
|
IFS0bits.UxRXIF | 受信 |
機能 | 区分 | マクロ |
---|---|---|
割り込みを許可 | 送信 | 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
のように定義されており、割り込み有効制御レジスタ (IECx) に設定することと同義です。
機能 | 区分 | マクロ |
---|---|---|
割り込み優先順位を設定 | 送信 | SetPriorityIntUxTX( priority ) |
受信 | SetPriorityIntUxRX( priority ) |
これもまたマクロであり、
/* Macros to set Interrupt priority of UART1 */
#define SetPriorityIntU1RX(priority) _U1RXIP = priority
#define SetPriorityIntU1TX(priority) _U1TXIP = priority
のように定義されています。優先順位を指定する引数には、
送信 | UART_TX_INT_PRn (nは0~7の数値) |
---|---|
受信 | UART_RX_INT_PRn (nは0~7の数値) |
の定数を使用します。レベルは0~7まであり、既定では4となっています。
ConfigIntUARTx()関数で、割り込みの許可、禁止および割り込み優先順位の設定を一括して行えます。
void ConfigIntUARTx( unsigned int config )
たとえば受信割り込みを有効にし、その優先順位を7とするには、
ConfigIntUART1( UART_RX_INT_EN & UART_RX_INT_PR7 );
とします。設定可能な定数は以下の通りです。
/* defines for UART Interrupt configuartion */ #define UART_RX_INT_EN 0xFFFF /*Receive interrupt enabled*/ #define UART_RX_INT_DIS 0xFFF7 /*Receive interrupt disabled*/ #define UART_RX_INT_PR0 0xFFF8 /*Priority RX interrupt 0*/ #define UART_RX_INT_PR1 0xFFF9 /*Priority RX interrupt 1*/ #define UART_RX_INT_PR2 0xFFFA /*Priority RX interrupt 2*/ #define UART_RX_INT_PR3 0xFFFB /*Priority RX interrupt 3*/ #define UART_RX_INT_PR4 0xFFFC /*Priority RX interrupt 4*/ #define UART_RX_INT_PR5 0xFFFD /*Priority RX interrupt 5*/ #define UART_RX_INT_PR6 0xFFFE /*Priority RX interrupt 6*/ #define UART_RX_INT_PR7 0xFFFF /*Priority RX interrupt 7*/ #define UART_TX_INT_EN 0xFFFF /*transmit interrupt enabled*/ #define UART_TX_INT_DIS 0xFF7F /*transmit interrupt disabled*/ #define UART_TX_INT_PR0 0xFF8F /*Priority TX interrupt 0*/ #define UART_TX_INT_PR1 0xFF9F /*Priority TX interrupt 1*/ #define UART_TX_INT_PR2 0xFFAF /*Priority TX interrupt 2*/ #define UART_TX_INT_PR3 0xFFBF /*Priority TX interrupt 3*/ #define UART_TX_INT_PR4 0xFFCF /*Priority TX interrupt 4*/ #define UART_TX_INT_PR5 0xFFDF /*Priority TX interrupt 5*/ #define UART_TX_INT_PR6 0xFFEF /*Priority TX interrupt 6*/ #define UART_TX_INT_PR7 0xFFFF /*Priority TX interrupt 7*/
割り込みにより呼び出される関数は、
記述方法 | 区分 |
---|---|
__attribute__(( interrupt, auto_psv )) _UxRXInterrupt() | 受信 |
__attribute__(( interrupt, auto_psv )) _UxTXInterrupt() | 送信 |
のように定義します。