概要
今回はdsPIC33AKシリーズのUARTモジュールの使い方に関し説明します。
| 関連記事 | リンク |
| UARTモジュールの使い方 | UARTモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com) |
開発環境
開発環境を以下に示します。
今回はCPUボード(EV02G02A)で確認します
| 項目 | 値 | リンク |
| ベースボード | dsPIC33A CURIOSITY PLATFORM DEVELOPMENT BOARD | dsPIC33A Curiosity Platform Development Board User’s Guide (microchip.com) |
| CPUボード(EV68M17A) | EV68M17A – dsPIC33AK128MC106 Motor Control DIM | dsPIC33AK128MC106 Motor Control Dual In-Line Module (DIM) Information Sheet (microchip.com) |
| CPUボード(EV02G02A) ※本記事で使用 | dsPIC33AK128MC106 General Purpose Dual In-Line Module (DIM) | dsPIC33AK128MC106 General Purpose Dual In-Line Module (DIM) | Microchip Technology |
| 統合開発環境 | MPLAB X IDE v6.20 | MPLAB® X IDE | Microchip Technology |
| コンパイラ | MPLAB XC DSC v3.10 | MPLAB® XC DSC Compiler | Microchip Technology |

概要
UARTとはUniversal Asynchronous Receiver Transmitterの頭文字をとったもので、周辺機器などの他の機器とのインターフェースに使用される柔軟なシリアル通信ペリフェラルです。
非同期シリアル通信以外にも以下のようなプロトコルに対応しています。
- lin 2.2/j2602
- IrDA
- デジタル・マルチプレックス512(DMX)
- スマートカード (ISO 7816)
UARTモジュールの主な特徴を以下に示します。
- 全二重または半二重動作
- 最大8ディープTXおよびRX先入れ先出し(FIFO)バッファ
- 8ビットまたは9ビットのデータ幅
- 設定可能なストップ・ビット長
- フロー制御
- 自動ボー校正
- パリティ、フレーミング、バッファ・オーバーラン・エラー検出
- アドレス検出
- ブレーク送信
- 送受信極性制御
- スリープ・モードでの動作
- 同期ブレーク受信割り込みによるスリープからの復帰
UARTモジュールブロック図
下記にUARTモジュールのブロック図を示します。

ハードウェア構成と制御ブロック
ベースボードとCPUボード(EV68M17A)との接続ブロック図を示します。
PCとつながるUSB Type-C とUSBハブが搭載され、更にその先にUSB-UARTブリッジデバイスとPKoB回路が接続されています。
今回は定期的にパソコン側に文字列とカウンタ値を送信するプログラムを作成します。

レジスタ
UART関連のレジスタは以下の10種類です。dsPIC33Cシリーズと比較し大きな変更は有りませんが、32bit幅となったことにより、レジスタの統一が図られています。
| レジスタ名(xは1~3) | 機能 | 説明 |
| UxCON | UARTx CONFIGURATION Register | UARTの共通設定レジスタ |
| UxSTAT | UARTx STATUS Register | UARTのステータスレジスタ |
| UxBRG | UARTx BAUD RATE Register | UARTの通信速度設定レジスタ |
| UxRXB | UARTx Receive Buffer Register | UART受信バッファレジスタ |
| UxTXB | UARTx Transmit Buffer Register | UART送信バッファレジスタ |
| UxPA | UARTx Timming ParameterA Register | UARTタイミングパラメータA |
| UxPB | UARTx Timming ParameterB Register | UARTタイミングパラメータB |
| UxCHK | UARTx Checksum Register | UART送受信チェックサムレジスタ |
| UxSCCON | UARTx Smart Card Configuration Register | UARTスマートカード設定レジスタ |
| UxUIR | UARTx Interrupt Register | UART割り込みレジスタ |
ボーレートに関しては下記のように分数分割モードが新たに追加されました。

| レガシーモード | 分数分割モード | |
| Baud Rate | Fp / (16 * (BRG+1)) or Fp / (4 * (BRG+1)) | Fp / BRG |
| BRG | Fp/(16 * Baud Rate) -1 , Fp/(4 * Baud Rate) -1 | Fp / Baudrate |
ソースコード
インクルードファイル
コンフィグレーションファイル、クロック設定ファイルは以下のファイルをインクルードしてください。
■コンフィグレーションファイル (config.h)
■クロック設定ソースファイル(Clock_Driver.c)
■クロックヘッダーファイル(clock_driver.h)
ソースコード全体
#include <stdio.h>
#include <stdlib.h>
#include <dsp.h>
#include <xc.h>
#include "config.h"
#include "clock_driver.h"
#define TXBUF_SIZE 32
int8_t TxTemp[16];
int8_t TxBuf[TXBUF_SIZE];
int8_t TxHead;
int8_t TxTail;
int32_t CntData;
int main()
{
/*-----------------------------------------------------------------------*/
/* 初期化*/
/*-----------------------------------------------------------------------*/
vdg_Clock_Set_Register();
/*-----------------------------------------------------------------------*/
/* ピン設定*/
/*-----------------------------------------------------------------------*/
RPOR12bits.RP50R = 9u; //UART1出力 RP50
RPINR9bits.U1RXR = 52u; //UART1入力 RP52
/*-----------------------------------------------------------------------*/
/* UART初期化*/
/*-----------------------------------------------------------------------*/
U1CON = 0x00000000u;
U1STAT = 0x00000000u;
U1BRG = (uint32_t) (100000000 / 115200);
U1RXB = 0x00000000u;
U1TXB = 0x00000000u;
U1PA = 0x00000000u;
U1PB = 0x00000000u;
U1CHK = 0x00000000u;
U1SCCON = 0x00000000u;
U1UIR = 0x00000000u;
U1CONbits.CLKMOD = 1u;
U1CONbits.RXEN = 1u; //受信許可
U1CONbits.TXEN = 1u; //送信許可
U1CONbits.ON = 1u;
/*-----------------------------------------------------------------------*/
/* タイマーレジスタ */
/*-----------------------------------------------------------------------*/
PR1 = 1000000;
T1CONbits.ON = 1;
T1CONbits.TCKPS = 0;
IFS1bits.T1IF = 0;
IEC1bits.T1IE = 0;
IPC6bits.T1IP = 3;
INTCON1bits.GIE = 0;
/*-----------------------------------------------------------------------*/
/* メインルーチン*/
/*-----------------------------------------------------------------------*/
while(1)
{
CntData ++;
if (IFS1bits.T1IF == 1)
{
sprintf(TxTemp,"CNT =%d\r\n",CntData);
Uart_Enque_TX_Data(TxTemp);
IFS1bits.T1IF = 0;
}
Uart_Deque_TX_Data();
}
}
void Uart_Enque_TX_Data(uint8_t *u1pa_Data)
{
while (*u1pa_Data != NULL)
{
TxBuf[TxHead++] = *u1pa_Data ++;
if (TxHead >= TXBUF_SIZE)
{
TxHead = 0;
}
}
}
void Uart_Deque_TX_Data(void)
{
while (TxHead != TxTail)
{
if (U1STATbits.TXBF == 0u)
{
U1TXB = TxBuf[TxTail++];
if (TxTail >= TXBUF_SIZE)
{
TxTail = 0;
}
}
else
{
break;
}
}
}
結果
PC上のシリアルターミナルソフト(Tera Termなど)で動作が確認できると思います。

記事についての注意点
本記事は慎重に内容を検討し正確さに努めておりますが、もし内容に誤りがあったとしても、この記事を参考にして生じた損害等については一切の責任を負いません。

コメント