dsPIC33Fの基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
dsPIC33F UART

dsPICのUART1を操作させるプログラムを示します。UARTの入出力ピンは、Peripheral Pin Select (PPS)機能を使い、任意のRPxピンに割りつけて使用します。このページの例では、

設定しています。ボーレートを決定する U1BRG の値は、以下の計算式で算出します。
  U1BRG = (Fcy / (16 * BaudRate)) - 1
  U1BRG = (40000000 / (16 * 9600)) - 1
  U1BRG = 259.42 // Round to 259

プログラム

/* ***************************************************
 * UART送受信                   受信は割込みで処理
 * ***************************************************
 * SWを押すと[Start]を送信
 * その後は、一行受信したら、そのまま送り返す。
 * クロックは4MHzXtalをPLLで20倍にし、80MHz(40MIPS)
 *
 * Target PIC dsPic33FJ128GP802
 * MPLAB X , Microchip XC16
 * Created on 2014/03/19, 17:45
 * ******************************************************/
#define FCY 40000000UL    // 80MHz / 2

#include <xc.h>              //
#include <string.h>
#include <libpic30.h>       // 遅延ライブラリ

//**********************************************************

// コンフィギュレーション ----- XT(3-10MHz)発振 + PLL -----
_FGS(GWRP_OFF & GCP_OFF);
_FOSCSEL(FNOSC_PRIPLL);
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT);
_FWDT(FWDTEN_OFF);

// プロトタイプ *********************************************
void UART_str(char *, char);
void UART_rom(const char *);

// 共通変数 *************************************************
unsigned char RxWptr,RxRptr;
char RxWbuf[20],RxRbuf[20];

// メイン ****************************************************
int main (void){
    //  PLLに関連する設定 ------------------------------------
    PLLFBD = 78;                 // M = 80  4MHz x80/2/2
    CLKDIVbits.PLLPOST=0;        // N2 = 2          = 80MHz
    CLKDIVbits.PLLPRE=0;         // N1 = 2
    while (OSCCONbits.LOCK!=1);  // PLLの安定(LOCK)を待つ
    // -------------------------------------------------------

    RxWptr = 0;                       // 受信書込みポインタのリセット
    RxRptr = 0;                       // 受信読込みポインタのリセット
    _PCFG5=1;                         // SW Portをデジタルに設定
    U1BRG  = 259;                     // 9600bps @ 40MHz
    U1MODE = 0x8000;                  // 8bit, No Parity,
    U1STA  = 0x0400;                  // No Flow Control
    _U1RXR = 5;                       // UART1 RX を RP5に設定
    _RP6R  = 3;                       // UART1 TX を RP6に設定
    __delay_ms(200);                  // UART安定動作を待つ遅延
    _U1RXIP = 4;                      // Rx割込優先度を4に設定 (既定値)
    _U1RXIF = 0;                      // Rx割込フラッグをクリア
    _U1RXIE = 1;                      // Rx割込を許可

    while(_RB3);                      // S1が押されるのを待つ
    UART_rom("Start\r\n");            // 開始メッセージ「>」送信
    while(1){
        if( RxRptr){                   // 受信していれば
            UART_str(RxRbuf, RxRptr);  //  バッファ内を送信
            RxRptr = 0;                //  送信終了を明示
            UART_rom("\r\n");          //  CRLFを送信
        }
    }
}
/* ********************************************************************
 * UART1 文字列送信
 * 文字配列の指定文字数だけ 送信する
 * *******************************************************************/
void UART_str(char *str, char ptr){
    while(ptr--){                     // 指示文字数分繰り返す
        while(U1STAbits.UTXBF);       // 送信バッファが空なら
        U1TXREG = *str++;             // 一文字送信 ポインタを進める
    }
}
/* ********************************************************************
 * UART1 ROM文字列送信
 * 指定文字列を送信する
 * *******************************************************************/
void UART_rom(const char *str){
    while(*str){                      // 終端の「0」になるまで繰り返す
        while(U1STAbits.UTXBF);       // 送信バッファが空なら
        U1TXREG = *str++;             // 一文字送信 ポインタを進める
    }
}

/* ********************************************************************
 * Uart1 Rx割込み処理
 * RxWptr,RxRptr; RxWbuf[20],RxRbuf[20];
 * *******************************************************************/
void __attribute__ ((interrupt, no_auto_psv)) _U1RXInterrupt(void) {
    char RxData;
    _U1RXIF = 0;
    if(U1STAbits.OERR){                 // 受信エラーなら
        U1STAbits.OERR = 0;             //    エラークリア
        RxWptr = 0;                     //    既存データはすべて廃棄
    }else{                              // 正常受信なら
        RxData = U1RXREG;
        switch(RxData){                 // CRLFを受信したら、
        case 0x0A:                      //   それまでの受信データを
        case 0x0D:                      //   RxRbufに転送する
            if(RxWptr){                 //   ただし、CRLFは転送しない
                memcpy(RxRbuf, RxWbuf, RxWptr);
                RxRptr = RxWptr;        //   バッファ転送し受信数保存
                RxWptr = 0;             //   ポインタリセット
            }
            break;
        default:                        // 一般文字なら
            RxWbuf[RxWptr++] = RxData;  //  受信バッファに保存
            if(RxWptr >= 20)RxWptr = 0; //  容量超えはすべて廃棄
            break;
        }
    }
}