PIC24でUART機能を使用するサンプルです。
とりあえず動いたので、メモ代わりにアップしておきます。
設定は以下の通り。
PIC24FJ32GA002で確認 UART1を使用 送受信処理はポーリングベース(割り込みは使わない) 9600bps 8bit ノンパリティ ストップ 1bit TxDのピン: RP5 RxDのピン: RP6 |
PICからの出力はFT2232経由でPCに取り込みます。
#include <p24FJ32GA002.h> #include "uart.h" #include "PPS.h" #define UART_CLK8MHZ_9600BPS 25 //-------------------------------------- // コンフィグレーションビットの設定 //-------------------------------------- _CONFIG2( POSCMOD_NONE & // Primary oscillator disabled IOL1WAY_OFF & // IOLOCK may be changed via unlocking seq OSCIOFNC_ON & // OSC2/CLKO/RC15 functions as port I/O (RC15) FCKSM_CSDCMD & // Clock switching and Fail-Safe Clock Monitor are disabled FNOSC_FRC & // Fast RC Oscillator (FRC) WUTSEL_LEG // Legacy Wake-up Timer ); _CONFIG1 ( FWDTEN_OFF & // Watchdog Timer is disabled ICS_PGx1 & // Emulator EMUC1/EMUD1 pins are shared with PGC1/PGD1 COE_ON & // Reset Into Clip On Emulation Mode BKBUG_ON & // Device resets into Debug mode GWRP_OFF & // Writes to program memory are allowed GCP_OFF & // Code protection is disabled JTAGEN_OFF // JTAG port is disabled ); int main( void ) { volatile int recvCount = 0; // 受信文字数 volatile int errCount = 0; // 受信エラー回数 volatile int waitCount = 0; // 送信待ち回数 //------------------------------------ // クロックの定義 //------------------------------------ OSCCONbits.COSC = 0; // CPUクロックにFast RC Oscillator (FRC)を使用 CLKDIVbits.DOZE = 0; // クロックのレート1:1(postscaler) CLKDIVbits.RCDIV = 0; // 8Mhz(prescaler) //------------------------------------ // RPピンの役割マッピング設定 //------------------------------------ iPPSOutput( OUT_PIN_PPS_RP5, OUT_FN_PPS_U1TX ); // RP5を UART1のTXDとして使用 iPPSInput( IN_FN_PPS_U1RX, IN_PIN_PPS_RP6 ); // RP6を UART1のRXDとして使用 //---------------------- // UART1のオープン //---------------------- CloseUART1(); unsigned int config1 = UART_EN & // UART有効 UART_IDLE_CON & // アイドル時も動作させる UART_DIS_WAKE & // スリープ時はWakeupさせない UART_IrDA_DISABLE & UART_DIS_LOOPBACK & // ループバックさせない UART_NO_PAR_8BIT & // パリティなし8bit UART_1STOPBIT & // ストップビット1 UART_MODE_SIMPLEX & // フローコントロール無し UART_UEN_00 & UART_UXRX_IDLE_ONE & // U1RXのアイドルを1にする UART_BRGH_SIXTEEN & // 高速転送を無効 UART_DIS_ABAUD; // ボーレートの自動検出を無効 unsigned int config2 = UART_INT_TX_BUF_EMPTY & // TXDバッファが空のとき割り込みを発生 UART_IrDA_POL_INV_ZERO & // U1TXアイドルを0とする UART_TX_ENABLE & // TXDを有効(同時にRXDも有効になる UART_INT_RX_CHAR & // RXD受信時に割り込みを発生 UART_ADR_DETECT_DIS & UART_RX_OVERRUN_CLEAR; OpenUART1(config1, config2, UART_CLK8MHZ_9600BPS ); ConfigIntUART1( UART_RX_INT_DIS & UART_TX_INT_DIS ); //----------------------------- // シリアル送受信の無限ループ // 一定周期で文字を送信します //----------------------------- while(1) { volatile unsigned int recvText; volatile long int loop; //------------------------- // 定期的に文字を送信する //------------------------- // 1byte書き込み U1TXREG = 'a'; //バッファが空になるまで待つ(TRMT:bit8) while ( U1STAbits.TRMT == 0 ) { waitCount++; } // ちょっと待つ for ( loop = 0; loop < 10000; loop++) { /* nop */; } } return 0; } |
今回、Microchip PIC24FのPeripheral Libraryを使用してみました。
RPピンの役割マッピング設定の…
iPPSOutput( OUT_PIN_PPS_RP5, OUT_FN_PPS_U1TX ); // RP5を UART1のTXDとして使用 |
は、以下のコードと等価です。
RPOR2bits.RP5R = 3; |
また、OpenUART1()は、以下のコードと同じです。
// I/Oレジスタを直接指定する場合 U1MODEbits.UARTEN = 1; U1MODEbits.USIDL = 0; U1MODEbits.IREN = 0; U1MODEbits.RTSMD = 1; U1MODEbits.UEN = 0; U1MODEbits.WAKE = 0; U1MODEbits.LPBACK = 0; U1MODEbits.ABAUD = 0; U1MODEbits.RXINV = 0; U1MODEbits.BRGH = 0; U1MODEbits.PDSEL = 0; U1MODEbits.STSEL = 0; U1STAbits.UTXISEL1 = 0; U1STAbits.UTXINV = 0; U1STAbits.UTXBRK = 0; U1STAbits.UTXEN = 1; U1STAbits.URXISEL = 0; U1STAbits.ADDEN = 0; U1BRG = UART_CLK8MHZ_9600BPS; |
実際の文字送信ループは、以下のコードに変更すると渡された文字のエコーバックが行えます
while(1) { //--------------------------------------- // 受信エラーが発生していないかチェック //--------------------------------------- if ( U1STAbits.PERR == 1 || U1STAbits.FERR == 1 || U1STAbits.OERR == 1 ) { errCount++; } //----------------------------- // バッファから文字を受信する //----------------------------- if ( U1STAbits.URXDA == 1 ) { recvText = U1RXREG; recvCount++; //----------------------------- // エコーバックする //----------------------------- U1TXREG = recvText; //バッファが空になるまで待つ while ( U1STAbits.TRMT == 0 ) { waitCount++; } } } |
送受信処理は、byte単位での送信に加えて、文字列単位のgetsUART1()/putsUART1() も使用できるようです。
getsUART1( unsigned int length, unsigned int * buffer, unsigned int uart_data_wait ); putsUART1( unsigned int * buffer ); |
関連記事
getsUART1()/putsUART1() は、PIC24Fも使っているので、とても参考になりました。ありがとうございました。