---
---
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;
}
}
}